123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232 |
- SuperStrict
- Rem
- bbdoc: Events/Timers
- End Rem
- Module BRL.Timer
- ModuleInfo "Version: 1.04"
- ModuleInfo "Author: Simon Armstrong, Mark Sibly, Bruce A Henderson"
- ModuleInfo "License: zlib/libpng"
- ModuleInfo "Copyright: Blitz Research Ltd"
- ModuleInfo "History: 1.04"
- ModuleInfo "History: New factory-based timer implementation."
- ModuleInfo "History: 1.03"
- ModuleInfo "History: Update to use Byte Ptr instead of int."
- Import BRL.Event
- Import pub.stdc
- Rem
- History:
- Removed use of _cycle:TTimer field to keep timer's alive - didn't work with 'real' GC!
- Replaced with BBRETAIN/BBRELEASE in C code.
- Added check for OS timer creation failure
- Added check for Win32 timer firing after timeKillEvent
- Removed brl.standardio dependancy
- End Rem
- Type TTimer Abstract
- Method Ticks:Int() Abstract
-
- Method Stop() Abstract
-
- Method Fire() Abstract
- Method Wait:Int() Abstract
-
- Function Create:TTimer( hertz:Float,event:TEvent=Null ) Abstract
- End Type
- Rem
- bbdoc: Create a timer
- returns: A new timer object
- about:
- #CreateTimer creates a timer object that 'ticks' @hertz times per second.
- Each time the timer ticks, @event will be emitted using #EmitEvent.
- If @event is Null, an event with an @id equal to EVENT_TIMERTICK and
- @source equal to the timer object will be emitted instead.
- End Rem
- Function CreateTimer:TTimer( hertz:Float,event:TEvent=Null )
- If timer_factories Then
- Return timer_factories.Create(hertz, event)
- Else
- Throw "No Timer installed. Maybe Import BRL.TimerDefault ?"
- End If
- End Function
- Rem
- bbdoc: Get timer tick counter
- returns: The number of times @timer has ticked over
- End Rem
- Function TimerTicks:Int( timer:TTimer )
- Return timer.Ticks()
- End Function
- Rem
- bbdoc: Wait until a timer ticks
- returns: The number of ticks since the last call to #WaitTimer
- End Rem
- Function WaitTimer:Int( timer:TTimer )
- Return timer.Wait()
- End Function
- Rem
- bbdoc: Stop a timer
- about:Once stopped, a timer can no longer be used.
- End Rem
- Function StopTimer( timer:TTimer )
- timer.Stop
- End Function
- Private
- Global timer_factories:TTimerFactory
- Public
- Type TTimerFactory
- Field _succ:TTimerFactory
-
- Method New()
- If _succ <> Null Then
- Throw "Timer already installed : " + _succ.GetName()
- End If
- _succ=timer_factories
- timer_factories=Self
- End Method
-
- Method GetName:String() Abstract
-
- Method Create:TTimer(hertz:Float,event:TEvent=Null) Abstract
-
- End Type
- Rem
- bbdoc: A high resolution timing mechanism.
- End Rem
- Type TChrono
- Const TICKS_PER_MILLIS:Int = 10000
- Const TICKS_PER_SEC:Int = TICKS_PER_MILLIS * 1000
- Const SECS_TO_NS:ULong = 1000000000:ULong
-
- Const FREQUENCY:Double = 1000000000.0
- Const tickFrequency:Double = TICKS_PER_SEC / FREQUENCY
-
- Field isRunning:Int
- Field startTimestamp:ULong
- Field elapsed:ULong
-
- Rem
- bbdoc: Creates a new #TChrono instance.
- End Rem
- Method New()
- Reset()
- End Method
-
- Method Reset()
- elapsed = 0
- isRunning = False
- startTimestamp = 0
- End Method
-
- Rem
- bbdoc: Restarts the timing mechanism.
- End Rem
- Method Restart()
- elapsed = 0
- startTimestamp = GetTimestamp()
- isRunning = True
- End Method
- Rem
- bbdoc: Returns the number of elapsed ticks since the timing mechanism was started.
- End Rem
- Method GetElapsedTicks:Long()
- Local timeElapsed:Long = elapsed
-
- If isRunning Then
- Local currentTimestamp:ULong = GetTimestamp()
- Local elapsedUntilNow:ULong = currentTimestamp - startTimestamp
- timeElapsed :+ elapsedUntilNow
- End If
-
- Return timeElapsed
- End Method
-
- Rem
- bbdoc: Returns the number of elapsed milliseconds since the timing mechanism was started.
- End Rem
- Method GetElapsedMilliseconds:ULong()
- Return GetElapsedDateTimeTicks() / TICKS_PER_MILLIS
- End Method
-
- Rem
- bbdoc:
- End Rem
- Method GetElapsedDateTimeTicks:ULong()
- Local ticks:Double = GetElapsedTicks()
- ticks :* tickFrequency
- Return ULong(ticks)
- End Method
-
- Rem
- bbdoc: Returns the current timestamp, in ns.
- End Rem
- Function GetTimestamp:ULong()
- ?Not macos
- Local tv:STimeSpec
- clock_gettime_(1, tv)
- Return tv.tv_sec * SECS_TO_NS + tv.tv_nsec
- ?macos
- Return mach_absolute_time_ns()
- ?
- End Function
-
- Rem
- bbdoc: Starts the timimg mechanism.
- End Rem
- Method Start()
- If Not isRunning Then
- startTimestamp = GetTimestamp()
- isRunning = True
- End If
- End Method
-
- Rem
- bbdoc: Stops the timing mechanism.
- End Rem
- Method Stop()
- If isRunning Then
- Local endTimestamp:ULong = GetTimestamp()
- Local elapsedThisPeriod:ULong = endTimestamp - startTimestamp
- elapsed :+ elapsedThisPeriod
- isRunning = False
- End If
- End Method
-
- Rem
- bbdoc: Creates, and optionally starts an instance of #TChrono.
- End Rem
- Function Create:TChrono(start:Int = True)
- Local stopWatch:TChrono = New TChrono
- If start Then
- stopWatch.Start()
- End If
- Return stopWatch
- End Function
-
- End Type
|