Timer Service
Timer Service
manages all time updates in IdleKit as well as providing a centralized source of time to any Entities or Services that require time-information. A significant portion of the gameplay Entities relies on this, including the Generator
(ProduceState, AutoCollecState). A class must implement the ITimerListener
interface to subscribe to the Timer Service
.
The Timer Service
tracks time in two different ways; systemTime and gameTime.
Game Time
The game time is the time for the Content
that the user is currently on. It is used in all timed gameplay-related calculations such as the Generator production time or timer trunks refresh timer.
IdleKit tracks a different game time for each Content
. This means that when a player enters a previously played Content, the ActivityTrackingService
can calculate how much time has elapsed between the Content's gameTime and the current systemTime. The elapsed time is then used to calculate the currency earned while offline.
System Time
The system time is the unifying time of the app, which should be overridden by an authoritative back-end server in a production environment. In the default IdleKit implementation, it is only used by the ActivityTrackingService to calculate any offline currencies gains.
ITimerListener
Events based on gameTime can be received via implementation of the ITimerListener
interface. Only objects that implement this interface can subscribe to the Timer Service
.
Every ITimerListener
contains an ITimerSubscription
, which includes data for the subscription. Any ITimerListener
must implement UpdateProgression(Single)
and OnTimerEnded(Int32)
. The Timer Service
invokes the first method on each update. The second method is be called when the subscription end time has been reached or exceeded.
ITimerSubscription
An ITimerListener
must contain an ITimerSubscription
composing of various pieces of information for a time-based subscription, such as; start time, duration, and end time. IdleKit's default implementation of the ITimerSubscription contains various constructors in different permutations of time formats (milliseconds, seconds, DateTime) to make it easier for objects that have different time information to work with the Timer Service.
Priority
When creating an ITimerSubscription
, the user can specify an optional int
parameter for the priority of the ITimerSubscription
. When time updates and all the ITimerListener
are evaluted (more below), those ITimerListener
with the ITimerSubscription
that contains a higher priority would be evaluated first. This enables finer control over timed update (i.e: We can set the ITimedBoost
to a lower priority so IGeneratorEntity
collection can take place with the ITimedBoost
still being active).
Flow Diagrams
Subscribe
The following diagram demonstrates the flow of subscribing to the Timer Service
with an ITimerListener
. This usually happens in the initialization phase of an ITimerListener
. The ITimerSubscription
is created, and the object then subscribes itself to the Timer Service
. At the end of the subscription flow, the subscriber can be in one of two states. It is either registered (subscribed) to the ITimerService, or unsubscribed if the timer immediately completed, in which case OnTimerEnded(Int32) has been invoked.
Update
The following diagram demonstrates the flow when the time is updated. Each update evaluates all the ITimerListener
objects subscribed to the Timer Service. Two things can trigger an update: * The Unity
Event Listener" that listens to Unity's Update() every frame and notifies the Timer Service * The ActivityTrackingService
or unit tests that set the time using TimerService.SetTime
The Update flow ends after all ITimerListener
objects have been updated with UpdateProgression(Single)
. If the end time for the subscription has been reached or exceeded, the ITimerListener
that contains a non-looping subscription would be Unsubscribed
and the OnTimerEnded(Int64)
method on the ITimerListener
is invoked.