From b948743d959e69569f5c437e47e3de176a71a393 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Enrique=20Garc=C3=ADa=20Cota?= Date: Sun, 4 Mar 2012 21:09:40 +0100 Subject: [PATCH] added beholder.group --- beholder.lua | 51 +++++++++++++++++++++++++++++++++++---------- spec/acceptance.lua | 23 ++++++++++++++++++++ spec/unit.lua | 49 ++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 111 insertions(+), 12 deletions(-) diff --git a/beholder.lua b/beholder.lua index b9f15d2..db14080 100644 --- a/beholder.lua +++ b/beholder.lua @@ -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 diff --git a/spec/acceptance.lua b/spec/acceptance.lua index bd74003..df1fd1f 100644 --- a/spec/acceptance.lua +++ b/spec/acceptance.lua @@ -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) diff --git a/spec/unit.lua b/spec/unit.lua index 422a074..0f660a4 100644 --- a/spec/unit.lua +++ b/spec/unit.lua @@ -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)