207 lines
5.1 KiB
C++
207 lines
5.1 KiB
C++
// Copyright (C) 2007 EQ2EMulator Development Team - GPL v3+ - http://www.eq2emulator.net
|
|
|
|
#pragma once
|
|
|
|
#include <chrono>
|
|
|
|
#include "types.hpp"
|
|
|
|
class Timer
|
|
{
|
|
public:
|
|
// Default constructor - creates a 30-second timer that is disabled by default
|
|
Timer()
|
|
{
|
|
timer_time = 30000;
|
|
start_time = GetCurrentTime();
|
|
set_at_trigger = timer_time;
|
|
use_accurate_timing = false;
|
|
enabled = false;
|
|
}
|
|
|
|
// Constructor with timer duration and optional accurate timing
|
|
Timer(int32 timer_time, bool use_accurate_timing = false)
|
|
{
|
|
this->timer_time = timer_time;
|
|
start_time = GetCurrentTime();
|
|
set_at_trigger = timer_time;
|
|
this->use_accurate_timing = use_accurate_timing;
|
|
enabled = (timer_time != 0);
|
|
}
|
|
|
|
// Constructor with custom start time, timer duration, and optional accurate timing
|
|
Timer(int32 start, int32 timer, bool use_accurate_timing = false)
|
|
{
|
|
timer_time = timer;
|
|
start_time = start;
|
|
set_at_trigger = timer_time;
|
|
this->use_accurate_timing = use_accurate_timing;
|
|
enabled = (timer_time != 0);
|
|
}
|
|
|
|
~Timer() { }
|
|
|
|
// Checks if the timer has triggered and optionally resets it
|
|
bool Check(bool reset = true)
|
|
{
|
|
if (enabled && GetCurrentTime() - start_time > timer_time) {
|
|
if (reset) {
|
|
if (use_accurate_timing)
|
|
start_time += timer_time;
|
|
else
|
|
start_time = GetCurrentTime();
|
|
timer_time = set_at_trigger;
|
|
}
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
// Enables the timer
|
|
void Enable()
|
|
{
|
|
enabled = true;
|
|
}
|
|
|
|
// Disables the timer
|
|
void Disable()
|
|
{
|
|
enabled = false;
|
|
}
|
|
|
|
// Starts the timer with optional new duration and reset behavior
|
|
void Start(int32 set_timer_time = 0, bool change_reset_timer = true)
|
|
{
|
|
start_time = GetCurrentTime();
|
|
enabled = true;
|
|
if (set_timer_time != 0) {
|
|
timer_time = set_timer_time;
|
|
if (change_reset_timer)
|
|
set_at_trigger = set_timer_time;
|
|
}
|
|
}
|
|
|
|
// Sets the timer duration without restarting it
|
|
void SetTimer(int32 set_timer_time = 0)
|
|
{
|
|
if (!enabled) {
|
|
start_time = GetCurrentTime();
|
|
enabled = true;
|
|
}
|
|
if (set_timer_time != 0) {
|
|
timer_time = set_timer_time;
|
|
set_at_trigger = set_timer_time;
|
|
}
|
|
}
|
|
|
|
// Returns the elapsed time since timer started, or 0xFFFFFFFF if disabled
|
|
int32 GetElapsedTime()
|
|
{
|
|
if (enabled) {
|
|
return GetCurrentTime() - start_time;
|
|
}
|
|
return 0xFFFFFFFF;
|
|
}
|
|
|
|
// Returns the remaining time until timer triggers, or 0xFFFFFFFF if disabled
|
|
int32 GetRemainingTime()
|
|
{
|
|
if (enabled) {
|
|
if (GetCurrentTime() - start_time > timer_time)
|
|
return 0;
|
|
else
|
|
return (start_time + timer_time) - GetCurrentTime();
|
|
}
|
|
return 0xFFFFFFFF;
|
|
}
|
|
|
|
// Sets the trigger value and optionally enables the timer
|
|
void SetAtTrigger(int32 trigger_value, bool enable_if_disabled = false)
|
|
{
|
|
set_at_trigger = trigger_value;
|
|
if (!Enabled() && enable_if_disabled) {
|
|
Enable();
|
|
}
|
|
}
|
|
|
|
// Forces the timer to trigger immediately
|
|
void Trigger()
|
|
{
|
|
enabled = true;
|
|
timer_time = set_at_trigger;
|
|
start_time = GetCurrentTime() - timer_time - 1;
|
|
}
|
|
|
|
// Returns the current timer duration
|
|
inline const int32& GetTimerTime() { return timer_time; }
|
|
|
|
// Returns the trigger value
|
|
inline const int32& GetSetAtTrigger() { return set_at_trigger; }
|
|
|
|
// Returns whether the timer is enabled
|
|
inline bool Enabled() { return enabled; }
|
|
|
|
// Returns the start time of the timer
|
|
inline int32 GetStartTime() { return start_time; }
|
|
|
|
// Returns the duration of the timer
|
|
inline int32 GetDuration() { return timer_time; }
|
|
|
|
// Returns the current time in milliseconds since program start
|
|
static int32 GetCurrentTime()
|
|
{
|
|
static auto program_start = std::chrono::steady_clock::now();
|
|
auto now = std::chrono::steady_clock::now();
|
|
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(now - program_start);
|
|
return static_cast<int32>(duration.count());
|
|
}
|
|
|
|
// Legacy method name for current time
|
|
static const int32 GetCurrentTime2()
|
|
{
|
|
static int32 current = GetCurrentTime();
|
|
current = GetCurrentTime();
|
|
return current;
|
|
}
|
|
|
|
// Legacy method name for setting current time
|
|
static const int32 SetCurrentTime()
|
|
{
|
|
return GetCurrentTime();
|
|
}
|
|
|
|
// Returns the current Unix timestamp in seconds
|
|
static int32 GetUnixTimeStamp()
|
|
{
|
|
auto now = std::chrono::system_clock::now();
|
|
auto time_t = std::chrono::system_clock::to_time_t(now);
|
|
return static_cast<int32>(time_t);
|
|
}
|
|
|
|
private:
|
|
int32 start_time; // Time when timer was started
|
|
int32 timer_time; // Duration of the timer in milliseconds
|
|
bool enabled; // Whether the timer is active
|
|
int32 set_at_trigger; // Value to reset timer_time to when triggered
|
|
|
|
// Uses accurate timing - adds timer_time to start_time instead of setting to current time
|
|
bool use_accurate_timing;
|
|
};
|
|
|
|
// High-resolution timer for benchmarking purposes
|
|
struct BenchTimer
|
|
{
|
|
typedef std::chrono::high_resolution_clock clock;
|
|
|
|
// Constructor - starts timing immediately
|
|
BenchTimer() : start_time(clock::now()) {}
|
|
|
|
// Resets the timer to current time
|
|
void reset() { start_time = clock::now(); }
|
|
|
|
// Returns elapsed time in seconds as a double
|
|
double elapsed() { return std::chrono::duration<double>(clock::now() - start_time).count(); }
|
|
|
|
private:
|
|
std::chrono::time_point<std::chrono::high_resolution_clock> start_time; // Timer start point
|
|
}; |