Advertisement
A-G-D

PeriodicEvent

Feb 9th, 2017
119
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.66 KB | None | 0 0
  1. library PeriodicEvent /*
  2.  
  3.  
  4. */requires /*
  5.  
  6. */Alloc /*
  7. */Timer /*
  8. */Table /*
  9. */Trigger /*
  10. */IntegerIndexer /*
  11. */BooleanExpression /*
  12. */Initializer /*
  13.  
  14.  
  15. *///! novjass
  16.  
  17. |=========|
  18. | Credits |
  19. |=========|
  20.  
  21. Author: AGD
  22.  
  23. |-----|
  24. | API |
  25. |-----|
  26.  
  27. struct Period/*
  28.  
  29. */static constant integer TIMEOUT_PRECISION/*
  30. - The number of decimal digits that the system will consider to see if the timeouts are identical.
  31. - The default value is 5, you can change the value below (The recommended value is betweed 3 to 5).
  32. - A higher value supports higher timeout accuracy while a lower value results to higher timeout
  33. merge chance and results to a better increase in performance in tight executions so set the value
  34. at your own discretion.
  35.  
  36. */readonly real timeout /* The periodic timeout
  37. */readonly real elapsed /* The elapsed time starting from the last expiration
  38. */readonly real remaining /* The remaining time before the next expiration
  39.  
  40. */static method operator [] takes real timeout returns Period/*
  41. - Creates a new Period of a certain timeout
  42.  
  43. */method destroy takes nothing returns nothing/*
  44. - Destroys a Period instance
  45.  
  46. */method operator [] takes BoolExpr expr returns PeriodicEvent/*
  47. - Retreives the PeriodicEvent instance based on the BoolExpr parameter
  48.  
  49. */method register takes BoolExpr expr returns PeriodicEvent/*
  50. - Creates a new PeriodicEvent instance based on the BoolExpr parameter
  51.  
  52. */method unregister takes BoolExpr expr returns nothing/*
  53. - Unregisters the PeriodicEvent instance of the BoolExpr parameter from this Period
  54.  
  55. */method registerTrigger takes Trigger t returns PeriodicEvent/*
  56. - Registers a Trigger to this Period instance
  57.  
  58. */method unregisterTrigger takes Trigger t returns nothing/*
  59. - Unregisters a Trigger from this Period instance
  60.  
  61.  
  62. */struct PeriodicEvent/*
  63.  
  64. */readonly Period period /* The Period in which this instance is registered
  65.  
  66. */method addExecutionDuration takes real duration returns nothing/*
  67. - Adds an execution duration limit to a PeriodicEvent instance
  68.  
  69. */method addExecutionLimit takes integer limit returns nothing/*
  70. - Adds an execution count limit to a PeriodicEvent instance
  71.  
  72. */method resetExecutionHandler takes nothing returns nothing/*
  73. - Removes all execution limits for a PeriodicEvent instance
  74.  
  75. *///! endnovjass
  76.  
  77. /*===================================================================================*/
  78.  
  79. private keyword EventCode
  80.  
  81. struct Period extends array
  82.  
  83. static constant integer TIMEOUT_PRECISION = 5
  84.  
  85. readonly real timeout
  86. private Timer timer
  87. private Trigger trigger
  88. private integer count
  89. private boolean allocated
  90. private static integer multiplier
  91.  
  92. implement IntegerIndexer
  93.  
  94. method operator remaining takes nothing returns real
  95. return .timer.remaining
  96. endmethod
  97.  
  98. method operator elapsed takes nothing returns real
  99. return .timer.elapsed
  100. endmethod
  101.  
  102. private static method onExpire takes nothing returns nothing
  103. call Trigger(Timer.expired.data).evaluate()
  104. endmethod
  105.  
  106. private method add takes BoolExpr expr returns PeriodicEvent
  107. local integer count = .count + 1
  108. set .count = count
  109. if count == 1 then
  110. call .timer.start(.timeout, true, function thistype.onExpire)
  111. endif
  112. if expr != 0 then
  113. return EventCode(this).insert(expr)
  114. endif
  115. return 0
  116. endmethod
  117.  
  118. private method remove takes BoolExpr expr returns nothing
  119. local integer count = .count - 1
  120. set .count = count
  121. if count == 0 then
  122. call .timer.pause()
  123. endif
  124. if expr != 0 then
  125. call EventCode(this).remove(expr)
  126. endif
  127. endmethod
  128.  
  129. static method operator [] takes real timeout returns thistype
  130. local integer timeoutInt = R2I(timeout*multiplier)
  131. local thistype this = getIntegerIndex(timeoutInt)
  132. if not .allocated then
  133. set .allocated = true
  134. set .trigger = Trigger.create()
  135. set .timer = Timer.newEx(.trigger)
  136. set .timeout = I2R(timeoutInt)/I2R(multiplier)
  137. endif
  138. return this
  139. endmethod
  140.  
  141. method operator [] takes BoolExpr expr returns PeriodicEvent
  142. return EventCode.table[this][expr]
  143. endmethod
  144.  
  145. method destroy takes nothing returns nothing
  146. if .allocated then
  147. set .allocated = false
  148. call removeIntegerIndex(getIntegerByIndex(this))
  149. call .trigger.destroy()
  150. call .timer.free()
  151. set .timeout = 0.00
  152. endif
  153. endmethod
  154.  
  155. method register takes BoolExpr expr returns PeriodicEvent
  156. call .trigger.addCondition(expr)
  157. return .add(expr)
  158. endmethod
  159.  
  160. method unregister takes BoolExpr expr returns nothing
  161. call .trigger.removeCondition(expr)
  162. call .remove(expr)
  163. endmethod
  164.  
  165. method registerTrigger takes Trigger t returns PeriodicEvent
  166. call .trigger.hook(t)
  167. return .add(t.condition.expression)
  168. endmethod
  169.  
  170. method unregisterTrigger takes Trigger t returns nothing
  171. call .trigger.unhook(t)
  172. call .remove(t.condition.expression)
  173. endmethod
  174.  
  175. private static method init takes nothing returns nothing
  176. set multiplier = R2I(Pow(10, TIMEOUT_PRECISION))
  177. endmethod
  178.  
  179. implement Initializer
  180.  
  181. endstruct
  182.  
  183. struct PeriodicEvent extends array
  184.  
  185. private Timer eventTimer
  186. private BoolExpr expr
  187.  
  188. method operator period takes nothing returns Period
  189. return EventCode(this).period
  190. endmethod
  191.  
  192. private static method unregisterCode takes nothing returns nothing
  193. local Timer expired = Timer.expired
  194. local thistype this = expired.data
  195. call .period.unregister(thistype(expired).expr)
  196. call expired.free()
  197. set .eventTimer = 0
  198. set thistype(expired).expr = 0
  199. endmethod
  200.  
  201. method addExecutionDuration takes real duration returns nothing
  202. local Period period = .period
  203. local real remaining = period.remaining
  204. if .eventTimer == 0 then
  205. set .eventTimer = Timer.newEx(this)
  206. endif
  207. if remaining == period.timeout then
  208. set remaining = 0.00
  209. endif
  210. call .eventTimer.start(remaining + duration, false, function thistype.unregisterCode)
  211. set thistype(.eventTimer).expr = EventCode(this).expr
  212. endmethod
  213.  
  214. method addExecutionLimit takes integer limit returns nothing
  215. local Period period = .period
  216. local real remaining = period.remaining
  217. local real timeout = period.timeout
  218. if .eventTimer == 0 then
  219. set .eventTimer = Timer.newEx(this)
  220. endif
  221. if remaining == timeout then
  222. set remaining = 0.00
  223. endif
  224. call .eventTimer.start(remaining + timeout*limit, false, function thistype.unregisterCode)
  225. set thistype(.eventTimer).expr = EventCode(this).expr
  226. endmethod
  227.  
  228. method resetExecutionHandler takes nothing returns nothing
  229. local Timer thisTimer = .eventTimer
  230. if thisTimer != 0 then
  231. call thisTimer.stop()
  232. call thisTimer.free()
  233. set .eventTimer = 0
  234. endif
  235. endmethod
  236.  
  237. endstruct
  238.  
  239. private struct EventCode extends array
  240.  
  241. static TableArray table
  242. Period period
  243. integer expr
  244.  
  245. implement Alloc
  246.  
  247. method insert takes BoolExpr expr returns PeriodicEvent
  248. local thistype instance
  249. debug if table[this].has(expr) then
  250. debug call debug("|CFFFF0000ERROR: Attempt to double-register BoolExpr[" + I2S(expr) + "] to Period[" + I2S(this) + "]")
  251. debug return table[this][expr]
  252. debug endif
  253. set instance = allocate()
  254. set instance.period = this
  255. set instance.expr = expr
  256. set table[this][expr] = instance
  257. return instance
  258. endmethod
  259.  
  260. method remove takes BoolExpr expr returns nothing
  261. local Table t = table[this]
  262. local thistype instance = t[expr]
  263. debug if not t.has(expr) then
  264. debug call debug("|CFFFF0000ERROR: Attempt to unregister an unregistered BoolExpr[" + I2S(expr) + "] from Period[" + I2S(this) + "]")
  265. debug return
  266. debug endif
  267. set instance.period = 0
  268. set instance.expr = 0
  269. call instance.deallocate()
  270. call t.remove(expr)
  271. endmethod
  272.  
  273. private static method init takes nothing returns nothing
  274. set table = TableArray[0x2000]
  275. endmethod
  276.  
  277. implement Initializer
  278.  
  279. endstruct
  280.  
  281.  
  282. endlibrary
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement