ArtifactEngine/Shared/Shared.h
2026-03-11 18:05:19 -04:00

86 lines
3 KiB
C++

#pragma once
#include <vector>
#include <glm/glm.hpp>
namespace std {
template<>
struct hash<glm::ivec3> {
std::size_t operator()(const glm::ivec3& v) const noexcept {
// Very common and reasonably good quality combination for floats
// (tries to mix bits while being fast)
std::size_t seed = 0;
// You can use any of these styles — pick one:
// ────────────────────────────────────────────────────────────────
// Style 1: Boost hash_combine pattern (very popular)
auto hash_float = [](float f) -> std::size_t {
return std::hash<float>{}(f);
};
seed ^= hash_float(v.x) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
seed ^= hash_float(v.y) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
seed ^= hash_float(v.z) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
// ────────────────────────────────────────────────────────────────
// Style 2: Simpler — fold with multiplication (often enough)
// seed = std::hash<float>{}(v.x);
// seed = seed * 31 + std::hash<float>{}(v.y);
// seed = seed * 31 + std::hash<float>{}(v.z);
// ────────────────────────────────────────────────────────────────
// Style 3: Treat as 12-byte blob → good quality, but slower on some platforms
// std::size_t h = 0;
// std::memcpy(&h, &v, sizeof(float)); // x
// h ^= std::hash<std::uint32_t>{}(h);
// std::memcpy(&h, reinterpret_cast<const char*>(&v) + 4, sizeof(float));
// h ^= std::hash<std::uint32_t>{}(h) * 0x85ebca6b;
// std::memcpy(&h, reinterpret_cast<const char*>(&v) + 8, sizeof(float));
// return std::hash<std::uint32_t>{}(h);
return seed;
}
};
} // namespace std
namespace Artifact {
template<typename Subsystem>
class Engine {
public:
std::vector<std::unique_ptr<Subsystem>> subsystems;
template <typename T, typename... Args>
T * addSubsystem(Args &&... args) {
auto system = std::make_unique<T>(std::forward<Args>(args)...);
auto ptr = system.get();
subsystems.push_back(std::move(system));
return ptr;
}
template <typename T>
T * subsystem() const {
for (const auto & system : subsystems) {
if (T * ptr = dynamic_cast<T *>(system.get())) {
return ptr;
}
}
return nullptr;
}
};
class BaseSubsystem {
public:
Engine<BaseSubsystem> * engine = nullptr;
virtual void init() {}
virtual void reload() {}
virtual void deinit() {}
virtual void render() {}
virtual void tick() {}
};
}