@@ -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
87130function Events :addTimer (time )
88131 local triggerAt = time * 1000 + self .epoch
@@ -117,10 +160,10 @@ end
117160
118161function 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" ) )
124167end
125168
126169return Events
0 commit comments