Skip to content

feat(ecs): create .cpp files and register reflection metadata for all 8 built-in components #650

Description

@JeanPhilippeKernel

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

Metadata

Metadata

Assignees

Labels

P1Critical path — blocks other workenhancementNew feature or request

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions