tdf#154285 Check upper bound of arguments in SbRtl_Minute function
[LibreOffice.git] / wizards / source / scriptforge / SF_Timer.xba
blob2b3286e041ab0fa1ff335fec6fadca5149fbe0de
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 =======================================================================================================================
8 Option Compatible
9 Option ClassModule
11 Option Explicit
13 &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;
14 &apos;&apos;&apos; SF_Timer
15 &apos;&apos;&apos; ========
16 &apos;&apos;&apos; Class for management of scripts execution performance
17 &apos;&apos;&apos; A Timer measures durations. It can be suspended, resumed, restarted
18 &apos;&apos;&apos; Duration properties are expressed in seconds with a precision of 3 decimal digits
19 &apos;&apos;&apos;
20 &apos;&apos;&apos; Service invocation example:
21 &apos;&apos;&apos; Dim myTimer As Variant
22 &apos;&apos;&apos; myTimer = CreateScriptService(&quot;Timer&quot;)
23 &apos;&apos;&apos; myTimer = CreateScriptService(&quot;Timer&quot;, True) &apos; =&gt; To start timer immediately
24 &apos;&apos;&apos;
25 &apos;&apos;&apos; Detailed user documentation:
26 &apos;&apos;&apos; https://help.libreoffice.org/latest/en-US/text/sbasic/shared/03/sf_timer.html?DbPAR=BASIC
27 &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;
29 REM ================================================================== EXCEPTIONS
31 REM ============================================================= PRIVATE MEMBERS
33 Private [Me] As Object
34 Private [_Parent] As Object
35 Private ObjectType As String &apos; Must be &quot;TIMER&quot;
36 Private ServiceName As String
37 Private _TimerStatus As Integer &apos; inactive, started, suspended or stopped
38 Private _StartTime As Double &apos; Moment when timer started, restarted
39 Private _EndTime As Double &apos; Moment when timer stopped
40 Private _SuspendTime As Double &apos; Moment when timer suspended
41 Private _SuspendDuration As Double &apos; Duration of suspended status as a difference of times
43 REM ============================================================ MODULE CONSTANTS
45 Private Const STATUSINACTIVE = 0
46 Private Const STATUSSTARTED = 1
47 Private Const STATUSSUSPENDED = 2
48 Private Const STATUSSTOPPED = 3
50 Private Const DSECOND As Double = 1 / (24 * 60 * 60) &apos; Duration of 1 second as compared to 1.0 = 1 day
52 REM ===================================================== CONSTRUCTOR/DESTRUCTOR
54 REM -----------------------------------------------------------------------------
55 Private Sub Class_Initialize()
56 Set [Me] = Nothing
57 Set [_Parent] = Nothing
58 ObjectType = &quot;TIMER&quot;
59 ServiceName = &quot;ScriptForge.Timer&quot;
60 _TimerStatus = STATUSINACTIVE
61 _StartTime = 0
62 _EndTime = 0
63 _SuspendTime = 0
64 _SuspendDuration = 0
65 End Sub &apos; ScriptForge.SF_Timer Constructor
67 REM -----------------------------------------------------------------------------
68 Private Sub Class_Terminate()
69 Call Class_Initialize()
70 End Sub &apos; ScriptForge.SF_Timer Destructor
72 REM -----------------------------------------------------------------------------
73 Public Function Dispose() As Variant
74 Call Class_Terminate()
75 Set Dispose = Nothing
76 End Function &apos; ScriptForge.SF_Timer Explicit destructor
78 REM ================================================================== PROPERTIES
80 REM -----------------------------------------------------------------------------
81 Public Function Duration() As Double
82 &apos;&apos;&apos; Returns the actual (out of suspensions) time elapsed since start or between start and stop
83 &apos;&apos;&apos; Args:
84 &apos;&apos;&apos; Returns:
85 &apos;&apos;&apos; A Double expressing the duration in seconds
86 &apos;&apos;&apos; Example:
87 &apos;&apos;&apos; myTimer.Duration returns 1.234 (1 sec, 234 ms)
89 Duration = _PropertyGet(&quot;Duration&quot;)
91 End Function &apos; ScriptForge.SF_Timer.Duration
93 REM -----------------------------------------------------------------------------
94 Property Get IsStarted() As Boolean
95 &apos;&apos;&apos; Returns True if timer is started or suspended
96 &apos;&apos;&apos; Example:
97 &apos;&apos;&apos; myTimer.IsStarted
99 IsStarted = _PropertyGet(&quot;IsStarted&quot;)
101 End Property &apos; ScriptForge.SF_Timer.IsStarted
103 REM -----------------------------------------------------------------------------
104 Property Get IsSuspended() As Boolean
105 &apos;&apos;&apos; Returns True if timer is started and suspended
106 &apos;&apos;&apos; Example:
107 &apos;&apos;&apos; myTimer.IsSuspended
109 IsSuspended = _PropertyGet(&quot;IsSuspended&quot;)
111 End Property &apos; ScriptForge.SF_Timer.IsSuspended
113 REM -----------------------------------------------------------------------------
114 Public Function SuspendDuration() As Double
115 &apos;&apos;&apos; Returns the actual time elapsed while suspended since start or between start and stop
116 &apos;&apos;&apos; Args:
117 &apos;&apos;&apos; Returns:
118 &apos;&apos;&apos; A Double expressing the duration in seconds
119 &apos;&apos;&apos; Example:
120 &apos;&apos;&apos; myTimer.SuspendDuration returns 1.234 (1 sec, 234 ms)
122 SuspendDuration = _PropertyGet(&quot;SuspendDuration&quot;)
124 End Function &apos; ScriptForge.SF_Timer.SuspendDuration
126 REM -----------------------------------------------------------------------------
127 Public Function TotalDuration() As Double
128 &apos;&apos;&apos; Returns the actual time elapsed (including suspensions) since start or between start and stop
129 &apos;&apos;&apos; Args:
130 &apos;&apos;&apos; Returns:
131 &apos;&apos;&apos; A Double expressing the duration in seconds
132 &apos;&apos;&apos; Example:
133 &apos;&apos;&apos; myTimer.TotalDuration returns 1.234 (1 sec, 234 ms)
135 TotalDuration = _PropertyGet(&quot;TotalDuration&quot;)
137 End Function &apos; ScriptForge.SF_Timer.TotalDuration
139 REM ===================================================================== METHODS
141 REM -----------------------------------------------------------------------------
142 Public Function Continue() As Boolean
143 &apos;&apos;&apos; Halt suspension of a running timer
144 &apos;&apos;&apos; Args:
145 &apos;&apos;&apos; Returns:
146 &apos;&apos;&apos; True if successful, False if the timer is not suspended
147 &apos;&apos;&apos; Examples:
148 &apos;&apos;&apos; myTimer.Continue()
150 Const cstThisSub = &quot;Timer.Continue&quot;
151 Const cstSubArgs = &quot;&quot;
153 Check:
154 Continue = False
155 SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
157 Try:
158 If _TimerStatus = STATUSSUSPENDED Then
159 _TimerStatus = STATUSSTARTED
160 _SuspendDuration = _SuspendDuration + _Now() - _SuspendTime
161 _SuspendTime = 0
162 Continue = True
163 End If
165 Finally:
166 SF_Utils._ExitFunction(cstThisSub)
167 Exit Function
168 End Function &apos; ScriptForge.SF_Timer.Continue
170 REM -----------------------------------------------------------------------------
171 Public Function GetProperty(Optional ByVal PropertyName As Variant) As Variant
172 &apos;&apos;&apos; Return the actual value of the given property
173 &apos;&apos;&apos; Args:
174 &apos;&apos;&apos; PropertyName: the name of the property as a string
175 &apos;&apos;&apos; Returns:
176 &apos;&apos;&apos; The actual value of the property
177 &apos;&apos;&apos; Exceptions
178 &apos;&apos;&apos; ARGUMENTERROR The property does not exist
179 &apos;&apos;&apos; Examples:
180 &apos;&apos;&apos; myTimer.GetProperty(&quot;Duration&quot;)
182 Const cstThisSub = &quot;Timer.GetProperty&quot;
183 Const cstSubArgs = &quot;PropertyName&quot;
185 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
186 GetProperty = Null
188 Check:
189 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
190 If Not SF_Utils._Validate(PropertyName, &quot;PropertyName&quot;, V_STRING, Properties()) Then GoTo Catch
191 End If
193 Try:
194 GetProperty = _PropertyGet(PropertyName)
196 Finally:
197 SF_Utils._ExitFunction(cstThisSub)
198 Exit Function
199 Catch:
200 GoTo Finally
201 End Function &apos; ScriptForge.SF_Timer.Properties
203 REM -----------------------------------------------------------------------------
204 Public Function Methods() As Variant
205 &apos;&apos;&apos; Return the list or methods of the Timer class as an array
207 Methods = Array( _
208 &quot;Continue&quot; _
209 , &quot;Restart&quot; _
210 , &quot;Start&quot; _
211 , &quot;Suspend&quot; _
212 , &quot;Terminate&quot; _
215 End Function &apos; ScriptForge.SF_Timer.Methods
217 REM -----------------------------------------------------------------------------
218 Public Function Properties() As Variant
219 &apos;&apos;&apos; Return the list or properties of the Timer class as an array
221 Properties = Array( _
222 &quot;Duration&quot; _
223 , &quot;IsStarted&quot; _
224 , &quot;IsSuspended&quot; _
225 , &quot;SuspendDuration&quot; _
226 , &quot;TotalDuration&quot; _
229 End Function &apos; ScriptForge.SF_Timer.Properties
231 REM -----------------------------------------------------------------------------
232 Public Function Restart() As Boolean
233 &apos;&apos;&apos; Terminate the timer and restart 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 inactive
237 &apos;&apos;&apos; Examples:
238 &apos;&apos;&apos; myTimer.Restart()
240 Const cstThisSub = &quot;Timer.Restart&quot;
241 Const cstSubArgs = &quot;&quot;
243 Check:
244 Restart = False
245 SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
247 Try:
248 If _TimerStatus &lt;&gt; STATUSINACTIVE Then
249 If _TimerStatus &lt;&gt; STATUSSTOPPED Then Terminate()
250 Start()
251 Restart = True
252 End If
254 Finally:
255 SF_Utils._ExitFunction(cstThisSub)
256 Exit Function
257 End Function &apos; ScriptForge.SF_Timer.Restart
259 REM -----------------------------------------------------------------------------
260 Public Function SetProperty(Optional ByVal PropertyName As Variant _
261 , Optional ByRef Value As Variant _
262 ) As Boolean
263 &apos;&apos;&apos; Set a new value to the given property
264 &apos;&apos;&apos; Args:
265 &apos;&apos;&apos; PropertyName: the name of the property as a string
266 &apos;&apos;&apos; Value: its new value
267 &apos;&apos;&apos; Exceptions
268 &apos;&apos;&apos; ARGUMENTERROR The property does not exist
270 Const cstThisSub = &quot;Timer.SetProperty&quot;
271 Const cstSubArgs = &quot;PropertyName, Value&quot;
273 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
274 SetProperty = False
276 Check:
277 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
278 If Not SF_Utils._Validate(PropertyName, &quot;PropertyName&quot;, V_STRING, Properties()) Then GoTo Catch
279 End If
281 Try:
282 Select Case UCase(PropertyName)
283 Case Else
284 End Select
286 Finally:
287 SF_Utils._ExitFunction(cstThisSub)
288 Exit Function
289 Catch:
290 GoTo Finally
291 End Function &apos; ScriptForge.SF_Timer.SetProperty
293 REM -----------------------------------------------------------------------------
294 Public Function Start() As Boolean
295 &apos;&apos;&apos; Start a new clean timer
296 &apos;&apos;&apos; Args:
297 &apos;&apos;&apos; Returns:
298 &apos;&apos;&apos; True if successful, False if the timer is already started
299 &apos;&apos;&apos; Examples:
300 &apos;&apos;&apos; myTimer.Start()
302 Const cstThisSub = &quot;Timer.Start&quot;
303 Const cstSubArgs = &quot;&quot;
305 Check:
306 Start = False
307 SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
309 Try:
310 If _TimerStatus = STATUSINACTIVE Or _TimerStatus = STATUSSTOPPED Then
311 _TimerStatus = STATUSSTARTED
312 _StartTime = _Now()
313 _EndTime = 0
314 _SuspendTime = 0
315 _SuspendDuration = 0
316 Start = True
317 End If
319 Finally:
320 SF_Utils._ExitFunction(cstThisSub)
321 Exit Function
322 End Function &apos; ScriptForge.SF_Timer.Start
324 REM -----------------------------------------------------------------------------
325 Public Function Suspend() As Boolean
326 &apos;&apos;&apos; Suspend a running timer
327 &apos;&apos;&apos; Args:
328 &apos;&apos;&apos; Returns:
329 &apos;&apos;&apos; True if successful, False if the timer is not started or already suspended
330 &apos;&apos;&apos; Examples:
331 &apos;&apos;&apos; myTimer.Suspend()
333 Const cstThisSub = &quot;Timer.Suspend&quot;
334 Const cstSubArgs = &quot;&quot;
336 Check:
337 Suspend = False
338 SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
340 Try:
341 If _TimerStatus = STATUSSTARTED Then
342 _TimerStatus = STATUSSUSPENDED
343 _SuspendTime = _Now()
344 Suspend = True
345 End If
347 Finally:
348 SF_Utils._ExitFunction(cstThisSub)
349 Exit Function
350 End Function &apos; ScriptForge.SF_Timer.Suspend
352 REM -----------------------------------------------------------------------------
353 Public Function Terminate() As Boolean
354 &apos;&apos;&apos; Terminate a running timer
355 &apos;&apos;&apos; Args:
356 &apos;&apos;&apos; Returns:
357 &apos;&apos;&apos; True if successful, False if the timer is neither started nor suspended
358 &apos;&apos;&apos; Examples:
359 &apos;&apos;&apos; myTimer.Terminate()
361 Const cstThisSub = &quot;Timer.Terminate&quot;
362 Const cstSubArgs = &quot;&quot;
364 Check:
365 Terminate = False
366 SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
368 Try:
369 If _TimerStatus = STATUSSTARTED Or _TimerStatus = STATUSSUSPENDED Then
370 If _TimerSTatus = STATUSSUSPENDED Then Continue()
371 _TimerStatus = STATUSSTOPPED
372 _EndTime = _Now()
373 Terminate = True
374 End If
376 Finally:
377 SF_Utils._ExitFunction(cstThisSub)
378 Exit Function
379 End Function &apos; ScriptForge.SF_Timer.Terminate
381 REM =========================================================== PRIVATE FUNCTIONS
383 REM -----------------------------------------------------------------------------
384 Private Function _Now() As Double
385 &apos;&apos;&apos; Returns the current date and time
386 &apos;&apos;&apos; Uses the Calc NOW() function to get a higher precision than the usual Basic Now() function
387 &apos;&apos;&apos; Args:
388 &apos;&apos;&apos; Returns:
389 &apos;&apos;&apos; The actual time as a number
390 &apos;&apos;&apos; The integer part represents the date, the decimal part represents the time
392 _Now = SF_Session.ExecuteCalcFunction(&quot;NOW&quot;)
394 End Function &apos; ScriptForge.SF_Timer._Now
396 REM -----------------------------------------------------------------------------
397 Private Function _PropertyGet(Optional ByVal psProperty As String)
398 &apos;&apos;&apos; Return the named property
399 &apos;&apos;&apos; Args:
400 &apos;&apos;&apos; psProperty: the name of the property
402 Dim dDuration As Double &apos; Computed duration
403 Dim cstThisSub As String
404 Dim cstSubArgs As String
406 cstThisSub = &quot;Timer.get&quot; &amp; psProperty
407 cstSubArgs = &quot;&quot;
408 SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
410 Select Case UCase(psProperty)
411 Case UCase(&quot;Duration&quot;)
412 Select Case _TimerStatus
413 Case STATUSINACTIVE : dDuration = 0.0
414 Case STATUSSTARTED
415 dDuration = _Now() - _StartTime - _SuspendDuration
416 Case STATUSSUSPENDED
417 dDuration = _SuspendTime - _StartTime - _SuspendDuration
418 Case STATUSSTOPPED
419 dDuration = _EndTime - _StartTime - _SuspendDuration
420 End Select
421 _PropertyGet = Fix(dDuration * 1000 / DSECOND) / 1000
422 Case UCase(&quot;IsStarted&quot;)
423 _PropertyGet = CBool( _TimerStatus = STATUSSTARTED Or _TimerStatus = STATUSSUSPENDED )
424 Case UCase(&quot;IsSuspended&quot;)
425 _PropertyGet = CBool( _TimerStatus = STATUSSUSPENDED )
426 Case UCase(&quot;SuspendDuration&quot;)
427 Select Case _TimerStatus
428 Case STATUSINACTIVE : dDuration = 0.0
429 Case STATUSSTARTED, STATUSSTOPPED
430 dDuration = _SuspendDuration
431 Case STATUSSUSPENDED
432 dDuration = _Now() - _SuspendTime + _SuspendDuration
433 End Select
434 _PropertyGet = Fix(dDuration * 1000 / DSECOND) / 1000
435 Case UCase(&quot;TotalDuration&quot;)
436 Select Case _TimerStatus
437 Case STATUSINACTIVE : dDuration = 0.0
438 Case STATUSSTARTED, STATUSSUSPENDED
439 dDuration = _Now() - _StartTime
440 Case STATUSSTOPPED
441 dDuration = _EndTime - _StartTime
442 End Select
443 _PropertyGet = Fix(dDuration * 1000 / DSECOND) / 1000
444 End Select
446 Finally:
447 SF_Utils._ExitFunction(cstThisSub)
448 Exit Function
449 End Function &apos; ScriptForge.SF_Timer._PropertyGet
451 REM -----------------------------------------------------------------------------
452 Private Function _Repr() As String
453 &apos;&apos;&apos; Convert the Timer instance to a readable string, typically for debugging purposes (DebugPrint ...)
454 &apos;&apos;&apos; Args:
455 &apos;&apos;&apos; Return:
456 &apos;&apos;&apos; &quot;[Timer] Duration:xxx.yyy
458 Const cstTimer = &quot;[Timer] Duration: &quot;
459 Const cstMaxLength = 50 &apos; Maximum length for items
461 _Repr = cstTimer &amp; Replace(SF_Utils._Repr(Duration), &quot;.&quot;, &quot;&quot;&quot;&quot;)
463 End Function &apos; ScriptForge.SF_Timer._Repr
465 REM ============================================ END OF SCRIPTFORGE.SF_TIMER
466 </script:module>