added beholder.group

This commit is contained in:
Enrique García Cota 2012-03-04 21:09:40 +01:00
parent 9df05b8a85
commit b948743d95
3 changed files with 111 additions and 12 deletions

View File

@ -28,10 +28,6 @@ local function newNode()
return { callbacks = {}, children = setmetatable({}, {__mode="k"}) }
end
local function initialize()
root = newNode()
nodesById = setmetatable({}, {__mode="k"})
end
local function findNodeById(id)
return nodesById[id]
@ -100,7 +96,27 @@ end
local beholder = {}
-- beholder private functions
-- beholder private functions/vars
local groups = nil
local currentGroupId = nil
local function addIdToCurrentGroup(id)
if currentGroupId then
groups[currentGroupId] = groups[currentGroupId] or {}
local group = groups[currentGroupId]
group[#group + 1] = id
end
return id
end
local function stopObservingGroup(group)
local count = #group
for i=1,count do
beholder.stopObserving(group[i])
end
return count
end
local function falseIfZero(n)
return n > 0 and n
@ -118,14 +134,24 @@ end
function beholder.observe(...)
local event, callback = extractEventAndCallbackFromParams({...})
local node = findOrCreateDescendantNode(root, event)
return addCallbackToNode(node, callback)
return addIdToCurrentGroup(addCallbackToNode(node, callback))
end
function beholder.stopObserving(id)
local node = findNodeById(id)
if not node then return false end
removeCallbackFromNode(node, id)
return true
if node then removeCallbackFromNode(node, id) end
local group, count = groups[id], 0
if group then count = stopObservingGroup(group) end
return (node or count > 0) and true or false
end
function beholder.group(groupId, f)
assert(not currentGroupId, "beholder.group can not be nested!")
currentGroupId = groupId
f()
currentGroupId = nil
end
function beholder.trigger(...)
@ -137,9 +163,12 @@ function beholder.triggerAll(...)
end
function beholder.reset()
initialize()
root = newNode()
nodesById = setmetatable({}, {__mode="k"})
groups = {}
currentGroupId = nil
end
initialize()
beholder.reset()
return beholder

View File

@ -114,5 +114,28 @@ describe("Acceptance", function()
end)
test("groups", function()
local group = {}
local up = 0
beholder.group(group, function()
beholder.observe("UP", function()
up = up + 1
end)
end)
beholder.trigger("UP")
assert_equal(1, up)
beholder.stopObserving(group)
beholder.trigger("UP")
assert_equal(1, up)
end)
end)

View File

@ -92,7 +92,7 @@ describe("Unit", function()
assert_equal(counter, 6)
end)
it("does not raise an error when stopping observing an inexisting event", function()
it("does not raise an error when stopping observing an inexisting event or group", function()
assert_not_error(function() beholder.stopObserving({}) end)
end)
@ -100,11 +100,25 @@ describe("Unit", function()
assert_equal(false, beholder.stopObserving({}))
end)
it("returns false when there was a group, but it had no action", function()
local group = {}
beholder.group(group, function() end)
assert_equal(false, beholder.stopObserving(group))
end)
it("returns true when an action was found and removed", function()
local id = beholder.observe("X", function() end)
assert_true(beholder.stopObserving(id))
end)
it("returns true when at least one action from a group was removed", function()
local group = {}
beholder.group(group, function()
beholder.observe("X", function() end)
end)
assert_true(beholder.stopObserving(group))
end)
end)
describe(".trigger", function()
@ -160,4 +174,37 @@ describe("Unit", function()
assert_equal(2, beholder.triggerAll())
end)
end)
describe(".group", function()
it("throws an error when nested", function()
assert_error(function()
beholder.group({}, function()
beholder.group({}, function()
end)
end)
end)
end)
it("creates a group of events that can be cancelled", function()
local counter = 0
local increment = function() counter = counter + 1 end
local group = {}
beholder.group(group, function()
beholder.observe("X", increment)
beholder.observe("Y", increment)
end)
beholder.trigger("X")
beholder.trigger("Y")
assert_equal(2, counter)
beholder.stopObserving(group)
beholder.trigger("X")
beholder.trigger("Y")
assert_equal(2, counter)
end)
end)
end)