fix engine variant added tests

This commit is contained in:
2026-07-22 16:49:46 +01:00
parent f4ad43b05f
commit 12d80df8ad
8 changed files with 290 additions and 92 deletions
@@ -68,13 +68,13 @@ class VariantOpManager {
return p + (n - p) * req.alpha;
},
[&](Vec2 p, Vec2 n) -> EngineVariant::InternalVariant {
return Vec2Lerp(p, n, req.alpha);
return vec2_lerp(p, n, req.alpha);
},
[&](Vec3 p, Vec3 n) -> EngineVariant::InternalVariant {
return Vec3Lerp(p, n, req.alpha);
return vec3_lerp(p, n, req.alpha);
},
[&](Vec4 p, Vec4 n) -> EngineVariant::InternalVariant {
return Vec4Lerp(p, n, req.alpha);
return vec4_lerp(p, n, req.alpha);
},
[&](const std::string &p, const std::string &n)
-> EngineVariant::InternalVariant {
@@ -0,0 +1,32 @@
#pragma once
#include <entt/entt.hpp>
namespace varicle {
namespace PropertyID {
using namespace entt::literals;
// Guaranteed unique & typo-proof at compile time!
constexpr auto TransformPosition = "transform:position"_hs;
constexpr auto TransformScale = "transform:scale"_hs;
constexpr auto TransformRotation = "transform:rotation"_hs;
constexpr auto GlobalTransformPosition = "global_transform:position"_hs;
constexpr auto GlobalTransformScale = "global_transform:scale"_hs;
constexpr auto GlobalTransformRotation = "global_transform:rotation"_hs;
constexpr auto VelocityX = "velocity:x"_hs;
constexpr auto VelocityY = "velocity:y"_hs;
constexpr auto SpriteRotation = "sprite:rotation"_hs;
constexpr auto SpriteTexture = "sprite:texture"_hs;
constexpr auto SpriteOffsetX = "sprite:offset:x"_hs;
constexpr auto SpriteOffsetY = "sprite:offset:y"_hs;
constexpr auto SpriteWidth = "sprite:width"_hs;
constexpr auto SpriteHeight = "sprite:height"_hs;
constexpr auto SpriteFlipV = "sprite:flip_v"_hs;
constexpr auto SpriteFlipH = "sprite:flip_h"_hs;
} // namespace PropertyID
} // namespace varicle
@@ -11,7 +11,7 @@ namespace varicle {
using VariantGetter =
std::function<EngineVariant(const entt::registry &, entt::entity)>;
using VariantSetter =
std::function<void(entt::registry &, entt::entity, const EngineVariant &)>;
std::function<bool(entt::registry &, entt::entity, const EngineVariant &)>;
struct PropertyRef {
uint32_t property_id;
@@ -22,10 +22,11 @@ struct PropertyRef {
return getter ? getter(reg, e) : EngineVariant();
}
void set(entt::registry &reg, entt::entity e,
bool set(entt::registry &reg, entt::entity e,
const EngineVariant &value) const {
if (setter)
setter(reg, e, value);
return setter(reg, e, value);
return false;
}
};
@@ -33,23 +34,33 @@ class PropertyRegistry {
public:
template <typename Component, typename T>
static PropertyRef bind_field(uint32_t prop_hash, T Component::*member) {
return PropertyRef{.property_id = prop_hash,
return PropertyRef{
.property_id = prop_hash,
.setter =
[member](entt::registry &reg, entt::entity e,
const EngineVariant &val) {
if (auto *comp = reg.try_get<Component>(e)) {
(*comp).*member = val.Get<T>();
}
},
.getter = [member](const entt::registry &reg,
entt::entity e) -> EngineVariant {
if (auto *component =
reg.try_get<Component>(e)) {
return EngineVariant((*component).*member);
}
return EngineVariant();
}};
.setter = [member, prop_hash](entt::registry &reg, entt::entity e,
const EngineVariant &val) -> bool {
auto *comp = reg.try_get<Component>(e);
if (!comp) {
return false;
}
if (const T *val_ptr = val.try_get<T>()) {
(*comp).*member = *val_ptr;
return true;
}
// Type mismatch caught safely!
std::cout << "[WARN] Property type mismatch: cannot assign "
"value to property hash "
<< prop_hash << "\n";
return false;
},
.getter = [member](const entt::registry &reg,
entt::entity e) -> EngineVariant {
if (auto *component = reg.try_get<Component>(e)) {
return EngineVariant((*component).*member);
}
return EngineVariant();
}};
}
};
@@ -76,7 +87,6 @@ class PropertyDatabase {
auto it = properites.find(prop_hash);
if (it != properites.end()) {
it->second.set(reg, e, value);
return true;
}
return false;
}
@@ -5,10 +5,9 @@
namespace varicle {
// Overload helper pattern
template <class... Ts> struct Overloaded : Ts... {
template <typename... Ts> struct Overloaded : Ts... {
using Ts::operator()...;
};
template <class... Ts> Overloaded(Ts...) -> Overloaded<Ts...>;
struct Vec2 {
float x = 0.0f;
@@ -59,14 +58,14 @@ struct Vec4 {
};
// Standalone Interpolation Helpers
inline Vec2 Vec2Lerp(const Vec2 &s, const Vec2 &e, float a) {
inline Vec2 vec2_lerp(const Vec2 &s, const Vec2 &e, float a) {
return {s.x + (e.x - s.x) * a, s.y + (e.y - s.y) * a};
}
inline Vec3 Vec3Lerp(const Vec3 &s, const Vec3 &e, float a) {
inline Vec3 vec3_lerp(const Vec3 &s, const Vec3 &e, float a) {
return {s.x + (e.x - s.x) * a, s.y + (e.y - s.y) * a,
s.z + (e.z - s.z) * a};
}
inline Vec4 Vec4Lerp(const Vec4 &s, const Vec4 &e, float a) {
inline Vec4 vec4_lerp(const Vec4 &s, const Vec4 &e, float a) {
return {s.x + (e.x - s.x) * a, s.y + (e.y - s.y) * a, s.z + (e.z - s.z) * a,
s.w + (e.w - s.w) * a};
}
@@ -87,10 +86,12 @@ class EngineVariant {
EngineVariant(std::string v) : data(v) {}
EngineVariant(bool v) : data(v) {}
template <typename T> T Get() const { return std::get<T>(data); }
template <typename T> T *TryGet() { return std::get_if<T>(&data); }
template <typename T> T get() const { return std::get<T>(data); }
template <typename T> const T *try_get() const {
return std::get_if<T>(&data);
}
std::string ToString() const {
std::string to_string() const {
return std::visit(
Overloaded{[](std::monostate) { return std::string("!"); },
[](float v) { return std::to_string(v); },
@@ -118,33 +119,23 @@ class EngineVariant {
friend std::ostream &operator<<(std::ostream &os,
const EngineVariant &variant) {
return os << variant.GetTypeName() << variant.ToString();
return os << variant.get_type_name() << variant.to_string();
}
private:
InternalVariant data;
std::string GetTypeName() const {
std::string get_type_name() const {
return std::visit(
[](auto &&arg) -> std::string {
using T = std::decay_t<decltype(arg)>;
if constexpr (std::is_same_v<T, std::monostate>)
return "Null";
else if constexpr (std::is_same_v<T, float>)
return "Float";
else if constexpr (std::is_same_v<T, Vec2>)
return "Vec2";
else if constexpr (std::is_same_v<T, Vec3>)
return "Vec3";
else if constexpr (std::is_same_v<T, Vec4>)
return "Vec4";
else if constexpr (std::is_same_v<T, std::string>)
return "String";
else if constexpr (std::is_same_v<T, bool>)
return "Bool";
else
return "Unknown";
},
Overloaded{
[](std::monostate) -> std::string { return "Null"; },
[](bool) -> std::string { return "Bool"; },
[](float) -> std::string { return "Float"; },
[](const Vec2 &) -> std::string { return "Vec2"; },
[](const Vec3 &) -> std::string { return "Vec3"; },
[](const Vec4 &) -> std::string { return "Vec4"; },
[](const std::string &) -> std::string { return "String"; },
[](const auto &) -> std::string { return "Unknown"; }},
data);
}
+47 -40
View File
@@ -1,5 +1,6 @@
#include "bindings.hpp"
#include "components.hpp"
#include "engine/core/engine-variant/engine-variant-property-id.hpp"
using namespace entt::literals;
@@ -9,84 +10,90 @@ void varicle::register_all_component_properties(PropertyDatabase &db) {
// LocalTransform2D
//----------------------------------------------------------
db.register_property(
"position"_hs,
PropertyRegistry::bind_field("position"_hs,
PropertyID::TransformPosition,
PropertyRegistry::bind_field(PropertyID::TransformPosition,
&varicle::LocalTransform2D::position));
db.register_property("scale"_hs,
PropertyRegistry::bind_field(
"scale"_hs, &varicle::LocalTransform2D::scale));
db.register_property(
PropertyID::TransformScale,
PropertyRegistry::bind_field(PropertyID::TransformScale,
&varicle::LocalTransform2D::scale));
db.register_property(
"rotation"_hs,
PropertyRegistry::bind_field("rotation"_hs,
PropertyID::TransformRotation,
PropertyRegistry::bind_field(PropertyID::TransformRotation,
&varicle::LocalTransform2D::rotation));
//----------------------------------------------------------
// GlobalTransform2D
//----------------------------------------------------------
db.register_property(
"global_position"_hs,
PropertyRegistry::bind_field("global_position"_hs,
PropertyID::GlobalTransformPosition,
PropertyRegistry::bind_field(PropertyID::GlobalTransformPosition,
&varicle::GlobalTransform2D::position));
db.register_property("global_scale"_hs,
PropertyRegistry::bind_field(
"global_scale"_hs, &varicle::GlobalTransform2D::scale));
db.register_property(
PropertyID::GlobalTransformScale,
PropertyRegistry::bind_field(PropertyID::GlobalTransformScale,
&varicle::GlobalTransform2D::scale));
db.register_property(
"global_rotation"_hs,
PropertyRegistry::bind_field("global_rotation"_hs,
PropertyID::GlobalTransformRotation,
PropertyRegistry::bind_field(PropertyID::GlobalTransformRotation,
&varicle::GlobalTransform2D::rotation));
//----------------------------------------------------------
// Velocity
//----------------------------------------------------------
db.register_property(
"velocity:x"_hs,
PropertyRegistry::bind_field("velocity:x"_hs, &varicle::Velocity::dx));
db.register_property(PropertyID::VelocityX,
PropertyRegistry::bind_field(PropertyID::VelocityX,
&varicle::Velocity::dx));
db.register_property(
"velocity:y"_hs,
PropertyRegistry::bind_field("velocity:y"_hs, &varicle::Velocity::dy));
db.register_property(PropertyID::VelocityY,
PropertyRegistry::bind_field(PropertyID::VelocityY,
&varicle::Velocity::dy));
//----------------------------------------------------------
// Sprite
//----------------------------------------------------------
db.register_property(
"sprite:texture_path"_hs,
PropertyRegistry::bind_field("sprite:texture_path"_hs, &varicle::Sprite::texture_path));
PropertyID::SpriteTexture,
PropertyRegistry::bind_field(PropertyID::SpriteTexture,
&varicle::Sprite::texture_path));
db.register_property(
"sprite:offset:y"_hs,
PropertyRegistry::bind_field("sprite:offset:y"_hs, &varicle::Sprite::offset_y));
PropertyID::SpriteOffsetY,
PropertyRegistry::bind_field(PropertyID::SpriteOffsetY,
&varicle::Sprite::offset_y));
db.register_property(
"sprite:offset:x"_hs,
PropertyRegistry::bind_field("sprite:offset:x"_hs, &varicle::Sprite::offset_x));
PropertyID::SpriteOffsetX,
PropertyRegistry::bind_field(PropertyID::SpriteOffsetX,
&varicle::Sprite::offset_x));
db.register_property(PropertyID::SpriteWidth,
PropertyRegistry::bind_field(PropertyID::SpriteWidth,
&varicle::Sprite::width));
db.register_property(
"sprite:width"_hs,
PropertyRegistry::bind_field("sprite:width"_hs, &varicle::Sprite::width));
PropertyID::SpriteHeight,
PropertyRegistry::bind_field(PropertyID::SpriteHeight,
&varicle::Sprite::height));
db.register_property(
"sprite:height"_hs,
PropertyRegistry::bind_field("sprite:height"_hs, &varicle::Sprite::height));
db.register_property(
"sprite:flip_h"_hs,
PropertyRegistry::bind_field("sprite:flip_h"_hs, &varicle::Sprite::flip_h));
PropertyID::SpriteFlipH,
PropertyRegistry::bind_field(PropertyID::SpriteFlipH,
&varicle::Sprite::flip_h));
db.register_property(
"sprite:flip_v"_hs,
PropertyRegistry::bind_field("sprite:flip_v"_hs, &varicle::Sprite::flip_v));
PropertyID::SpriteFlipV,
PropertyRegistry::bind_field(PropertyID::SpriteFlipV,
&varicle::Sprite::flip_v));
db.register_property(
"sprite:rotation"_hs,
PropertyRegistry::bind_field("sprite:rotation"_hs, &varicle::Sprite::rotation));
PropertyID::SpriteRotation,
PropertyRegistry::bind_field(PropertyID::SpriteRotation,
&varicle::Sprite::rotation));
}