Dependency position
#648 (types) ──► THIS ISSUE
#649 (registry) ──► THIS ISSUE ──► #651 (inspector migration)
Wait for #648 and #649 to be merged before adding the Register(...) call.
The .cpp files and FieldDescriptor arrays can be written while #649 is in review — just leave Register(...) as a // TODO stub and fill it in once #649 lands.
Why
All 8 built-in components are currently header-only. Reflection registration needs a translation unit (.cpp file) so the static initializer runs at startup. Without registrations, the inspector's ForEach loop has nothing to display.
Work
Create one .cpp file per component in ZEngine/ZEngine/ECS/Components/. Each file follows the same pattern:
// TransformComponent.cpp
#include <ZEngine/ECS/Components/TransformComponent.h>
#include <ZEngine/ECS/Reflection/ComponentReflectionRegistry.h>
static const ZEngine::ECS::FieldDescriptor kFields[] = {
{ "Position", ZEngine::ECS::FieldType::Vec3f, offsetof(TC, Position), sizeof(Vec3f), .Tooltip="World-space position" },
{ "Rotation", ZEngine::ECS::FieldType::Vec3f, offsetof(TC, Rotation), sizeof(Vec3f), .Tooltip="Euler angles (radians)" },
{ "Scale", ZEngine::ECS::FieldType::Vec3f, offsetof(TC, Scale), sizeof(Vec3f), .Min=0.001f, .Max=1000.f },
{ "PreviousPosition", ZEngine::ECS::FieldType::Vec3f, offsetof(TC, PreviousPosition), sizeof(Vec3f), .Hidden=true },
};
static bool s_reg = [] {
ZEngine::ECS::ComponentReflectionRegistry::Get().Register({
.TypeID=ZEngine::ECS::ComponentTypeOf<TC>(), .TypeName="TransformComponent",
.Size=sizeof(TC), .Align=alignof(TC),
.Fields=kFields, .FieldCount=4, .Category="Transform",
});
return true;
}();
The 8 components and their field mappings
| Component |
Fields |
Notes |
TransformComponent |
Position Rotation Scale (Vec3f), PreviousPosition (Vec3f, Hidden=true) |
Category: "Transform" |
MeshComponent |
MeshUUID (AssetUUID, ReadOnly=true), RenderInstanceId (UInt32, Hidden=true) |
Category: "Rendering" |
CameraComponent |
FovY Near Far AspectRatio (Float), IsMain (Bool) |
Category: "Camera" |
LightComponent |
LightType (Enum: Directional/Point/Spot), Intensity Range SpotAngle (Float), Color (Vec3f mapped as 3×Float) |
Category: "Lighting" |
MaterialComponent |
MaterialUUID (AssetUUID) |
Category: "Rendering" |
NameComponent |
Value (String, StringCap=128) |
Category: "General" |
RigidBodyComponent |
MotionKind (Enum: Static/Kinematic/Dynamic), Mass Friction Restitution (Float), BodyID (UInt32, ReadOnly=true, Hidden=true) |
Category: "Physics" |
UUIDComponent |
Value (String, ReadOnly=true, StringCap=37) — display via uuids::to_string() in the inspector |
Category: "General" |
LightComponent.LightType enum values
static const ZEngine::ECS::EnumValue kLightTypes[] = {
{ "Directional", 0 },
{ "Point", 1 },
{ "Spot", 2 },
};
RigidBodyComponent.MotionKind enum values
static const ZEngine::ECS::EnumValue kMotionTypes[] = {
{ "Static", 0 },
{ "Kinematic", 1 },
{ "Dynamic", 2 },
};
Acceptance criteria
ComponentReflectionRegistry::Get().Count() == 8 after engine startup
- Each component lookable by TypeID and by TypeName string
ForEach visits all 8 in registration order
NameComponent renders as editable text input (StringCap=128)
UUIDComponent.Value is ReadOnly in the inspector
Dependency position
Wait for #648 and #649 to be merged before adding the
Register(...)call.The
.cppfiles andFieldDescriptorarrays can be written while #649 is in review — just leaveRegister(...)as a// TODOstub and fill it in once #649 lands.Why
All 8 built-in components are currently header-only. Reflection registration needs a translation unit (
.cppfile) so the static initializer runs at startup. Without registrations, the inspector'sForEachloop has nothing to display.Work
Create one
.cppfile per component inZEngine/ZEngine/ECS/Components/. Each file follows the same pattern:The 8 components and their field mappings
TransformComponentPositionRotationScale(Vec3f),PreviousPosition(Vec3f, Hidden=true)MeshComponentMeshUUID(AssetUUID, ReadOnly=true),RenderInstanceId(UInt32, Hidden=true)CameraComponentFovYNearFarAspectRatio(Float),IsMain(Bool)LightComponentLightType(Enum: Directional/Point/Spot),IntensityRangeSpotAngle(Float),Color(Vec3f mapped as 3×Float)MaterialComponentMaterialUUID(AssetUUID)NameComponentValue(String, StringCap=128)RigidBodyComponentMotionKind(Enum: Static/Kinematic/Dynamic),MassFrictionRestitution(Float),BodyID(UInt32, ReadOnly=true, Hidden=true)UUIDComponentValue(String, ReadOnly=true, StringCap=37) — display viauuids::to_string()in the inspectorLightComponent.LightTypeenum valuesRigidBodyComponent.MotionKindenum valuesAcceptance criteria
ComponentReflectionRegistry::Get().Count()== 8 after engine startupForEachvisits all 8 in registration orderNameComponentrenders as editable text input (StringCap=128)UUIDComponent.Valueis ReadOnly in the inspector