tests passed on the first try after massive change. I am very weary now

This commit is contained in:
Enrique García Cota 2012-02-03 18:51:33 +01:00
parent f7940a7705
commit 7d614bb4f0

View File

@ -11,21 +11,18 @@ local function copy(t)
return c return c
end end
local function hash2array(t)
local arr, i = {}, 0
for _,v in pairs(t) do
i = i+1
arr[i] = v
end
return arr, i
end
-- private Node class -- private Node class
local nodesById = nil local nodesById = nil
local root = nil local root = nil
local function newNode() local function newNode()
return { callbacks = {}, children = setmetatable({}, {__mode="k"}) } return {
callbacks = {},
subjectCallbacks = setmetatable({}, {__mode="k"}),
children = setmetatable({}, {__mode="k"})
}
end end
local function initialize() local function initialize()
@ -42,6 +39,23 @@ local function findOrCreateChildNode(self, key)
return self.children[key] return self.children[key]
end end
-- Returns an array containing all the callbacks to be invoked in a node, making a copy.
-- This ensures safety on self-erasures (buttons that make themselves stopping observing onclick when clicked)
local function getNodeCallbacksList(self)
local arr, i = {}, 0
for _,c in pairs(self.callbacks) do
i = i+1
arr[i] = c
end
for _,subjectCallbacks in pairs(self.subjectCallbacks) do
for _,c in pairs(subjectCallbacks) do
i = i+1
arr[i] = c
end
end
return arr, i
end
local function findOrCreateDescendantNode(self, keys) local function findOrCreateDescendantNode(self, keys)
local node = self local node = self
for i=1, #keys do for i=1, #keys do
@ -51,8 +65,7 @@ local function findOrCreateDescendantNode(self, keys)
end end
local function invokeNodeCallbacks(self, params) local function invokeNodeCallbacks(self, params)
-- copy the hash into an array, for safety (self-erasures) local callbacks, count = getNodeCallbacksList(self)
local callbacks, count = hash2array(self.callbacks)
for i=1,#callbacks do for i=1,#callbacks do
callbacks[i](unpack(params)) callbacks[i](unpack(params))
end end
@ -89,11 +102,24 @@ local function addCallbackToNode(self, callback)
return id return id
end end
local function addSubjectCallbackToNode(self, subject, callback)
local id = {}
self.subjectCallbacks[subject] = self.subjectCallbacks[subject] or {}
self.subjectCallbacks[subject][id] = callback
nodesById[id] = self
return id
end
local function removeCallbackFromNode(self, id) local function removeCallbackFromNode(self, id)
self.callbacks[id] = nil self.callbacks[id] = nil
nodesById[id] = nil nodesById[id] = nil
end end
local function removeCallbackFromSubject(self, subject, id)
self.subjectCallbacks[subject][id] = nil
nodesById[id] = nil
end
------ beholder table ------ beholder table
@ -125,7 +151,7 @@ function beholder.observeSubject(subject, ...)
assert(subject ~= nil, "Subject was nil. Please provide a valid subject") assert(subject ~= nil, "Subject was nil. Please provide a valid subject")
local event, callback = extractEventAndCallbackFromParams({...}) local event, callback = extractEventAndCallbackFromParams({...})
local node = findOrCreateDescendantNode(root, event) local node = findOrCreateDescendantNode(root, event)
return addCallbackToNode(node, callback) return addSubjectCallbackToNode(node, subject, callback)
end end
function beholder.stopObserving(id) function beholder.stopObserving(id)