Alternative Observer Pattern

lua-users home
wiki

This is an alternative implementation of the ObserverPattern that uses a slightly different usage idiom.

module(..., package.seeall)



-- Register

local function register( self, observer, method )

  local t = {}

  t.o = observer

  t.m = method

  table.insert( self, t )

end



-- Deregister

local function deregister( self, observer, method )

  local i

  local n = #self

  for i = n, 1, -1 do

    if (not observer or self[i].o == observer) and

       (not method   or self[i].m == method)

    then

      table.remove( self, i )

    end

  end

end



-- Notify

local function notify( self, ... )

  local i

  local n = #self

  for i = 1, n do

    self[i].m( self[i].o, ... )

  end

end



-- signal metatable

local mt = {

  __call = function( self, ... )

    self:notify(...)

  end

}



function signal()

  local t = {}

  t.register = register

  t.deregister = deregister

  t.notify = notify

  setmetatable( t, mt )

  return t

end

Because the signals are now explicit objects, instead of implicit data (such as a string), we use the table syntactic sugar to work with them. The __call metamethod is included for convenience, so that we can use the signal directly.

observer = require( "alt_obs" )



alice = {}

function alice:slot( param )

  print( self, param )

end



bob = {}

bob.alert = observer.signal()



bob.alert:register( alice, alice.slot )

bob.alert( "Hi there" )

bob.alert:deregister( alice )

bob.alert( "Hello?" )

-- WilliamBubel


RecentChanges · preferences
edit · history
Last edited November 17, 2008 3:59 am GMT (diff)