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 4:59 am GMT (diff)