Skip to content

Commit e18c8a0

Browse files
committed
changed name to Observer
1 parent 845538d commit e18c8a0

File tree

5 files changed

+127
-127
lines changed

5 files changed

+127
-127
lines changed

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
1-
# subscriber-lib
1+
# Observer-lib
22

33
A library which allows to listen to changes in any table
44

55
# Example
66

77
```lua
8-
local createSubscriber = require("../subscriber")
8+
local createObserver = require("../observer")
99

1010
local t = {
1111
[1] = "example",
1212
[2] = "example 2"
1313
}
14-
local s = createSubscriber(t)
14+
local s = createObserver(t)
1515

1616
local id = s.subscribe(function(event, data)
1717
print(event) -- 1. "Insert" | "Modify" | "Delete"

files.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
subscriber.lua
1+
observer.lua

observer.lua

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
local function deepcopy(tbl, copyTo)
2+
if type(tbl) ~= "table" then return tbl end
3+
copyTo = copyTo or {}
4+
for k, v in pairs(tbl) do
5+
copyTo[deepcopy(k)] = deepcopy(v)
6+
end
7+
return copyTo
8+
end
9+
local function emptyTable(tbl)
10+
for k, _ in pairs(tbl) do
11+
tbl[k] = nil
12+
end
13+
end
14+
15+
16+
17+
---@param object table The table which the subscribtion should be created for
18+
local CreateObserver = function(object)
19+
---@class Observer
20+
local Observer = {
21+
obj = {},
22+
listeners = {},
23+
listenerID = 1,
24+
originalMetaTable = getmetatable(object),
25+
running = true
26+
}
27+
28+
local function init()
29+
assert(type(object) == "table",
30+
"Observer can only be created for tables. Got a " .. type(object) .. " instead.")
31+
Observer.obj = deepcopy(object)
32+
Observer.listenerID = 1
33+
Observer.listeners = {}
34+
Observer.originalMetaTable = deepcopy(getmetatable(object) or {})
35+
36+
emptyTable(object)
37+
local mt
38+
mt = deepcopy(getmetatable(object) or {})
39+
40+
mt.__newindex = function(_, key, value)
41+
if value == nil then
42+
Observer.notify("Delete", { key, value, Observer.obj[key] })
43+
elseif Observer.obj[key] == nil then
44+
Observer.notify("Insert", { key, value })
45+
else
46+
Observer.notify("Modify", { key, value, Observer.obj[key] })
47+
end
48+
rawset(Observer.obj, key, value)
49+
end
50+
mt.__index = function(_, key)
51+
return rawget(Observer.obj, key)
52+
end
53+
setmetatable(object, mt)
54+
end
55+
56+
local function returnToOriginalState()
57+
Observer.listeners = nil
58+
Observer.running = false
59+
setmetatable(object, Observer.originalMetaTable)
60+
deepcopy(Observer.obj, object)
61+
Observer.obj = nil
62+
end
63+
64+
function Observer.subscribe(listener)
65+
if Observer.running == false then
66+
init()
67+
end
68+
Observer.listeners[Observer.listenerID] = listener
69+
Observer.listenerID = Observer.listenerID + 1
70+
return Observer.listenerID - 1
71+
end
72+
73+
function Observer.notify(event, data)
74+
if Observer.listeners == nil then
75+
return
76+
end
77+
for _, listener in pairs(Observer.listeners) do
78+
listener(event, data)
79+
end
80+
end
81+
82+
function Observer.unsubscribe(ID)
83+
Observer.listeners[ID] = nil
84+
end
85+
86+
function Observer.unsubscribeAll()
87+
returnToOriginalState()
88+
end
89+
90+
init()
91+
92+
return Observer
93+
end
94+
95+
return CreateObserver

subscriber.lua

Lines changed: 0 additions & 95 deletions
This file was deleted.

tests/test_spec.lua

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,13 @@
2727
---@field equal function
2828
assert = assert
2929

30-
local subscriber = require("../subscriber")
30+
local observer = require("../observer")
3131

3232
describe("Subscribe", function()
3333
it("Table behaves normal", function()
3434
local t = { [1] = "test", [2] = "test2" }
3535
assert.are.equal("test", t[1])
36-
local sub = subscriber(t)
36+
local sub = observer(t)
3737
t[3] = "test3"
3838

3939
-- old table should still have the same values
@@ -48,8 +48,8 @@ describe("Subscribe", function()
4848
end)
4949
it("Delete should trigger", function()
5050
local t = { [1] = "test", [2] = "test2" }
51-
local sub = subscriber(t)
52-
sub.subscribe(function(event, data)
51+
local o = observer(t)
52+
o.subscribe(function(event, data)
5353
assert.are.equal("Delete", event)
5454
assert.are.equal(1, data[1])
5555
assert.are.equal(nil, data[2])
@@ -61,8 +61,8 @@ describe("Subscribe", function()
6161
end)
6262
it("Modify should trigger", function()
6363
local t = { [1] = "test", [2] = "test2" }
64-
local sub = subscriber(t)
65-
sub.subscribe(function(event, data)
64+
local o = observer(t)
65+
o.subscribe(function(event, data)
6666
assert.are.equal("Modify", event)
6767
assert.are.equal("test3", data[2])
6868
assert.is_true("test" == data[3])
@@ -73,8 +73,8 @@ describe("Subscribe", function()
7373
end)
7474
it("Insert should trigger", function()
7575
local t = {}
76-
local sub = subscriber(t)
77-
sub.subscribe(function(event, data)
76+
local o = observer(t)
77+
o.subscribe(function(event, data)
7878
assert.are.equal("Insert", event)
7979
assert.True(("test" == data[2]) or ("test2" == data[2]))
8080
end)
@@ -85,26 +85,26 @@ describe("Subscribe", function()
8585
end)
8686
it("Unsubscribe should work", function()
8787
local t = { [1] = "test", [2] = "test2" }
88-
local sub = subscriber(t)
89-
local id = sub.subscribe(function(event, data)
88+
local o = observer(t)
89+
local id = o.subscribe(function(event, data)
9090
assert.are.equal("Modify", event)
9191
assert.are.equal("new Test", data[2])
9292
end)
9393
t[1] = "new Test"
9494
assert.are.equal("new Test", t[1])
95-
sub.unsubscribe(id)
95+
o.unsubscribe(id)
9696
t[2] = "new Test 2"
9797
assert.are.equal("new Test 2", t[2])
9898
end)
9999
describe("Multiple subscribers", function()
100100
it("Multiple Subscribtions shoud work", function()
101101
local t = { [1] = "test", [2] = "test2" }
102-
local sub = subscriber(t)
102+
local o = observer(t)
103103
local calls = 0
104-
sub.subscribe(function(_, _)
104+
o.subscribe(function(_, _)
105105
calls = calls + 1
106106
end)
107-
sub.subscribe(function(event, data)
107+
o.subscribe(function(event, data)
108108
calls = calls + 1
109109
assert.are.equal("Modify", event)
110110
assert.are.equal("new Test 2", data[2])
@@ -115,17 +115,17 @@ describe("Subscribe", function()
115115
end)
116116
it("Unsubscribing once should work", function()
117117
local t = { [1] = "test", [2] = "test2" }
118-
local sub = subscriber(t)
118+
local o = observer(t)
119119
local calls = 0
120-
local id = sub.subscribe(function(_, _)
120+
local id = o.subscribe(function(_, _)
121121
calls = calls + 1
122122
end)
123-
sub.subscribe(function(event, data)
123+
o.subscribe(function(event, data)
124124
calls = calls + 1
125125
assert.are.equal("Modify", event)
126126
assert.are.equal("new Test 2", data[2])
127127
end)
128-
sub.unsubscribe(id)
128+
o.unsubscribe(id)
129129
t[2] = "new Test 2"
130130
assert.are.equal("new Test 2", t[2])
131131
assert.are.equal(1, calls)
@@ -134,8 +134,8 @@ describe("Subscribe", function()
134134
describe("Metatables", function()
135135
it("Metatable should be set", function()
136136
local t = { [1] = "test" }
137-
local sub = subscriber(t)
138-
assert.False(sub.originalMetaTable == getmetatable(t))
137+
local o = observer(t)
138+
assert.False(o.originalMetaTable == getmetatable(t))
139139
end)
140140
it("Metatable should be reset", function()
141141
local t = { [1] = "test" }
@@ -150,17 +150,17 @@ describe("Subscribe", function()
150150
end
151151
}
152152
setmetatable(t, metatable)
153-
local sub = subscriber(t)
153+
local o = observer(t)
154154
local newCalls = 0
155-
sub.subscribe(function(event, data)
155+
o.subscribe(function(event, data)
156156
assert.are.equal("Modify", event)
157157
assert.are.equal("new Test", data[2])
158158
newCalls = newCalls + 1
159159
end)
160160
t[1] = "new Test"
161161
assert.are.equal(1, newCalls)
162-
sub.unsubscribeAll()
163-
sub = nil
162+
o.unsubscribeAll()
163+
o = nil
164164
t[2] = "new Test 2"
165165
assert.are.equal(1, oldCall)
166166
assert.are.equal(metatable.__newindex, getmetatable(t).__newindex)
@@ -172,16 +172,16 @@ describe("Subscribe", function()
172172
describe("Resetting", function()
173173
it("Should reset and then Restart", function()
174174
local t = { [1] = "test", [2] = "test2" }
175-
local sub = subscriber(t)
176-
sub.subscribe(function(event, data)
175+
local o = observer(t)
176+
o.subscribe(function(event, data)
177177
assert.are.equal("Modify", event)
178178
assert.are.equal("new Test", data[2])
179179
end)
180180
t[1] = "new Test"
181181
assert.are.equal("new Test", t[1])
182-
local t2 = sub.unsubscribeAll()
182+
local t2 = o.unsubscribeAll()
183183
assert.are.equal("new Test", t[1])
184-
sub.subscribe(function(event, data)
184+
o.subscribe(function(event, data)
185185
assert.are.equal("Modify", event)
186186
assert.are.equal("new Test 2", data[2])
187187
end)

0 commit comments

Comments
 (0)