diff --git a/modules/app/private/application.cpp b/modules/app/private/application.cpp index 1038001..194bfcf 100644 --- a/modules/app/private/application.cpp +++ b/modules/app/private/application.cpp @@ -9,10 +9,16 @@ void Application::game_loop() { for (auto &system : m_systems) { - if (system->tick()) - { - return; - } + const auto &last_tick = system->get_last_tick_result(); + const auto now = std::chrono::steady_clock::now(); + + system->tick( + TickInfo { + .delta_time = now - last_tick.end_time, + .budget = std::chrono::milliseconds { 10 }, + .start_time = now, + } + ); } for (auto &system : m_systems_to_be_registered) diff --git a/modules/app/public/system.hpp b/modules/app/public/system.hpp index 231fa88..b513dfb 100644 --- a/modules/app/public/system.hpp +++ b/modules/app/public/system.hpp @@ -1,7 +1,89 @@ #pragma once +#include + namespace lt::app { +/** Information required to tick a system. + * @note May be used across an entire application-frame (consisting of multiple systems ticking) + */ +struct TickInfo +{ + using Timepoint_T = std::chrono::time_point; + + using Duration_T = std::chrono::duration; + + /** Duration since previous tick's end_time to current tick's start_time. */ + Duration_T delta_time {}; + + /** Maximum duration the system is expected to finish ticking in. + * + * if end_time - start_time > budget -> the system exceeded its ticking budget. + * else end_time - start_time < budget -> the system ticked properly. + * + * In other words, end_time is expected to be less than start_time + budget. + */ + Duration_T budget {}; + + /** Exact time which ticking started. */ + Timepoint_T start_time; +}; + +/** Information about how a system's tick performed */ +struct TickResult +{ + using Timepoint_T = std::chrono::time_point; + + using Duration_T = std::chrono::duration; + + /** The info supplied to the system for ticking. */ + TickInfo info; + + /** Equivalent to end_time - info.start_time. */ + Duration_T duration {}; + + /** Exact time which ticking ended. */ + Timepoint_T end_time; +}; + + +struct SystemDiagnosis +{ + enum class Severity : uint8_t + { + verbose, + info, + warning, + error, + fatal, + }; + + std::string message; + + std::string code; + + Severity severity; +}; + +class SystemStats +{ +public: + void push_diagnosis(SystemDiagnosis &&diagnosis) + { + auto diag = m_diagnosis.emplace_back(std::move(diagnosis)); + + log_dbg("message: {}", diag.message); + } + + [[nodiscard]] auto empty_diagnosis() const -> bool + { + return m_diagnosis.empty(); + } + +private: + std::vector m_diagnosis; +}; + class ISystem { public: @@ -21,7 +103,9 @@ public: virtual void on_unregister() = 0; - virtual auto tick() -> bool = 0; + virtual void tick(TickInfo tick) = 0; + + [[nodiscard]] virtual auto get_last_tick_result() const -> const TickResult & = 0; }; } // namespace lt::app