An open API service indexing awesome lists of open source software.

https://github.com/catcodegames/intervaltimers

Timers for UniTask. Using UniTask's functionality to integrate with PlayerLoop. Featuring flexible settings and eliminating accumulation of errors in cyclic executions.
https://github.com/catcodegames/intervaltimers

Last synced: 8 months ago
JSON representation

Timers for UniTask. Using UniTask's functionality to integrate with PlayerLoop. Featuring flexible settings and eliminating accumulation of errors in cyclic executions.

Awesome Lists containing this project

README

          

# 1. Description
Timers for UniTask. Using UniTask's functionality to integrate with PlayerLoop. Featuring flexible settings and eliminating accumulation of errors in cyclic executions.\

### Key Features and Advantages:
- **Accuracy without error accumulation.**\
Each timer tick accounts for the difference between the scheduled and actual execution times, preventing error accumulation.
- **Configurable number of ticks.**\
You can set a specific number of timer ticks, such as having the timer run 10 times at one-second intervals and then stop.
- **Choice of game cycle for execution.**\
The timer can run in various cycles like `Update`, `FixedUpdate`, and others.
- **Custom time function.**\
You can use your own time function instead of the standard Time.time and Time.deltaTime.
- **Multiple ticks per frame.**\
For very short intervals, the timer can trigger events multiple times within a single frame.
- **Safe multiple starts and stops.**\
The timer remains stable even if Start() and Stop() are called multiple times within the same frame.
- **On-the-fly parameter changes.**\
Parameters such as the interval and number of ticks can be adjusted during the timer's operation.
- **Easy saving and copying.**\
Internal parameters like elapsed time and the number of ticks are accessible, making it easy to save the state or create copies.

 
# 2. Timers

## 1. DeltaTimeTimer
- Uses the difference in time between frames (`Time.deltaTime` and similar) for its calculations.
- Upon stopping and restarting, continues without accounting for the time when the timer was paused.

### Creation
``` csharp
public static DeltaTimeTimer Create( float interval, int loopCount, InvokeMode invokeMode, bool unscaledTime, PlayerLoopTiming playerLoopTiming)
```
- `interval` - The time interval after which the timer triggers the Elapsed event.
- `loopCount` - The number of times the timer should trigger the Elapsed event. -1 indicates an infinite loop.
- `invokeMode` - Determines whether the timer can trigger the Elapsed event multiple times within a single frame or only once.
- `unscaledTime` - Specifies whether to use Time.unscaledDeltaTime or Time.deltaTime for time calculation.
- `playerLoopTiming` - Determines which game loop (e.g., Update, FixedUpdate, etc.) the timer will use.

``` csharp
public static DeltaTimeTimer Create( float interval, Func getDeltaTime, int loopCount, InvokeMode invokeMode, PlayerLoopTiming playerLoopTiming)
```
- `getDeltaTime` - A custom function that returns the interval between the current and previous frame.

### Properties
#### Data
Contains all the working parameters of the timer.
- `ElapsedTime` - The time since the timer was started or last triggered.
- `Interval` - The time interval after which the timer triggers the Elapsed event.
- `CompletedTicks` - The current number of times the timer has triggered.
- `TotalTicks` - The number of times the timer should trigger. -1 indicates an infinite loop.

#### TickData
Contains information about the last trigger of the timer. If the timer can trigger multiple times within a single frame, this property determines the number of event calls and their order.
- `TicksPerFrame` - The number of times the timer triggers within a single frame.
- `TickNumber` - The sequential number of the timer trigger in InvokeMode.Multi; always 0 in InvokeMode.Single.

 
## 2. RealtimeTimer
- Uses game time (`Time.time` and similar, or a user-defined time function).
- Upon stopping and restarting, triggers all missed events.
- In the case of multiple events within a single frame, the timer accurately determines the time of each event using the Date.Time property.

### Creation
``` csharp
public static RealtimeTimer Create(float interval, int loopsCount, InvokeMode invokeMode, RealtimeMode timeMode, PlayerLoopTiming playerLoopTiming)
```
- `interval` - The time interval after which the timer triggers the `Elapsed` event.
- `loopCount` - The number of times the timer should trigger the `Elapsed` event. `-1` indicates an infinite loop.
- `invokeMode` - Determines whether the timer can trigger the Elapsed event multiple times within a single frame or only once.
- `timeMode` - Specifies the type of time used: `Time.unscaledTime`, `Time.time`, or `Time.realtimeSinceStartup`.
- `playerLoopTiming` - Determines which game loop (e.g., Update, FixedUpdate, etc.) the timer will use.

``` csharp
public static RealtimeTimer Create(float interval, Func getTime, int loopsCount, InvokeMode invokeMode, PlayerLoopTiming playerLoopTiming)
```
- `getDeltaTime`: A custom function that returns the interval between the current and previous frame.

### Properties
#### Data
Contains all the working parameters of the timer.
- `LastTime` - The time of the last trigger or when the timer started.
- `Interval` - The time interval after which the timer triggers the `Elapsed` event.
- `CompletedTicks` - The current number of times the timer has triggered.
- `TotalTicks` - The total number of times the timer will trigger before stopping. `-1` indicates an infinite loop.

#### TickData
Contains information about the last trigger of the timer. If the timer can trigger multiple times within a single frame, this property determines the number of event calls and their order.
- `TicksPerFrame` - The number of times the timer triggers within a single frame.
- `TickNumber` - The sequential number of the timer trigger in InvokeMode.Multi; always 0 in InvokeMode.Single.

 
## 3. DateTimeTimer
- Uses system time (`DateTime.Now` or a user-defined function).
- Upon stopping and restarting, triggers all missed events.
- In the case of multiple events within a single frame, the timer accurately determines the time of each event using the Date.Time property.
-
### Creation
``` csharp
public static DateTimeTimer Create(TimeSpan interval, int loopsCount, InvokeMode invokeMode, PlayerLoopTiming playerLoopTiming)
```
- `interval` - The time interval after which the timer triggers the `Elapsed` event.
- `loopCount` - The number of times the timer should trigger the `Elapsed` event. `-1` indicates an infinite loop.
- `invokeMode` - Determines whether the timer can trigger the Elapsed event multiple times within a single frame or only once.
- `playerLoopTiming` - Determines which game loop (e.g., Update, FixedUpdate, etc.) the timer will use.

``` csharp
public static DateTimeTimer Create(TimeSpan interval, Func getTime, int loopsCount, InvokeMode invokeMode, PlayerLoopTiming playerLoopTiming)
```
- `getDeltaTime`: A custom function that returns the interval between the current and previous frame.

### Properties
#### Data
Contains all the working parameters of the timer.
- `LastTime` - The time of the last trigger or when the timer started.
- `Interval` - The time interval after which the timer triggers the `Elapsed` event.
- `CompletedTicks` - The current number of times the timer has triggered.
- `TotalTicks` - The total number of times the timer will trigger before stopping. `-1` indicates an infinite loop.

#### TickData
Contains information about the last trigger of the timer. If the timer can trigger multiple times within a single frame, this property determines the number of event calls and their order.
- `TicksPerFrame` - The number of times the timer triggers within a single frame.
- `TickNumber` - The sequential number of the timer trigger in InvokeMode.Multi; always 0 in InvokeMode.Single.

 
# 3. Examples
An example of a timer that ticks every second and stops after 10 ticks
``` csharp
float interval = 1f;
int loopCount = 10;
// Custom time function for example.
Func getTime = GameWorldTime.GetTime;
InvokeMode invokeMode = InvokeMode.Multi;

// Create timer
var timer = RealtimeTimer.Create(interval, getTime, loopCount, invokeMode);

timer.Elapsed += () => { Debug.Log($"Elapsed at realtime {Time.time}. Calculate time - {timer.Data.LastTime}"); };
timer.Started += () => Debug.Log("Timer started");
timer.Stopped += () => Debug.Log("Timer stopped");
timer.Completed += () => Debug.Log("Tier finished");

// Start or resume the timer
timer.Start();

// Modify timer properties
timer.Data.Interval = interval * 2;
timer.Data.LastTime = GameWorldTime.GetTime() + 10;

// Stop the timer, with the ability to resume.
timer.Stop();

// Stop and reset the timer
timer.Reset();
```

## InvokeMode
When the timer's interval is shorter than the frame time, this parameter defines how the timer will trigger events.
### InvokeMode.Multi
In this mode, the `Elapsed` event is called multiple times within a single frame. The `TickData` property provides information on how many times the timer has triggered and the sequence number of the current event.
``` csharp
float interval = 0.005f;
int loopCount = 5;

var timer = DeltaTimeTimer.Create(interval, loopCount, invokeMode: InvokeMode.Multi);
timer.Started += ()=> Debug.Log($"Timer started at {Time.time}");
timer.Completed += () => Debug.Log($"Timer finished at {Time.time}");
timer.Elapsed += () => Debug.Log($"Current time - {Time.time}. Scheduled time - {timer.Data.LastTime}. Ticks - {timer.TickData.TickNumber + 1}/{timer.TickData.TicksPerFrame}");

timer.Start();
```
Output
```
Timer started at 19,02731
Current time - 19,03973. Scheduled time - 19,03231. Ticks - 1/2
Current time - 19,03973. Scheduled time - 19,03731. Ticks - 2/2
Current time - 19,05369. Scheduled time - 19,04231. Ticks - 1/3
Current time - 19,05369. Scheduled time - 19,04731. Ticks - 2/3
Current time - 19,05369. Scheduled time - 19,05231. Ticks - 3/3
Timer finished at 19,05369
```
### InvokeMode.Single
In this mode, the `Elapsed` method is called once per frame. The `TickData` properties provide information only about the number of timer triggers.
``` csharp
float interval = 0.005f;
int loopCount = 5;

var timer = DeltaTimeTimer.Create(interval, loopCount, invokeMode: InvokeMode.Single);
timer.Started += ()=> Debug.Log($"Timer started at {Time.time}");
timer.Completed += () => Debug.Log($"Timer finished at {Time.time}");
timer.Elapsed += () => Debug.Log($"Current time - {Time.time}. Ticks - {timer.TickData.TicksPerFrame}");

timer.Start();
```
Вывод
```
Timer started at 19,02731
Current time - 19,03973. Ticks - 2
Current time - 19,05369. Ticks - 3
Timer finished at 19,05369
```

 
 
# 1. Описание
Таймеры для UniTask. Используют функционал библиотеки UniTask для интеграции в PlayerLoop. Имеют гибкие настройки и не накапливают погрешности в циклических срабатываниях.

### Основные возможности и преимущества:
- **Точность работы без накопления ошибок.**\
При каждом срабатывании таймера учитывается разница между запланированным и фактическим временем выполнения.
- **Настраиваемое количество срабатываний.**\
Возможность задать количество срабатываний, например, чтобы таймер отработал 10 раз с интервалом в одну секунду и затем остановился.
- **Выбор игрового цикла для выполнения.**\
Таймер может работать в Update, FixedUpdate и других циклах.
- **Пользовательская функция времени.**\
Возможность использовать собственную функцию времени вместо стандартных Time.time, Time.deltaTime и других.
- **Многократные срабатывания за один кадр.**\
При малых интервалах времени таймер может вызывать события несколько раз за один кадр.
- **Безопасный многократный запуск и остановка.**\
Таймер остается стабильным при многократных вызовах Start() и Stop() в пределах одного кадра
- **Изменение параметров на лету.**\
Интервал, количество срабатываний и другие параметры могут быть изменены в процессе работы таймера.
- **Простота сохранения и копирования.**\
Внутренние параметры таймера, такие как прошедшее время и количество срабатываний, доступны для сохранения и создания копий.

 
# 2. Таймера:

## 1. DeltaTimeTimer:
- Использует разницу времени между кадрами для своих расчётов (Time.deltaTime и другие).
- При остановке и последующем запуске продолжает работу без учета времени, когда таймер был остановлен.

### Создание
``` csharp
public static DeltaTimeTimer Create( float interval, int loopCount, InvokeMode invokeMode, bool unscaledTime, PlayerLoopTiming playerLoopTiming)
```
- ```interval``` - Интервал времени, по истечению которого таймер вызывает событие ```Elapsed```.\
- ```loopCount``` - Количество раз, которое таймер должен вызвать событие ```Elapsed```. ```-1``` - бесконечный режим работы таймера.\
- ```invokeMode``` - Определяет, может ли таймер вызывать событие ```Elapsed``` несколько раз за один кадр или только один раз.\
- ```unscaledTime``` - Указывает, использовать ли ```Time.unscaledDeltaTime``` или ```Time.deltaTime``` для расчета времени.\
- ```playerLoopTiming``` - Определяет, в каком из игровых циклов (например, ```Update```, ```FixedUpdate``` и т.д.) будет использоваться таймер.

``` csharp
public static DeltaTimeTimer Create( float interval, Func getDeltaTime, int loopCount, InvokeMode invokeMode, PlayerLoopTiming playerLoopTiming)
```
- ```getDeltaTime``` - пользовательская функция, возвращающая интервал между текущим и предыдущим кадром.

### Свойства

#### Data
Содержит все рабочие параметры таймера.
- ```ElapsedTime``` - Время с момента запуска или последнего срабатывания таймера.
- ```Interval``` - Интервал времени, по истечению которого таймер вызывает событие ```Elapsed```.
- ```CompletedTicks``` - Текущее количество срабатываний таймера.
- ```TotalTicks``` - Количество раз сколько должен сработать таймер. -1 - бесконечный режим работы таймера.

#### TickData
Содержит информацию о последнем срабатывании таймера. Если таймер может сработать несколько раз в пределах одного кадра, это свойство позволяет определить количество вызовов события и их порядок.
- ```TicksPerFrame``` - Количество срабатываний таймера в пределах одного кадра.
- ```TickNumber``` - Порядковый номер срабатывания таймера в режиме ```InvokeMode.Multi```; всегда 0 в режиме ```InvokeMode.Single```.

 
## 2. RealtimeTimer
- Использует игровое время (Time.time и другие или пользовательскую функцию времени).
- При остановке и последующем запуске вызываются все пропущенные срабатывания.
- В случае многократных срабатываний в пределах одного кадра, таймер позволяет точно определить время каждого срабатывания, используя свойство Date.Time.
### Создание
``` csharp
public static RealtimeTimer Create(float interval, int loopsCount, InvokeMode invokeMode, RealtimeMode timeMode, PlayerLoopTiming playerLoopTiming)
```
- ```interval``` - Интервал времени, по истечению которого таймер вызывает событие ```Elapsed```.\
- ```loopCount``` - Количество раз, которое таймер должен вызвать событие ```Elapsed```. ```-1``` - бесконечный режим работы таймера.
- ```invokeMode``` - Определяет, может ли таймер вызывать событие ```Elapsed``` несколько раз за один кадр или только один раз.
- ```timeMode``` - Указывает тип используемого времени : ```Time.unscaledTime```, ```Time.time``` или ```Time.realtimeSinceStartup```.
- ```playerLoopTiming``` - Определяет, в каком из игровых циклов (например, ```Update```, ```FixedUpdate``` и т.д.) будет использоваться таймер.

``` csharp
public static RealtimeTimer Create(float interval, Func getTime, int loopsCount, InvokeMode invokeMode, PlayerLoopTiming playerLoopTiming)
```
- ```getTime``` - Пользовательская функция, возвращающая текущее игровое время.

### Свойства
#### Data
Содержит все рабочие параметры таймера.
- ```LastTime``` - Время последнего срабатывания таймера или время его запуска.
- ```Interval``` - Временной интервал, по истечению которого таймер генерирует событие ```Elapsed```.
- ```CompletedTicks``` - Текущее количество срабатываний таймера
- ```TotalTicks``` - Общее количество срабатываний таймера до его остановки. Значение -1 указывает на бесконечный режим работы.

#### TickData
Содержит информацию о последнем срабатывании таймера. Если таймер может сработать несколько раз в пределах одного кадра, это свойство позволяет определить количество вызовов события и их порядок.
- ```TicksPerFrame``` - Количество срабатываний таймера в пределах одного кадра;
- ```TickNumber``` - Порядковый номер срабатывания таймера в режиме ```InvokeMode.Multi```; всегда 0 в режиме ```InvokeMode.Single```;

 
## 3. DateTimeTimer
- Использует системное время (DateTime.Now или пользовательскую функцию).
- При остановке и последующем запуске вызываются все пропущенные срабатывания.
- В случае многократных срабатываний в пределах одного кадра, таймер позволяет точно определить время каждого срабатывания, используя свойство Date.Time.

### Создание
``` csharp
public static DateTimeTimer Create(TimeSpan interval, int loopsCount, InvokeMode invokeMode, PlayerLoopTiming playerLoopTiming)
```
- ```interval``` - Интервал времени, по истечению которого таймер вызывает событие ```Elapsed```.\
- ```loopCount``` - Количество раз, которое таймер должен вызвать событие ```Elapsed```. ```-1``` - бесконечный режим работы таймера.\
- ```invokeMode``` - Определяет, может ли таймер вызывать событие ```Elapsed``` несколько раз за один кадр или только один раз.\
- ```playerLoopTiming``` - Определяет, в каком из игровых циклов (например, ```Update```, ```FixedUpdate``` и т.д.) будет использоваться таймер.

``` csharp
public static DateTimeTimer Create(TimeSpan interval, Func getTime, int loopsCount, InvokeMode invokeMode, PlayerLoopTiming playerLoopTiming)
```
- ```getTime``` - Пользовательская функция, возвращающая текущее системное время.

 
# 3. Использование
Пример таймера, который срабатывает каждую секунду и останавливается после 10 срабатываний.
``` csharp
float interval = 1f;
int loopCount = 10;
Func getTime = GameWorldTime.GetTime;
InvokeMode invokeMode = InvokeMode.Multi;

// Create timer
var timer = RealtimeTimer.Create(interval, getTime, loopCount, invokeMode);

timer.Elapsed += () => { Debug.Log($"Elapsed at realtime {Time.time}. Calculate time - {timer.Data.LastTime}"); };
timer.Started += () => Debug.Log("Timer started");
timer.Stopped += () => Debug.Log("Timer stopped");
timer.Completed += () => Debug.Log("Tier finished");

// Start or resume the timer
timer.Start();

// Modify timer properties
timer.Data.Interval = interval * 2;
timer.Data.LastTime = GameWorldTime.GetTime() + 10;

// Stop the timer, with the ability to resume.
timer.Stop();

// Stop and reset the timer
timer.Reset();
```

## InvokeMode
Если интервал срабатывания таймера меньше, чем интервал времени между кадрами, то этот параметр определяет как таймер будет вызывать событие.
### InvokeMode.Multi
В этом режиме событие `Elapsed` будет вызываться несколько раз в течении одного кадра. Свойство `TickData` позволяет получить информацию о количестве срабатываний таймера за кадр и номер текущего события.
``` csharp
float interval = 0.005f;
int loopCount = 5;

var timer = DeltaTimeTimer.Create(interval, loopCount, invokeMode: InvokeMode.Multi);
timer.Started += ()=> Debug.Log($"Timer started at {Time.time}");
timer.Completed += () => Debug.Log($"Timer finished at {Time.time}");
timer.Elapsed += () => Debug.Log($"Current time - {Time.time}. Scheduled time - {timer.Data.LastTime}. Ticks - {timer.TickData.TickNumber + 1}/{timer.TickData.TicksPerFrame}");

timer.Start();
```
Вывод
```
Timer started at 19,02731
Current time - 19,03973. Scheduled time - 19,03231. Ticks - 1/2
Current time - 19,03973. Scheduled time - 19,03731. Ticks - 2/2
Current time - 19,05369. Scheduled time - 19,04231. Ticks - 1/3
Current time - 19,05369. Scheduled time - 19,04731. Ticks - 2/3
Current time - 19,05369. Scheduled time - 19,05231. Ticks - 3/3
Timer finished at 19,05369
```
### InvokeMode.Single
В этом режиме событие `Elapsed` будет вызываться один раз в течении одного кадра. Свойство `TickData` позволяет получить информацию только о коичестве срабатываний таймера.
``` csharp
float interval = 0.005f;
int loopCount = 5;

var timer = DeltaTimeTimer.Create(interval, loopCount, invokeMode: InvokeMode.Single);
timer.Started += ()=> Debug.Log($"Timer started at {Time.time}");
timer.Completed += () => Debug.Log($"Timer finished at {Time.time}");
timer.Elapsed += () => Debug.Log($"Current time - {Time.time}. Ticks - {timer.TickData.TicksPerFrame}");

timer.Start();
```
Вывод
```
Timer started at 19,02731
Current time - 19,03973. Ticks - 2
Current time - 19,05369. Ticks - 3
Timer finished at 19,05369
```