SF_Timer.xba 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE script:module PUBLIC "-//OpenOffice.org//DTD OfficeDocument 1.0//EN" "module.dtd">
  3. <script:module xmlns:script="http://openoffice.org/2000/script" script:name="SF_Timer" script:language="StarBasic" script:moduleType="normal">REM =======================================================================================================================
  4. REM === The ScriptForge library and its associated libraries are part of the LibreOffice project. ===
  5. REM === Full documentation is available on https://help.libreoffice.org/ ===
  6. REM =======================================================================================================================
  7. Option Compatible
  8. Option ClassModule
  9. Option Explicit
  10. &apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;
  11. &apos;&apos;&apos; SF_Timer
  12. &apos;&apos;&apos; ========
  13. &apos;&apos;&apos; Class for management of scripts execution performance
  14. &apos;&apos;&apos; A Timer measures durations. It can be suspended, resumed, restarted
  15. &apos;&apos;&apos; Duration properties are expressed in seconds with a precision of 3 decimal digits
  16. &apos;&apos;&apos;
  17. &apos;&apos;&apos; Service invocation example:
  18. &apos;&apos;&apos; Dim myTimer As Variant
  19. &apos;&apos;&apos; myTimer = CreateScriptService(&quot;Timer&quot;)
  20. &apos;&apos;&apos; myTimer = CreateScriptService(&quot;Timer&quot;, True) &apos; =&gt; To start timer immediately
  21. &apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;
  22. REM ================================================================== EXCEPTIONS
  23. REM ============================================================= PRIVATE MEMBERS
  24. Private [Me] As Object
  25. Private [_Parent] As Object
  26. Private ObjectType As String &apos; Must be &quot;TIMER&quot;
  27. Private ServiceName As String
  28. Private _TimerStatus As Integer &apos; inactive, started, suspended or stopped
  29. Private _StartTime As Double &apos; Moment when timer started, restarted
  30. Private _EndTime As Double &apos; Moment when timer stopped
  31. Private _SuspendTime As Double &apos; Moment when timer suspended
  32. Private _SuspendDuration As Double &apos; Duration of suspended status as a difference of times
  33. REM ============================================================ MODULE CONSTANTS
  34. Private Const STATUSINACTIVE = 0
  35. Private Const STATUSSTARTED = 1
  36. Private Const STATUSSUSPENDED = 2
  37. Private Const STATUSSTOPPED = 3
  38. Private Const DSECOND As Double = 1 / (24 * 60 * 60) &apos; Duration of 1 second as compared to 1.0 = 1 day
  39. REM ===================================================== CONSTRUCTOR/DESTRUCTOR
  40. REM -----------------------------------------------------------------------------
  41. Private Sub Class_Initialize()
  42. Set [Me] = Nothing
  43. Set [_Parent] = Nothing
  44. ObjectType = &quot;TIMER&quot;
  45. ServiceName = &quot;ScriptForge.Timer&quot;
  46. _TimerStatus = STATUSINACTIVE
  47. _StartTime = 0
  48. _EndTime = 0
  49. _SuspendTime = 0
  50. _SuspendDuration = 0
  51. End Sub &apos; ScriptForge.SF_Timer Constructor
  52. REM -----------------------------------------------------------------------------
  53. Private Sub Class_Terminate()
  54. Call Class_Initialize()
  55. End Sub &apos; ScriptForge.SF_Timer Destructor
  56. REM -----------------------------------------------------------------------------
  57. Public Function Dispose() As Variant
  58. Call Class_Terminate()
  59. Set Dispose = Nothing
  60. End Function &apos; ScriptForge.SF_Timer Explicit destructor
  61. REM ================================================================== PROPERTIES
  62. REM -----------------------------------------------------------------------------
  63. Public Function Duration() As Double
  64. &apos;&apos;&apos; Returns the actual (out of suspensions) time elapsed since start or between start and stop
  65. &apos;&apos;&apos; Args:
  66. &apos;&apos;&apos; Returns:
  67. &apos;&apos;&apos; A Double expressing the duration in seconds
  68. &apos;&apos;&apos; Example:
  69. &apos;&apos;&apos; myTimer.Duration returns 1.234 (1 sec, 234 ms)
  70. Duration = _PropertyGet(&quot;Duration&quot;)
  71. End Function &apos; ScriptForge.SF_Timer.Duration
  72. REM -----------------------------------------------------------------------------
  73. Property Get IsStarted() As Boolean
  74. &apos;&apos;&apos; Returns True if timer is started or suspended
  75. &apos;&apos;&apos; Example:
  76. &apos;&apos;&apos; myTimer.IsStarted
  77. IsStarted = _PropertyGet(&quot;IsStarted&quot;)
  78. End Property &apos; ScriptForge.SF_Timer.IsStarted
  79. REM -----------------------------------------------------------------------------
  80. Property Get IsSuspended() As Boolean
  81. &apos;&apos;&apos; Returns True if timer is started and suspended
  82. &apos;&apos;&apos; Example:
  83. &apos;&apos;&apos; myTimer.IsSuspended
  84. IsSuspended = _PropertyGet(&quot;IsSuspended&quot;)
  85. End Property &apos; ScriptForge.SF_Timer.IsSuspended
  86. REM -----------------------------------------------------------------------------
  87. Public Function SuspendDuration() As Double
  88. &apos;&apos;&apos; Returns the actual time elapsed while suspended since start or between start and stop
  89. &apos;&apos;&apos; Args:
  90. &apos;&apos;&apos; Returns:
  91. &apos;&apos;&apos; A Double expressing the duration in seconds
  92. &apos;&apos;&apos; Example:
  93. &apos;&apos;&apos; myTimer.SuspendDuration returns 1.234 (1 sec, 234 ms)
  94. SuspendDuration = _PropertyGet(&quot;SuspendDuration&quot;)
  95. End Function &apos; ScriptForge.SF_Timer.SuspendDuration
  96. REM -----------------------------------------------------------------------------
  97. Public Function TotalDuration() As Double
  98. &apos;&apos;&apos; Returns the actual time elapsed (including suspensions) since start or between start and stop
  99. &apos;&apos;&apos; Args:
  100. &apos;&apos;&apos; Returns:
  101. &apos;&apos;&apos; A Double expressing the duration in seconds
  102. &apos;&apos;&apos; Example:
  103. &apos;&apos;&apos; myTimer.TotalDuration returns 1.234 (1 sec, 234 ms)
  104. TotalDuration = _PropertyGet(&quot;TotalDuration&quot;)
  105. End Function &apos; ScriptForge.SF_Timer.TotalDuration
  106. REM ===================================================================== METHODS
  107. REM -----------------------------------------------------------------------------
  108. Public Function Continue() As Boolean
  109. &apos;&apos;&apos; Halt suspension of a running timer
  110. &apos;&apos;&apos; Args:
  111. &apos;&apos;&apos; Returns:
  112. &apos;&apos;&apos; True if successful, False if the timer is not suspended
  113. &apos;&apos;&apos; Examples:
  114. &apos;&apos;&apos; myTimer.Continue()
  115. Const cstThisSub = &quot;Timer.Continue&quot;
  116. Const cstSubArgs = &quot;&quot;
  117. Check:
  118. Continue = False
  119. SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
  120. Try:
  121. If _TimerStatus = STATUSSUSPENDED Then
  122. _TimerStatus = STATUSSTARTED
  123. _SuspendDuration = _SuspendDuration + _Now() - _SuspendTime
  124. _SuspendTime = 0
  125. Continue = True
  126. End If
  127. Finally:
  128. SF_Utils._ExitFunction(cstThisSub)
  129. Exit Function
  130. End Function &apos; ScriptForge.SF_Timer.Continue
  131. REM -----------------------------------------------------------------------------
  132. Public Function GetProperty(Optional ByVal PropertyName As Variant) As Variant
  133. &apos;&apos;&apos; Return the actual value of the given property
  134. &apos;&apos;&apos; Args:
  135. &apos;&apos;&apos; PropertyName: the name of the property as a string
  136. &apos;&apos;&apos; Returns:
  137. &apos;&apos;&apos; The actual value of the property
  138. &apos;&apos;&apos; Exceptions
  139. &apos;&apos;&apos; ARGUMENTERROR The property does not exist
  140. &apos;&apos;&apos; Examples:
  141. &apos;&apos;&apos; myTimer.GetProperty(&quot;Duration&quot;)
  142. Const cstThisSub = &quot;Timer.GetProperty&quot;
  143. Const cstSubArgs = &quot;PropertyName&quot;
  144. If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
  145. GetProperty = Null
  146. Check:
  147. If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
  148. If Not SF_Utils._Validate(PropertyName, &quot;PropertyName&quot;, V_STRING, Properties()) Then GoTo Catch
  149. End If
  150. Try:
  151. GetProperty = _PropertyGet(PropertyName)
  152. Finally:
  153. SF_Utils._ExitFunction(cstThisSub)
  154. Exit Function
  155. Catch:
  156. GoTo Finally
  157. End Function &apos; ScriptForge.SF_Timer.Properties
  158. REM -----------------------------------------------------------------------------
  159. Public Function Methods() As Variant
  160. &apos;&apos;&apos; Return the list or methods of the Timer class as an array
  161. Methods = Array( _
  162. &quot;Continue&quot; _
  163. , &quot;Restart&quot; _
  164. , &quot;Start&quot; _
  165. , &quot;Suspend&quot; _
  166. , &quot;Terminate&quot; _
  167. )
  168. End Function &apos; ScriptForge.SF_Timer.Methods
  169. REM -----------------------------------------------------------------------------
  170. Public Function Properties() As Variant
  171. &apos;&apos;&apos; Return the list or properties of the Timer class as an array
  172. Properties = Array( _
  173. &quot;Duration&quot; _
  174. , &quot;IsStarted&quot; _
  175. , &quot;IsSuspended&quot; _
  176. , &quot;SuspendDuration&quot; _
  177. , &quot;TotalDuration&quot; _
  178. )
  179. End Function &apos; ScriptForge.SF_Timer.Properties
  180. REM -----------------------------------------------------------------------------
  181. Public Function Restart() As Boolean
  182. &apos;&apos;&apos; Terminate the timer and restart a new clean timer
  183. &apos;&apos;&apos; Args:
  184. &apos;&apos;&apos; Returns:
  185. &apos;&apos;&apos; True if successful, False if the timer is inactive
  186. &apos;&apos;&apos; Examples:
  187. &apos;&apos;&apos; myTimer.Restart()
  188. Const cstThisSub = &quot;Timer.Restart&quot;
  189. Const cstSubArgs = &quot;&quot;
  190. Check:
  191. Restart = False
  192. SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
  193. Try:
  194. If _TimerStatus &lt;&gt; STATUSINACTIVE Then
  195. If _TimerStatus &lt;&gt; STATUSSTOPPED Then Terminate()
  196. Start()
  197. Restart = True
  198. End If
  199. Finally:
  200. SF_Utils._ExitFunction(cstThisSub)
  201. Exit Function
  202. End Function &apos; ScriptForge.SF_Timer.Restart
  203. REM -----------------------------------------------------------------------------
  204. Public Function SetProperty(Optional ByVal PropertyName As Variant _
  205. , Optional ByRef Value As Variant _
  206. ) As Boolean
  207. &apos;&apos;&apos; Set a new value to the given property
  208. &apos;&apos;&apos; Args:
  209. &apos;&apos;&apos; PropertyName: the name of the property as a string
  210. &apos;&apos;&apos; Value: its new value
  211. &apos;&apos;&apos; Exceptions
  212. &apos;&apos;&apos; ARGUMENTERROR The property does not exist
  213. Const cstThisSub = &quot;Timer.SetProperty&quot;
  214. Const cstSubArgs = &quot;PropertyName, Value&quot;
  215. If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
  216. SetProperty = False
  217. Check:
  218. If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
  219. If Not SF_Utils._Validate(PropertyName, &quot;PropertyName&quot;, V_STRING, Properties()) Then GoTo Catch
  220. End If
  221. Try:
  222. Select Case UCase(PropertyName)
  223. Case Else
  224. End Select
  225. Finally:
  226. SF_Utils._ExitFunction(cstThisSub)
  227. Exit Function
  228. Catch:
  229. GoTo Finally
  230. End Function &apos; ScriptForge.SF_Timer.SetProperty
  231. REM -----------------------------------------------------------------------------
  232. Public Function Start() As Boolean
  233. &apos;&apos;&apos; Start a new clean timer
  234. &apos;&apos;&apos; Args:
  235. &apos;&apos;&apos; Returns:
  236. &apos;&apos;&apos; True if successful, False if the timer is already started
  237. &apos;&apos;&apos; Examples:
  238. &apos;&apos;&apos; myTimer.Start()
  239. Const cstThisSub = &quot;Timer.Start&quot;
  240. Const cstSubArgs = &quot;&quot;
  241. Check:
  242. Start = False
  243. SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
  244. Try:
  245. If _TimerStatus = STATUSINACTIVE Or _TimerStatus = STATUSSTOPPED Then
  246. _TimerStatus = STATUSSTARTED
  247. _StartTime = _Now()
  248. _EndTime = 0
  249. _SuspendTime = 0
  250. _SuspendDuration = 0
  251. Start = True
  252. End If
  253. Finally:
  254. SF_Utils._ExitFunction(cstThisSub)
  255. Exit Function
  256. End Function &apos; ScriptForge.SF_Timer.Start
  257. REM -----------------------------------------------------------------------------
  258. Public Function Suspend() As Boolean
  259. &apos;&apos;&apos; Suspend a running timer
  260. &apos;&apos;&apos; Args:
  261. &apos;&apos;&apos; Returns:
  262. &apos;&apos;&apos; True if successful, False if the timer is not started or already suspended
  263. &apos;&apos;&apos; Examples:
  264. &apos;&apos;&apos; myTimer.Suspend()
  265. Const cstThisSub = &quot;Timer.Suspend&quot;
  266. Const cstSubArgs = &quot;&quot;
  267. Check:
  268. Suspend = False
  269. SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
  270. Try:
  271. If _TimerStatus = STATUSSTARTED Then
  272. _TimerStatus = STATUSSUSPENDED
  273. _SuspendTime = _Now()
  274. Suspend = True
  275. End If
  276. Finally:
  277. SF_Utils._ExitFunction(cstThisSub)
  278. Exit Function
  279. End Function &apos; ScriptForge.SF_Timer.Suspend
  280. REM -----------------------------------------------------------------------------
  281. Public Function Terminate() As Boolean
  282. &apos;&apos;&apos; Terminate a running timer
  283. &apos;&apos;&apos; Args:
  284. &apos;&apos;&apos; Returns:
  285. &apos;&apos;&apos; True if successful, False if the timer is neither started nor suspended
  286. &apos;&apos;&apos; Examples:
  287. &apos;&apos;&apos; myTimer.Terminate()
  288. Const cstThisSub = &quot;Timer.Terminate&quot;
  289. Const cstSubArgs = &quot;&quot;
  290. Check:
  291. Terminate = False
  292. SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
  293. Try:
  294. If _TimerStatus = STATUSSTARTED Or _TimerStatus = STATUSSUSPENDED Then
  295. If _TimerSTatus = STATUSSUSPENDED Then Continue()
  296. _TimerStatus = STATUSSTOPPED
  297. _EndTime = _Now()
  298. Terminate = True
  299. End If
  300. Finally:
  301. SF_Utils._ExitFunction(cstThisSub)
  302. Exit Function
  303. End Function &apos; ScriptForge.SF_Timer.Terminate
  304. REM =========================================================== PRIVATE FUNCTIONS
  305. REM -----------------------------------------------------------------------------
  306. Private Function _Now() As Double
  307. &apos;&apos;&apos; Returns the current date and time
  308. &apos;&apos;&apos; Uses the Calc NOW() function to get a higher precision than the usual Basic Now() function
  309. &apos;&apos;&apos; Args:
  310. &apos;&apos;&apos; Returns:
  311. &apos;&apos;&apos; The actual time as a number
  312. &apos;&apos;&apos; The integer part represents the date, the decimal part represents the time
  313. _Now = SF_Session.ExecuteCalcFunction(&quot;NOW&quot;)
  314. End Function &apos; ScriptForge.SF_Timer._Now
  315. REM -----------------------------------------------------------------------------
  316. Private Function _PropertyGet(Optional ByVal psProperty As String)
  317. &apos;&apos;&apos; Return the named property
  318. &apos;&apos;&apos; Args:
  319. &apos;&apos;&apos; psProperty: the name of the property
  320. Dim dDuration As Double &apos; Computed duration
  321. Dim cstThisSub As String
  322. Dim cstSubArgs As String
  323. cstThisSub = &quot;Timer.get&quot; &amp; psProperty
  324. cstSubArgs = &quot;&quot;
  325. SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
  326. Select Case UCase(psProperty)
  327. Case UCase(&quot;Duration&quot;)
  328. Select Case _TimerStatus
  329. Case STATUSINACTIVE : dDuration = 0.0
  330. Case STATUSSTARTED
  331. dDuration = _Now() - _StartTime - _SuspendDuration
  332. Case STATUSSUSPENDED
  333. dDuration = _SuspendTime - _StartTime - _SuspendDuration
  334. Case STATUSSTOPPED
  335. dDuration = _EndTime - _StartTime - _SuspendDuration
  336. End Select
  337. _PropertyGet = Fix(dDuration * 1000 / DSECOND) / 1000
  338. Case UCase(&quot;IsStarted&quot;)
  339. _PropertyGet = ( _TimerStatus = STATUSSTARTED Or _TimerStatus = STATUSSUSPENDED )
  340. Case UCase(&quot;IsSuspended&quot;)
  341. _PropertyGet = ( _TimerStatus = STATUSSUSPENDED )
  342. Case UCase(&quot;SuspendDuration&quot;)
  343. Select Case _TimerStatus
  344. Case STATUSINACTIVE : dDuration = 0.0
  345. Case STATUSSTARTED, STATUSSTOPPED
  346. dDuration = _SuspendDuration
  347. Case STATUSSUSPENDED
  348. dDuration = _Now() - _SuspendTime + _SuspendDuration
  349. End Select
  350. _PropertyGet = Fix(dDuration * 1000 / DSECOND) / 1000
  351. Case UCase(&quot;TotalDuration&quot;)
  352. Select Case _TimerStatus
  353. Case STATUSINACTIVE : dDuration = 0.0
  354. Case STATUSSTARTED, STATUSSUSPENDED
  355. dDuration = _Now() - _StartTime
  356. Case STATUSSTOPPED
  357. dDuration = _EndTime - _StartTime
  358. End Select
  359. _PropertyGet = Fix(dDuration * 1000 / DSECOND) / 1000
  360. End Select
  361. Finally:
  362. SF_Utils._ExitFunction(cstThisSub)
  363. Exit Function
  364. End Function &apos; ScriptForge.SF_Timer._PropertyGet
  365. REM -----------------------------------------------------------------------------
  366. Private Function _Repr() As String
  367. &apos;&apos;&apos; Convert the Timer instance to a readable string, typically for debugging purposes (DebugPrint ...)
  368. &apos;&apos;&apos; Args:
  369. &apos;&apos;&apos; Return:
  370. &apos;&apos;&apos; &quot;[Timer] Duration:xxx.yyy
  371. Const cstTimer = &quot;[Timer] Duration: &quot;
  372. Const cstMaxLength = 50 &apos; Maximum length for items
  373. _Repr = cstTimer &amp; Replace(SF_Utils._Repr(Duration), &quot;.&quot;, &quot;&quot;&quot;&quot;)
  374. End Function &apos; ScriptForge.SF_Timer._Repr
  375. REM ============================================ END OF SCRIPTFORGE.SF_TIMER
  376. </script:module>