Skip to content

Commit 0960920

Browse files
author
Björn Ritzl
committed
Added listener tests and improved the listener module
1 parent 7ffddee commit 0960920

File tree

5 files changed

+334
-67
lines changed

5 files changed

+334
-67
lines changed

examples/listener/listener3.script

+3-4
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
local some_data = require "examples.listener.some_data"
22

33
local function foo(message_id, message)
4+
assert(message_id == some_data.FOO, "Expected only messages of type FOO to be received")
45
print("listener3 foo() received", message_id)
56
end
67

78
function init(self)
8-
some_data.listeners.add({
9-
[some_data.FOO] = foo,
10-
[some_data.BAR] = msg.url(),
11-
})
9+
some_data.listeners.add(foo, some_data.FOO)
10+
some_data.listeners.add(msg.url(), some_data.BAR)
1211
end
1312

1413
function final(self)

ludobits/m/listener.lua

+68-63
Original file line numberDiff line numberDiff line change
@@ -8,28 +8,37 @@
88
--
99
-- local l = listener.create()
1010
--
11-
-- l.add(msg.url("#myscript"))
12-
-- l.add(function(message_id, message)
13-
-- -- handle message
14-
-- end)
15-
-- l.add({
16-
-- [hash("mymessage")] = function(message_id, message)
17-
-- -- handle "mymessage"
18-
-- end,
19-
-- [hash("foobar")] = msg.url("#myscript"),
20-
-- })
11+
-- local function handler1(message_id, message)
12+
-- -- will get mymessage1, mymessage2, mymessage3 and foobar
13+
-- end
14+
--
15+
-- local function handler2(message_id, message)
16+
-- -- will get mymessage1 and mymessage2
17+
-- end
18+
--
19+
-- l.add(handler1)
20+
-- l.add(handler2, "mymessage1")
21+
-- l.add(handler2, "mymessage2")
2122
--
22-
-- l.trigger(hash("mymessage"), { text = "lorem ipsum" })
23+
-- l.add(msg.url("#myscript1"))
24+
-- l.add(msg.url("#myscript2"), "mymessage1")
25+
-- l.add(msg.url("#myscript2"), "mymessage2")
26+
--
27+
--
28+
-- l.trigger(hash("mymessage1"), { text = "lorem ipsum" })
29+
-- l.trigger(hash("mymessage2"), { text = "lorem ipsum" })
30+
-- l.trigger(hash("mymessage3"), { text = "lorem ipsum" })
2331
-- l.trigger(hash("foobar"), { foo = "bar" })
2432
--
2533
--
26-
-- -- myscript.script
34+
-- -- myscript1.script
2735
-- function on_message(self, mesage_id, message, sender)
28-
-- if message_id == hash("mymessage") then
29-
-- -- handle "mymessage"
30-
-- elseif message_id == hahs("foobar") then
31-
-- -- handle "foobar"
32-
-- end
36+
-- -- will get mymessage1, mymessage2, mymessage3 and foobar
37+
-- end
38+
--
39+
-- -- myscript2.script
40+
-- function on_message(self, mesage_id, message, sender)
41+
-- -- will get mymessage1 and mymessage2
3342
-- end
3443
--
3544

@@ -57,51 +66,45 @@ function M.create()
5766
local instance = {}
5867

5968
--- Add a function or url to invoke when the listener is triggered
60-
-- @param url_fn_table This can be one of three things:
61-
-- 1. Function
62-
-- 2. URL
63-
-- 3. Table with mapping between specific message ids and functions or urls
64-
function instance.add(url_fn_table)
65-
-- no function, url or table defined
66-
-- add current script url
67-
if not url_fn_table then
68-
listeners[msg.url()] = {
69-
trigger = trigger_url
70-
}
71-
else
72-
-- add a mapping of message hashes to functions/urls
73-
if type(url_fn_table) == "table" then
74-
for message_id, url_fn in pairs(url_fn_table) do
75-
listeners[url_fn] = {
76-
message_id = ensure_hash(message_id),
77-
trigger = type(url_fn) == "function" and trigger_function or trigger_url
78-
}
79-
end
80-
-- add a function or url
81-
else
82-
listeners[url_fn_table] = {
83-
trigger = type(url_fn_table) == "function" and trigger_function or trigger_url
84-
}
85-
end
86-
end
69+
-- @param url_or_fn_to_add URL or function to call. Can be nil in which case the current URL is used.
70+
-- @param message_id Optional message id to filter on
71+
function instance.add(url_or_fn_to_add, message_id)
72+
url_or_fn_to_add = url_or_fn_to_add or msg.url()
73+
message_id = message_id and ensure_hash(message_id) or nil
74+
listeners[url_or_fn_to_add] = listeners[url_or_fn_to_add] or {}
75+
76+
instance.remove(url_or_fn_to_add, message_id)
77+
table.insert(listeners[url_or_fn_to_add], {
78+
message_id = message_id,
79+
trigger = type(url_or_fn_to_add) == "userdata" and trigger_url or trigger_function
80+
})
8781
end
8882

8983
--- Remove a previously added callback function or url
90-
-- @param url_fn_to_remove
91-
function instance.remove(url_fn_to_remove)
92-
if type(url_fn_to_remove) == "function" then
93-
listeners[url_fn_to_remove] = nil
94-
else
95-
-- urls can't be compared using the equality operator
96-
-- msg.url() ~= msg.url()
97-
-- compare on socket, path and fragment instead
98-
local url_to_remove = url_fn_to_remove or msg.url()
99-
for url_fn,_ in pairs(listeners) do
100-
if type(url_fn) ~= "function"
101-
and url_fn.socket == url_to_remove.socket
102-
and url_fn.path == url_to_remove.path
103-
and url_fn.fragment == url_to_remove.fragment then
104-
listeners[url_fn] = nil
84+
-- @param url_or_fn_to_remove
85+
-- @param message_id Optional message_id to limit removal to
86+
function instance.remove(url_or_fn_to_remove, message_id)
87+
url_or_fn_to_remove = url_or_fn_to_remove or msg.url()
88+
message_id = message_id and ensure_hash(message_id) or nil
89+
90+
local is_url = type(url_or_fn_to_remove) == "userdata"
91+
92+
for url_fn,url_fn_listeners in pairs(listeners) do
93+
-- make sure to only check against urls if we are removing a url and vice versa
94+
if (is_url and type(url_fn) == "userdata") or (not is_url and type(url_fn) ~= "userdata") then
95+
for k,data in pairs(url_fn_listeners) do
96+
if is_url then
97+
if url_fn.socket == url_or_fn_to_remove.socket
98+
and url_fn.path == url_or_fn_to_remove.path
99+
and url_fn.fragment == url_or_fn_to_remove.fragment
100+
and (not message_id or message_id == data.message_id) then
101+
url_fn_listeners[k] = nil
102+
end
103+
else
104+
if url_fn == url_or_fn_to_remove and (not message_id or message_id == data.message_id) then
105+
url_fn_listeners[k] = nil
106+
end
107+
end
105108
end
106109
end
107110
end
@@ -112,11 +115,13 @@ function M.create()
112115
-- @param message The message itself (can be nil)
113116
function instance.trigger(message_id, message)
114117
assert(message_id, "You must provide a message_id")
118+
assert(not message or type(message) == "table", "You must either provide no message or a message of type 'table'")
115119
message_id = ensure_hash(message_id)
116-
message = message or {}
117-
for url_fn,listener in pairs(listeners) do
118-
if not listener.message_id or listener.message_id == message_id then
119-
listener.trigger(url_fn, message_id, message)
120+
for url_fn,url_fn_listeners in pairs(listeners) do
121+
for _,listener in pairs(url_fn_listeners) do
122+
if not listener.message_id or listener.message_id == message_id then
123+
listener.trigger(url_fn, message_id, message or {})
124+
end
120125
end
121126
end
122127
end

test/test.collection

+60
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,66 @@ embedded_instances {
4040
z: 1.0
4141
}
4242
}
43+
embedded_instances {
44+
id: "listener1"
45+
data: ""
46+
position {
47+
x: 0.0
48+
y: 0.0
49+
z: 0.0
50+
}
51+
rotation {
52+
x: 0.0
53+
y: 0.0
54+
z: 0.0
55+
w: 1.0
56+
}
57+
scale3 {
58+
x: 1.0
59+
y: 1.0
60+
z: 1.0
61+
}
62+
}
63+
embedded_instances {
64+
id: "listener2"
65+
data: ""
66+
position {
67+
x: 0.0
68+
y: 0.0
69+
z: 0.0
70+
}
71+
rotation {
72+
x: 0.0
73+
y: 0.0
74+
z: 0.0
75+
w: 1.0
76+
}
77+
scale3 {
78+
x: 1.0
79+
y: 1.0
80+
z: 1.0
81+
}
82+
}
83+
embedded_instances {
84+
id: "listener3"
85+
data: ""
86+
position {
87+
x: 0.0
88+
y: 0.0
89+
z: 0.0
90+
}
91+
rotation {
92+
x: 0.0
93+
y: 0.0
94+
z: 0.0
95+
w: 1.0
96+
}
97+
scale3 {
98+
x: 1.0
99+
y: 1.0
100+
z: 1.0
101+
}
102+
}
43103
embedded_instances {
44104
id: "tests"
45105
data: "components {\n"

test/test.script

+2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ local test_broadcast = require "test.test_broadcast"
33
local test_flow = require "test.test_flow"
44
local test_timer = require "test.test_timer"
55
local test_savefile = require "test.test_savefile"
6+
local test_listener = require "test.test_listener"
67

78
local deftest = require "deftest.deftest"
89

@@ -12,5 +13,6 @@ function init(self)
1213
deftest.add(test_flow)
1314
deftest.add(test_timer)
1415
deftest.add(test_savefile)
16+
deftest.add(test_listener)
1517
deftest.run()
1618
end

0 commit comments

Comments
 (0)