// Copyright (C) 2007 EQ2EMulator Development Team - GPL v3+ - http://www.eq2emulator.net #pragma once #include #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(now - program_start); return static_cast(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(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(clock::now() - start_time).count(); } private: std::chrono::time_point start_time; // Timer start point };