1+ local class = require (" ccClass" )
2+
3+ --- @class Event
4+ --- @field eventName string
5+ --- @field eventArgs table | nil
6+ --- @field receivedBy table
7+
8+ --- @class timer
9+ --- @field id number
10+ --- @field triggerAfter number
11+
12+ --- @class timerList
13+ --- @field timers timer[]
14+ --- @field currentID number
15+
16+ --- @class ccEvent
17+ --- @field FIFOEventList Event[]
18+ --- @field FIFOTimerList timerList
19+ --- @field co thread
20+ --- @field time number eq. os.time (" ingame" ) from ccTweaked )
21+ --- @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 )
31+ --- @cast baseClass ccEvent
32+ baseClass .FIFOEventList = {}
33+ baseClass .FIFOTimerList = {timers = {}, currentID = 1 }
34+ baseClass .time = 0
35+ baseClass .epoch = 0
36+
37+ end )()
38+
39+ local env = {}
40+ --- @class EventOS : oslib
41+ env .os = setmetatable ({
42+
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" )}
47+ end
48+ return table.unpack (t )
49+ end ,
50+ queueEvent = function (name , ...)
51+ eventObj :invoke (name , arg )
52+ end ,
53+ startTimer = function (time )
54+ return eventObj :addTimer (time )
55+ end ,
56+ cancleTimer = function (id )
57+ eventObj :removeTimer (id )
58+ end
59+
60+ }, {__index = os })
61+ setmetatable (env , {__index = _G })
62+
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
73+
74+
75+
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 )
86+
87+ function Events :addTimer (time )
88+ local triggerAt = time * 1000 + self .epoch
89+ local id = self .FIFOTimerList .currentID
90+ self .FIFOTimerList .currentID = self .FIFOTimerList .currentID + 1
91+ table.insert (self .FIFOTimerList .timers , {triggerAt = triggerAt , id = id })
92+ return id
93+ end
94+
95+ function Events :removeTimer (id )
96+ for k ,v in pairs (self .FIFOTimerList .timers ) do
97+ if v .id == id then
98+ self .FIFOTimerList .currentID [id ] = nil
99+ end
100+ end
101+ end
102+
103+ --- Passes time (in Seconds)
104+ --- Required for timers
105+ --- @param time number seconds
106+ function Events :passTime (time )
107+ self .time = (self .time + (time / 60 / 24 )) % 24
108+ self .epoch = self .epoch + time
109+
110+ for key , value in pairs (self .FIFOTimerList .timers ) do
111+ if value .triggerAfter <= self .epoch then
112+ self :invoke (" timer" , value .id )
113+ end
114+ end
115+
116+ end
117+
118+ function Events :invoke (eventName , ...)
119+ --- @type Event
120+ local event = {eventName = eventName , receivedBy = {}, eventArgs = arg }
121+ table.insert (self .FIFOEventList , event )
122+ self .newEventAdded = true
123+ coroutine.resume (run , " tick" )
124+ end
125+
126+ return Events
0 commit comments