Skip to content

Commit f508039

Browse files
committed
WIP
1 parent 54f8cba commit f508039

File tree

4 files changed

+87
-34
lines changed

4 files changed

+87
-34
lines changed

.github/workflows/test.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,12 @@ jobs:
1313
- name: get lua
1414
uses: leafo/gh-actions-lua@v10
1515
with:
16-
luaVersion: "5.2"
16+
luaVersion: "5.1"
1717

1818
- name: get luarocks
1919
uses: leafo/gh-actions-luarocks@v4
2020
with:
21-
luaVersion: "5.2"
21+
luaVersion: "5.1"
2222

2323
- name: get busted and luasocket
2424
run: |

events.lua

Lines changed: 40 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,13 @@ local class = require("ccClass")
1414
---@field currentID number
1515

1616
---@class subThread
17+
---@field originalFunction function
1718
---@field thread thread
1819
---@field waiting boolean
1920

2021
---@class ccEvent
2122
---@field FIFOEventList Event[]
22-
---@field FIFOTimerList timerList
23+
---@field TimerList timerList
2324
---@field thread thread
2425
---@field subThreads table<string, subThread>
2526
---@field time number eq. os.time("ingame") from ccTweaked)
@@ -29,14 +30,14 @@ local Events = class(
2930
function(baseClass)
3031
---@cast baseClass ccEvent
3132
baseClass.FIFOEventList = {}
32-
baseClass.FIFOTimerList = {timers = {}, currentID = 1}
33+
baseClass.TimerList = {timers = {}, currentID = 1}
3334
baseClass.time = 0
3435
baseClass.epoch = 0
3536
baseClass.subThreads = {}
3637
baseClass.run = coroutine.create(
3738
function()
3839
while true do
39-
while #baseClass.FIFOEventList > 0 do
40+
while #baseClass.FIFOEventList > 0 do -- TODO if a DID trigger something, stop?
4041
local event = table.remove(baseClass.FIFOEventList, 1)
4142
---@cast event Event
4243
if coroutine.status(baseClass.thread) == "suspended" then -- Modules should be "dead"
@@ -45,8 +46,10 @@ local Events = class(
4546
end
4647
for key, value in pairs(baseClass.subThreads) do
4748
if value.waiting then
48-
assert(coroutine.status(value.thread) == "suspended")
4949
assert(coroutine.resume(value.thread, event.eventName, table.unpack(event.eventArgs)))
50+
if coroutine.status(value.thread) == "dead" then
51+
value.waiting = false
52+
end
5053
end
5154
end
5255
end
@@ -61,7 +64,7 @@ local Events = class(
6164
---@param func function | T
6265
---@param wrapModule? boolean This will modify the Module!
6366
---@param ... any If loading a Module, these are the parameters
64-
---@return T|any|nil result if module is wrapped, it returns the wrapped module.
67+
---@return T|nil result if module is wrapped, it returns the wrapped module.
6568
function Events:wrap(func, wrapModule, ...)
6669
assert(self.subThreads, "Do not use Eventclass, create an Event-Object via 'local eventObj = ccEvent()'")
6770
local manager = self
@@ -79,9 +82,10 @@ function Events:wrap(func, wrapModule, ...)
7982
return table.unpack(event)
8083
end,
8184
queueEvent = function(name, ...)
82-
manager:invoke(name, arg)
85+
manager:invoke(name, ...)
8386
end,
8487
startTimer = function(time)
88+
assert(type(time) == "number")
8589
return manager:addTimer(time)
8690
end,
8791
cancleTimer = function(id)
@@ -109,13 +113,21 @@ function Events:wrap(func, wrapModule, ...)
109113
for k,v in pairs(result) do
110114
if type(v) == "function" and (self.subThreads[k] == nil)then
111115
local thread = coroutine.create(v)
112-
self.subThreads[k] = {
113-
thread = thread,
114-
waiting = false
115-
}
116+
self.subThreads[k] = {
117+
thread = thread,
118+
originalFunction = v,
119+
waiting = false
120+
}
116121
result[k] = function(...)
117122
local ok, result = coroutine.resume(self.subThreads[k].thread, ...)
118-
self.subThreads[k].waiting = coroutine.status(self.subThreads[k].thread) == "suspended"
123+
local status = coroutine.status(self.subThreads[k].thread)
124+
if status == "dead" then
125+
-- "restart" function => create new Thread
126+
self.subThreads[k].thread = coroutine.create(self.subThreads[k].originalFunction)
127+
self.subThreads[k].waiting = false
128+
else
129+
self.subThreads[k].waiting = true
130+
end
119131
assert(ok, "coroutine Error: "..tostring(result))
120132
return result
121133
end
@@ -126,19 +138,22 @@ function Events:wrap(func, wrapModule, ...)
126138
end
127139

128140

129-
141+
---@param time number seconds
142+
---@return number timerID
130143
function Events:addTimer(time)
131-
local triggerAt = time * 1000 + self.epoch
132-
local id = self.FIFOTimerList.currentID
133-
self.FIFOTimerList.currentID = self.FIFOTimerList.currentID + 1
134-
table.insert(self.FIFOTimerList.timers, {triggerAt = triggerAt, id = id})
144+
assert(type(time) == "number" and time > 0)
145+
local triggerAfter = time * 1000 + self.epoch - 1
146+
local id = self.TimerList.currentID
147+
self.TimerList.currentID = self.TimerList.currentID + 1
148+
table.insert(self.TimerList.timers, {triggerAfter = triggerAfter, id = id})
135149
return id
136150
end
137151

138152
function Events:removeTimer(id)
139-
for k,v in pairs(self.FIFOTimerList.timers) do
153+
assert(type(id) == "number")
154+
for k,v in pairs(self.TimerList.timers) do
140155
if v.id == id then
141-
self.FIFOTimerList.currentID[id] = nil
156+
self.TimerList.currentID[id] = nil
142157
end
143158
end
144159
end
@@ -147,20 +162,23 @@ end
147162
---Required for timers
148163
---@param time number seconds
149164
function Events:passTime(time)
150-
self.time = (self.time + (time / 60 / 24)) % 24
165+
assert(type(time) == "number")
166+
time = time * 1000
167+
self.time = (self.time + (time / 60 / 24)) % 24 -- TODO: Test
151168
self.epoch = self.epoch + time
152169

153-
for key, value in pairs(self.FIFOTimerList.timers) do
154-
if value.triggerAfter <= self.epoch then
170+
for key, value in pairs(self.TimerList.timers) do
171+
if value.triggerAfter < self.epoch then
155172
self:invoke("timer", value.id)
173+
self.TimerList.timers[key] = nil
156174
end
157175
end
158176

159177
end
160178

161179
function Events:invoke(eventName, ...)
162180
---@type Event
163-
local event = {eventName = eventName, receivedBy = {}, eventArgs = ... or {}}
181+
local event = {eventName = eventName, receivedBy = {}, eventArgs = {...}}
164182
table.insert(self.FIFOEventList, event)
165183
self.newEventAdded = true
166184
assert(coroutine.resume(self.run, "tick"))

tests/event_spec.lua

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ package.path = package.path .. ";"
3434
local EventEmulator = require("events")
3535

3636
describe("Event-Tests", function ()
37-
---@type ccEvent, TestFile | nil, string
37+
---@type ccEvent, TestFile, string
3838
local eventManager, testModule, invokeWord
3939
local path = "tests/testFiles/event_testFile.lua"
4040
before_each(function()
@@ -49,25 +49,49 @@ describe("Event-Tests", function ()
4949
end, false)
5050

5151
testFunc("parameterCheck")
52-
assert.are.equal(coroutine.status(eventManager.thread), "suspended")
52+
assert.are.equal("suspended", coroutine.status(eventManager.thread))
5353
eventManager:invoke()
54-
assert.are.equal(coroutine.status(eventManager.thread), "suspended")
54+
assert.are.equal("suspended", coroutine.status(eventManager.thread))
5555
eventManager:invoke(invokeWord)
56-
assert.are.equal(coroutine.status(eventManager.thread), "dead")
56+
assert.are.equal("dead", coroutine.status(eventManager.thread))
5757
end)
5858
it("Pull and invoke on module", function()
5959
local file = loadfile(path, "t")
6060
testModule = eventManager:wrap(file, true)
6161
assert(type(testModule)=="table", type(testModule))
62+
6263
invokeWord = "test"
63-
assert.are.equal(eventManager.subThreads.event1.waiting, false)
64-
testModule:event1(invokeWord) -- start function (in thread)
65-
assert.are.equal(eventManager.subThreads.event1.waiting, true)
64+
assert.are.equal(false, eventManager.subThreads.event1.waiting)
65+
testModule:event1(invokeWord) -- start function (runs in a thread)
66+
assert.are.equal(true, eventManager.subThreads.event1.waiting)
6667
eventManager:invoke("wrongword")
67-
assert.are.equal(coroutine.status(eventManager.subThreads.event1.thread), "suspended")
68+
assert.are.equal("suspended", coroutine.status(eventManager.subThreads.event1.thread))
6869
eventManager:invoke(invokeWord)
69-
assert.are.equal(coroutine.status(eventManager.subThreads.event1.thread), "dead")
70-
assert.are.equal(testModule.status.event1, invokeWord)
70+
assert.are.equal(false, eventManager.subThreads.event1.waiting)
71+
assert.are.equal(invokeWord, testModule.status.event1)
72+
end)
73+
end)
74+
describe("Timer",function()
75+
it("startTimer", function()
76+
local file = loadfile(path, "t")
77+
testModule = eventManager:wrap(file, true)
78+
assert(testModule)
79+
80+
testModule:event2()
81+
testModule:event2()
82+
testModule:event2()
83+
assert.are.same(1, #eventManager.TimerList.timers) -- only one timer is inserted, the pullEvent didn't trigger
84+
85+
assert.are.same(1, testModule.status.event2)
86+
eventManager:passTime(3)
87+
assert.are.same(1, testModule.status.event2)
88+
eventManager:passTime(1)
89+
assert.are.same(1, testModule.status.event2)
90+
eventManager:passTime(1)
91+
assert.are.same(nil, testModule.status.event2)
92+
eventManager:passTime(1)
93+
assert.are.same(nil, testModule.status.event2) -- the next pullEvent should never be triggered
7194
end)
95+
7296
end)
7397
end)

tests/testFiles/event_testFile.lua

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,17 @@ function TestFile:event1(p1)
99
return p1
1010
end
1111

12+
function TestFile:event2()
13+
local timerID = os.startTimer(5)
14+
self.status.event2 = timerID
15+
local event, id = os.pullEvent("timer")
16+
if (id ~= 1) then error("Wrong timer triggerd") end
17+
self.status.event2 = nil
18+
event = os.pullEvent("timer")
19+
self.status.event2 = "Should not be filled"
20+
21+
end
22+
1223

1324

1425
return TestFile

0 commit comments

Comments
 (0)