From 6dc76c9f04ad64b95188746f0befd71e9217fad1 Mon Sep 17 00:00:00 2001 From: Nathan Lam Date: Tue, 14 Feb 2017 20:06:39 -0500 Subject: [PATCH 1/9] Created dev branch ADDED: - dev branch for testing changes locally first before using travis-ci. CHANGED: - travis-ci configuration changed to only run when master is committed to. --- .travis.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.travis.yml b/.travis.yml index da64fef..2f961f1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,3 +20,7 @@ install: script: - busted + +branches: + only: + - master From 98b7d4a84407656b097f0b45e5686df839a50e26 Mon Sep 17 00:00:00 2001 From: Nathan Lam Date: Wed, 15 Feb 2017 18:12:31 -0500 Subject: [PATCH 2/9] Added event handling ADDED: - Event listener methods for adding and removing them. - Methods for sending events locally, toward root and toward descendents. - Tests for event listeners. --- scene.lua | 78 +++++++++++++++++++++++++++++++++++++++++++++ spec/event_spec.lua | 74 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 152 insertions(+) create mode 100644 spec/event_spec.lua diff --git a/scene.lua b/scene.lua index dc23ffb..7fcd5bf 100644 --- a/scene.lua +++ b/scene.lua @@ -12,6 +12,12 @@ local function min_bounds(x, y, half_width, half_height) return x - half_width, y - half_height end +local function insert_all(src, dest) + for _, value in ipairs(src) do + table.insert(dest, value) + end +end + --[[ A node representing a local transform. --]] @@ -36,6 +42,7 @@ function node:init(params) self.halfw = (params and params.halfw) or 0 self.halfh = (params and params.halfh) or 0 self._id = (params and params.id) or nil + self.listeners = {} end -- Adds id to id tables of all ancestors @@ -187,6 +194,77 @@ function node:calc_bounds() end end +function node:on(event_type, listener) + self.listeners[event_type] = self.listeners[event_type] or {} + table.insert(self.listeners[event_type], listener) + return listener +end + +function node:off(event_type, listener) + if listener == nil then + self.listeners[event_type] = nil + else + local pos = nil + for i, value in ipairs(self.listeners[event_type]) do + if value == listener then + pos = i + break + end + end + + if pos ~= nil then + table.remove(self.listeners[event_type], pos) + end + end +end + +-- Sends event to current node only +function node:fire(event_type, ...) + for _, listener in ipairs(self.listeners[event_type]) do + local stopLocal, stopGlobal = listener(...) + if stopGlobal then + return false + elseif stopLocal then + break + end + end + + return true +end + +-- Sends event to root +function node:emit(event_type, ...) + if not self:fire(event_type, ...) then + return + end + + self.parent:emit(event_type, ...) +end + +-- Sends event to descendents +function node:broadcast(event_type, ...) + if not self:fire(event_type, ...) then + return + end + + -- Breadth first traversal of scene tree + local queue = {} + local qpos = 1 + insert_all(self.children, queue) + while qpos <= #queue do + local next = queue[qpos] + if not child:fire(event_type, ...) then + return + end + + if child.children ~= nil then + insert_all(child.children, queue) + end + + qpos = qpos + 1 + end +end + scene.node = node ----------------------------------------------- diff --git a/spec/event_spec.lua b/spec/event_spec.lua new file mode 100644 index 0000000..36fa9df --- /dev/null +++ b/spec/event_spec.lua @@ -0,0 +1,74 @@ +local scene = require('scene') + +local describe = require('busted').describe +local it = require('busted').it + +describe("event listeners", function() + it("can be attached to nodes", function() + local node = scene.node() + node:on("test", function(obj) + obj.test_value = true + end) + + local event = {test_value=false} + node:fire("test", event) + assert.is_true(event.test_value) + end) + + it("can be removed", function() + local node = scene.node() + local listener = node:on("test", function() + print("will be removed") + end) + + assert.is_equal(#node.listeners["test"], 1) + node:off("test", listener) + assert.is_equal(#node.listeners["test"], 0) + end) + + it("can be emitted", function() + local node1 = scene.node() + local node2 = scene.node() + local node3 = scene.node() + + node1:attach(node2) + node2:attach(node3) + + local listener = node1:on("test", function(obj) + obj.test_value = obj.test_value + 1 + end) + node2:on("test", listener) + node3:on("test", listener) + + local test_obj = {test_value=0} + node3:emit("test", test_obj) + + assert.is_equal(test_obj.test_value, 3) + end) + + it("can be broadcasted", function() + local node1 = scene.node() + local node2 = scene.node() + local node3 = scene.node() + + node1:attach(node2) + node1:attach(node3) + + node1:on("test", function(obj) + table.insert(obj.received, node1) + end) + node2:on("test", function(obj) + table.insert(obj.received, node2) + end) + node3:on("test", function(obj) + table.insert(obj.received, node3) + end) + + local test_obj = {received={}} + node3:emit("test", test_obj) + + assert.is_equal(test_obj.received[1], node1) + assert.is_equal(test_obj.received[2], node2) + assert.is_equal(test_obj.received[3], node3) + end) +end) From 9c1f6da5465f41f7b236745f7f2b0b04d0710de9 Mon Sep 17 00:00:00 2001 From: Nathan Lam Date: Wed, 15 Feb 2017 18:15:15 -0500 Subject: [PATCH 3/9] Fixed error in emit CHANGED: - Emit now checks that parent is not nil before propagating. --- scene.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/scene.lua b/scene.lua index 7fcd5bf..e2af4f5 100644 --- a/scene.lua +++ b/scene.lua @@ -238,7 +238,9 @@ function node:emit(event_type, ...) return end - self.parent:emit(event_type, ...) + if self.parent then + self.parent:emit(event_type, ...) + end end -- Sends event to descendents From a9660a3d3b277c16da6197ab5b7958f91c4123d4 Mon Sep 17 00:00:00 2001 From: Nathan Lam Date: Wed, 15 Feb 2017 18:21:04 -0500 Subject: [PATCH 4/9] Debugging error in broadcast test ADDED: - Print statement for nodes being received. --- spec/event_spec.lua | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/spec/event_spec.lua b/spec/event_spec.lua index 36fa9df..4db5d83 100644 --- a/spec/event_spec.lua +++ b/spec/event_spec.lua @@ -47,9 +47,9 @@ describe("event listeners", function() end) it("can be broadcasted", function() - local node1 = scene.node() - local node2 = scene.node() - local node3 = scene.node() + local node1 = scene.node{id="1"} + local node2 = scene.node{id="2"} + local node3 = scene.node{id="3"} node1:attach(node2) node1:attach(node3) @@ -67,6 +67,9 @@ describe("event listeners", function() local test_obj = {received={}} node3:emit("test", test_obj) + for i, node in ipairs(test_obj.received) do + print(i, node.id()) + end assert.is_equal(test_obj.received[1], node1) assert.is_equal(test_obj.received[2], node2) assert.is_equal(test_obj.received[3], node3) From 3673b68eb18ffc7a0bb3b401912ec691497a6d84 Mon Sep 17 00:00:00 2001 From: Nathan Lam Date: Wed, 15 Feb 2017 18:22:50 -0500 Subject: [PATCH 5/9] Fixed error in debug statement CHANGED: - id() uses method notation. --- spec/event_spec.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/event_spec.lua b/spec/event_spec.lua index 4db5d83..e1a2109 100644 --- a/spec/event_spec.lua +++ b/spec/event_spec.lua @@ -68,7 +68,7 @@ describe("event listeners", function() node3:emit("test", test_obj) for i, node in ipairs(test_obj.received) do - print(i, node.id()) + print(i, node:id()) end assert.is_equal(test_obj.received[1], node1) assert.is_equal(test_obj.received[2], node2) From 167af29b35ddff4515fdced112e9868b9d84b26c Mon Sep 17 00:00:00 2001 From: Nathan Lam Date: Wed, 15 Feb 2017 18:28:57 -0500 Subject: [PATCH 6/9] Fixed error in broadcast test CHANGED: - Broadcast test was using emit() instead of broadcast() --- spec/event_spec.lua | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/spec/event_spec.lua b/spec/event_spec.lua index e1a2109..78fa060 100644 --- a/spec/event_spec.lua +++ b/spec/event_spec.lua @@ -65,11 +65,8 @@ describe("event listeners", function() end) local test_obj = {received={}} - node3:emit("test", test_obj) + node3:broadcast("test", test_obj) - for i, node in ipairs(test_obj.received) do - print(i, node:id()) - end assert.is_equal(test_obj.received[1], node1) assert.is_equal(test_obj.received[2], node2) assert.is_equal(test_obj.received[3], node3) From 8a5fc4a4423f0a6746f3acff8d98a53d975b1b96 Mon Sep 17 00:00:00 2001 From: Nathan Lam Date: Wed, 15 Feb 2017 18:32:37 -0500 Subject: [PATCH 7/9] Fixed error in handling nil case CHANGED: - Check for nil on node being broadcasted. --- scene.lua | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/scene.lua b/scene.lua index e2af4f5..db0d25d 100644 --- a/scene.lua +++ b/scene.lua @@ -249,6 +249,10 @@ function node:broadcast(event_type, ...) return end + if not self.children then + return + end + -- Breadth first traversal of scene tree local queue = {} local qpos = 1 @@ -259,7 +263,7 @@ function node:broadcast(event_type, ...) return end - if child.children ~= nil then + if child.children then insert_all(child.children, queue) end From ca2662505e098fae1d3036eafb89398eaf64ff0d Mon Sep 17 00:00:00 2001 From: Nathan Lam Date: Wed, 15 Feb 2017 18:34:55 -0500 Subject: [PATCH 8/9] Fixed another error in broadcast test CHANGED: - Node1 should be broadcasting not node3 --- spec/event_spec.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/event_spec.lua b/spec/event_spec.lua index 78fa060..b423c02 100644 --- a/spec/event_spec.lua +++ b/spec/event_spec.lua @@ -65,7 +65,7 @@ describe("event listeners", function() end) local test_obj = {received={}} - node3:broadcast("test", test_obj) + node1:broadcast("test", test_obj) assert.is_equal(test_obj.received[1], node1) assert.is_equal(test_obj.received[2], node2) From f2a2578a9ca87d4e4eb5dfae04f0a8cecefad50c Mon Sep 17 00:00:00 2001 From: Nathan Lam Date: Wed, 15 Feb 2017 18:36:39 -0500 Subject: [PATCH 9/9] Fixed error in broadcast method CHANGED: - Forgot to rename 'child' variable name to 'next' when changing structure. --- scene.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scene.lua b/scene.lua index db0d25d..a9ff374 100644 --- a/scene.lua +++ b/scene.lua @@ -259,12 +259,12 @@ function node:broadcast(event_type, ...) insert_all(self.children, queue) while qpos <= #queue do local next = queue[qpos] - if not child:fire(event_type, ...) then + if not next:fire(event_type, ...) then return end - if child.children then - insert_all(child.children, queue) + if next.children then + insert_all(next.children, queue) end qpos = qpos + 1