feat: add System and SystemRegistry classes for managing systems in the game engine

Signed-off-by: szdytom <szdytom@qq.com>
This commit is contained in:
方而静 2025-08-05 16:09:22 +08:00
parent 95422cff7a
commit 998668802f
Signed by: szTom
GPG Key ID: 072D999D60C6473C
2 changed files with 88 additions and 0 deletions

View File

@ -0,0 +1,50 @@
#ifndef ISTD_CORE_SYSTEM_H
#define ISTD_CORE_SYSTEM_H
#include "istd_core/world.h"
#include <cstdint>
#include <string_view>
#include <tuple>
#include <vector>
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<std::tuple<std::uint32_t, const System *>> systems_;
};
} // namespace istd
#endif

38
core/src/system.cpp Normal file
View File

@ -0,0 +1,38 @@
#include "istd_core/system.h"
#include <algorithm>
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<std::uint32_t, const System *> &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