;; Builtin command & identifier calls are forced via ! and ~ respectively. Doing so bypasses script-equivalent lookups
;; same usage as $ctime, and the above $ctimems
alias ctimeex {
;; Use hashtables over global variables, can be quite a bit faster
;; No need to track $ctime
;; $ticks can overflow and roll back to zero, so check for overflow condition
!if (!$~isid || !$~hget(misc,milliseconds.ticks) == $~null || $~v1 > $~ticks) {
;; create the hashtable
!if (!$hget(misc)) hmake misc 1
;; Use inline arthmatic to avoid the overhead of calling $calc()
!var %ctime $~ctime + 1
;; Use $v1 to store $ticks instead of a tracking variable
!while ($~ctime < %ctime && $~ticks) { !noop }
;; store the ticks
!hadd misc milliseconds.ticks $~v1
;; if used as command, stop processing
!if (!$~isid) return
}
;; Inline arthmatic to, yet again, avoid the overhead of $calc()
;; Done immediately to increase accuracy of the return value
!var %ms $~ticks - $~hget(misc, milliseconds.ticks), %ms %ms % 1000
;; Return ctime with 3 digits of ticks in the decimal position; $calc is avoided
!return $~+($~ctime, ., $~base(%m,10,10,3))
}
;; Uses the same formatting as $asctime with the addition of the following format items:
; x: milliseconds as-is, so if the millisecond value is 95ms, x is replaced with "95"
; xxx: milliseconds padded to 3 places so if the millisecond value is 95ms, xxx is replaced with "095"
alias timestampex {
;; existence & overflow check
!if ($~hget(misc, milliseconds.ticks) == $null || $v1 > $ticks) { ctimeex }
;; Immediately calculate the offset
!var %ms $~ticks - $~hget(misc, milliseconds.ticks), %ms %ms % 1000
;; Using $replacexcs so only a single pass is made over the input AND the x/xxx replace matching is case-sensitive
;; Replace xxx with the padded milliseconds
;; Replace x with non-padded milliseconds value
!return $~replacexcs($~asctime($~ctime, $~timestampfmt), xxx, $~base(%ms, 10, 10, 3), x, %ms)
}
;; initialization events
on *:LOAD:ctimems
on *:START:ctimems