diff --git a/core/include/istd_core/system.h b/core/include/istd_core/system.h new file mode 100644 index 0000000..adf6669 --- /dev/null +++ b/core/include/istd_core/system.h @@ -0,0 +1,50 @@ +#ifndef ISTD_CORE_SYSTEM_H +#define ISTD_CORE_SYSTEM_H + +#include "istd_core/world.h" +#include +#include +#include +#include + +namespace istd { + +struct System { + virtual void tick(World &world) const = 0; + virtual std::string_view name() const noexcept = 0; // for debugging + + // No virtual destructor: static lifetime and no member variables is the + // intended use case + + struct Precedence { + // Smaller value means higher precedence or earlier execution + enum { + Highest = 0, + ResetVelocity, + DeviceAccumulateVelocity, + UpdateKinematics, + }; + }; +}; + +class SystemRegistry { +public: + static SystemRegistry &instance() noexcept; + + void register_system( + std::uint32_t precedence, const System *system + ) noexcept; + + void tick(World &world) const noexcept; + + struct Registar { + Registar(std::uint32_t precedence, const System *system); + }; + +private: + std::vector> systems_; +}; + +} // namespace istd + +#endif \ No newline at end of file diff --git a/core/src/system.cpp b/core/src/system.cpp new file mode 100644 index 0000000..fb14e50 --- /dev/null +++ b/core/src/system.cpp @@ -0,0 +1,38 @@ +#include "istd_core/system.h" +#include + +namespace istd { + +SystemRegistry &SystemRegistry::instance() noexcept { + static SystemRegistry registry; + return registry; +} + +void SystemRegistry::register_system( + std::uint32_t precedence, const System *system +) noexcept { + auto cmp = [](const std::tuple &a, + std::uint32_t b) { + return std::get<0>(a) < b; + }; + + auto it = std::lower_bound( + systems_.begin(), systems_.end(), precedence, cmp + ); + + systems_.insert(it, std::make_tuple(precedence, system)); +} + +void SystemRegistry::tick(World &world) const noexcept { + for (const auto &[_, system] : systems_) { + system->tick(world); + } +} + +SystemRegistry::Registar::Registar( + std::uint32_t precedence, const System *system +) { + SystemRegistry::instance().register_system(precedence, system); +} + +} // namespace istd \ No newline at end of file