Skip to content

Commit 54f8cba

Browse files
committed
WIP
1 parent b517eb1 commit 54f8cba

File tree

4 files changed

+122
-57
lines changed

4 files changed

+122
-57
lines changed

events.lua

Lines changed: 86 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -13,76 +13,119 @@ local class = require("ccClass")
1313
---@field timers timer[]
1414
---@field currentID number
1515

16+
---@class subThread
17+
---@field thread thread
18+
---@field waiting boolean
19+
1620
---@class ccEvent
1721
---@field FIFOEventList Event[]
1822
---@field FIFOTimerList timerList
19-
---@field co thread
23+
---@field thread thread
24+
---@field subThreads table<string, subThread>
2025
---@field time number eq. os.time("ingame") from ccTweaked)
2126
---@field epoch number eq. os.epoch("ingame") from ccTweaked)
22-
---@field private tmpObj any
23-
local Events = {}
24-
25-
---@param path string
26-
---@return ccEvent
27-
---@return table loadedModule
28-
function Events:new(path)
29-
30-
local eventObj = class(function(baseClass)
27+
---@field private run thread
28+
local Events = class(
29+
function(baseClass)
3130
---@cast baseClass ccEvent
3231
baseClass.FIFOEventList = {}
3332
baseClass.FIFOTimerList = {timers = {}, currentID = 1}
3433
baseClass.time = 0
3534
baseClass.epoch = 0
36-
37-
end)()
38-
35+
baseClass.subThreads = {}
36+
baseClass.run = coroutine.create(
37+
function()
38+
while true do
39+
while #baseClass.FIFOEventList > 0 do
40+
local event = table.remove(baseClass.FIFOEventList, 1)
41+
---@cast event Event
42+
if coroutine.status(baseClass.thread) == "suspended" then -- Modules should be "dead"
43+
coroutine.resume(baseClass.thread, event.eventName, table.unpack(event.eventArgs))
44+
-- just empty the list until an event was valid OR no Events are left
45+
end
46+
for key, value in pairs(baseClass.subThreads) do
47+
if value.waiting then
48+
assert(coroutine.status(value.thread) == "suspended")
49+
assert(coroutine.resume(value.thread, event.eventName, table.unpack(event.eventArgs)))
50+
end
51+
end
52+
end
53+
coroutine.yield("tick")
54+
end
55+
end
56+
)
57+
end
58+
)
59+
60+
---@generic T
61+
---@param func function | T
62+
---@param wrapModule? boolean This will modify the Module!
63+
---@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.
65+
function Events:wrap(func, wrapModule, ...)
66+
assert(self.subThreads, "Do not use Eventclass, create an Event-Object via 'local eventObj = ccEvent()'")
67+
local manager = self
3968
local env = {}
4069
---@class EventOS: oslib
4170
env.os = setmetatable({
4271

43-
pullEvent = function(name)
44-
local t = {coroutine.yield(name)}
45-
while not t or (name and t[1] ~= name) do
46-
t = {coroutine.yield(name, "does not match")}
72+
pullEvent = function(expectedEventName)
73+
local firstStart = true
74+
local event
75+
while firstStart or (event[1] ~= expectedEventName) do
76+
event = {coroutine.yield(expectedEventName)}
77+
firstStart = false
4778
end
48-
return table.unpack(t)
79+
return table.unpack(event)
4980
end,
5081
queueEvent = function(name, ...)
51-
eventObj:invoke(name, arg)
82+
manager:invoke(name, arg)
5283
end,
5384
startTimer = function(time)
54-
return eventObj:addTimer(time)
85+
return manager:addTimer(time)
5586
end,
5687
cancleTimer = function(id)
57-
eventObj:removeTimer(id)
88+
manager:removeTimer(id)
5889
end
5990

6091
}, {__index = os})
6192
setmetatable(env, {__index = _G})
93+
setfenv(func, env)
94+
6295

63-
print("stuff", env.os.pullEvent)
64-
local func = assert(loadfile(path, "t", env))
65-
print("func", func)
66-
67-
eventObj.co = coroutine.create(function ()
68-
return func()
69-
end)
70-
local _, loadedModule = coroutine.resume(eventObj.co)
71-
return eventObj, loadedModule
72-
end
96+
self.thread = coroutine.create(func)
97+
98+
if(not wrapModule) then
99+
return function(...)
100+
local ok, result = coroutine.resume(self.thread, ...)
101+
assert(ok, "coroutine Error: "..tostring(result))
102+
return result
103+
end
104+
end
105+
106+
local ok, result = coroutine.resume(self.thread, ...)
107+
assert(ok, "Could not load Module")
108+
assert(type(result) == "table")
109+
for k,v in pairs(result) do
110+
if type(v) == "function" and (self.subThreads[k] == nil)then
111+
local thread = coroutine.create(v)
112+
self.subThreads[k] = {
113+
thread = thread,
114+
waiting = false
115+
}
116+
result[k] = function(...)
117+
local ok, result = coroutine.resume(self.subThreads[k].thread, ...)
118+
self.subThreads[k].waiting = coroutine.status(self.subThreads[k].thread) == "suspended"
119+
assert(ok, "coroutine Error: "..tostring(result))
120+
return result
121+
end
122+
end
123+
end
73124

125+
return result
126+
end
74127

75128

76-
---@param ccEvent ccEvent
77-
local run = coroutine.create(function(ccEvent)
78-
while true do
79-
while #ccEvent.FIFOEventList > 0 and coroutine.status(ccEvent.co) == "suspended" do
80-
coroutine.resume(ccEvent.co, table.remove(ccEvent.FIFOEventList, 1))
81-
-- just empty the list until an event was valid OR no Events are left
82-
end
83-
coroutine.yield("tick")
84-
end
85-
end)
86129

87130
function Events:addTimer(time)
88131
local triggerAt = time * 1000 + self.epoch
@@ -117,10 +160,10 @@ end
117160

118161
function Events:invoke(eventName, ...)
119162
---@type Event
120-
local event = {eventName = eventName, receivedBy = {}, eventArgs = arg}
163+
local event = {eventName = eventName, receivedBy = {}, eventArgs = ... or {}}
121164
table.insert(self.FIFOEventList, event)
122165
self.newEventAdded = true
123-
coroutine.resume(run, "tick")
166+
assert(coroutine.resume(self.run, "tick"))
124167
end
125168

126169
return Events

t.lua

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@ local co = coroutine.create(function (a,b)
33
print("t", t)
44
end)
55
print(coroutine.resume(co, "b"))
6-
print(coroutine.resume(co, "b"))
6+
print(coroutine.resume(co, "b"))
7+

tests/event_spec.lua

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

3636
describe("Event-Tests", function ()
37-
---@type ccEvent, TestFile
38-
local eventManager, testModule
37+
---@type ccEvent, TestFile | nil, string
38+
local eventManager, testModule, invokeWord
39+
local path = "tests/testFiles/event_testFile.lua"
3940
before_each(function()
40-
eventManager, testModule = EventEmulator:new("tests/testFiles/event_testFile.lua")
41+
eventManager = EventEmulator()
4142
end)
4243
describe("Basics", function()
43-
it("pull And Invoke", function()
44+
it("Pull and invoke on function only", function ()
45+
invokeWord = "testEvent"
46+
local testFunc = eventManager:wrap(function(parameter)
47+
assert(parameter == "parameterCheck")
48+
os.pullEvent(invokeWord)
49+
end, false)
50+
51+
testFunc("parameterCheck")
52+
assert.are.equal(coroutine.status(eventManager.thread), "suspended")
53+
eventManager:invoke()
54+
assert.are.equal(coroutine.status(eventManager.thread), "suspended")
55+
eventManager:invoke(invokeWord)
56+
assert.are.equal(coroutine.status(eventManager.thread), "dead")
57+
end)
58+
it("Pull and invoke on module", function()
59+
local file = loadfile(path, "t")
60+
testModule = eventManager:wrap(file, true)
4461
assert(type(testModule)=="table", type(testModule))
45-
testModule:event1()
46-
assert.is.falsy(testModule.status.event1)
47-
eventManager:invoke("TestEvent")
48-
assert.is.truthy(testModule.status.event1)
62+
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)
66+
eventManager:invoke("wrongword")
67+
assert.are.equal(coroutine.status(eventManager.subThreads.event1.thread), "suspended")
68+
eventManager:invoke(invokeWord)
69+
assert.are.equal(coroutine.status(eventManager.subThreads.event1.thread), "dead")
70+
assert.are.equal(testModule.status.event1, invokeWord)
4971
end)
5072
end)
5173
end)

tests/testFiles/event_testFile.lua

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,10 @@ local TestFile = {
33
status = {}
44
}
55

6-
function TestFile:event1()
7-
print("os.execute", os.execute)
8-
print("os.pullEvent", os.pullEvent)
9-
os.pullEvent()
10-
self.status.event1 = "Fired"
6+
function TestFile:event1(p1)
7+
local event = os.pullEvent(p1)
8+
self.status.event1 = event
9+
return p1
1110
end
1211

1312

0 commit comments

Comments
 (0)