Bit more cleanup

This commit is contained in:
2026-04-30 20:03:44 -05:00
parent 3d984e13c2
commit 2e43aa2c44
13 changed files with 132 additions and 84 deletions
+6 -3
View File
@@ -1,14 +1,17 @@
function CubeEntity() { function CubeEntity() {
Entity.call(this); Entity.call(this);
this.add(POSITION); this.add(POSITION);
this.add(MESH);
this.add(MATERIAL);
this.position.x = 0; this.position.x = 0;
this.position.y = 0; this.position.y = 0;
this.position.z = 0; this.position.z = 0;
this.add(MESH);
this.add(MATERIAL);
} }
Object.assign(CubeEntity.prototype, Entity.prototype); CubeEntity.prototype = Object.create(Entity.prototype);
CubeEntity.prototype.constructor = CubeEntity;
CubeEntity.prototype.update = function() { CubeEntity.prototype.update = function() {
var speed = 3.0; var speed = 3.0;
+2 -1
View File
@@ -3,11 +3,12 @@ var Cube = include('entities/cube.js');
function CubeScene() { function CubeScene() {
this.cam = new Entity(); this.cam = new Entity();
this.cam.add(POSITION); this.cam.add(POSITION);
this.cam.add(CAMERA);
this.cam.position.x = 3; this.cam.position.x = 3;
this.cam.position.y = 3; this.cam.position.y = 3;
this.cam.position.z = 3; this.cam.position.z = 3;
this.cam.position.lookAt(0, 0, 0); this.cam.position.lookAt(0, 0, 0);
this.cam.add(CAMERA);
this.cube = new Cube(); this.cube = new Cube();
} }
+8 -2
View File
@@ -12,8 +12,14 @@
componentdefinition_t COMPONENT_DEFINITIONS[] = { componentdefinition_t COMPONENT_DEFINITIONS[] = {
[COMPONENT_TYPE_NULL] = { 0 }, [COMPONENT_TYPE_NULL] = { 0 },
#define X(enumName, type, field, iMethod, dMethod) \ #define X(enm, type, field, iMethod, dMethod) \
[COMPONENT_TYPE_##enumName] = { .name = #field, .init = iMethod, .dispose = dMethod }, [COMPONENT_TYPE_##enm] = { \
.enumName = #enm, \
.name = #field, \
.init = iMethod, \
.dispose = dMethod \
},
#include "componentlist.h" #include "componentlist.h"
#undef X #undef X
+1
View File
@@ -20,6 +20,7 @@ typedef union {
} componentdata_t; } componentdata_t;
typedef struct { typedef struct {
const char_t *enumName;
const char_t *name; const char_t *name;
void (*init)(const entityid_t, const componentid_t); void (*init)(const entityid_t, const componentid_t);
void (*dispose)(const entityid_t, const componentid_t); void (*dispose)(const entityid_t, const componentid_t);
+6
View File
@@ -11,6 +11,12 @@
#include "entity/component/display/entitymaterial.h" #include "entity/component/display/entitymaterial.h"
#include "entity/component/physics/entityphysics.h" #include "entity/component/physics/entityphysics.h"
// Name (Uppercase)
// Structure
// Field name (lowercase)
// Init function (optional)
// Dispose function (optional)
X(POSITION, entityposition_t, position, entityPositionInit, NULL) X(POSITION, entityposition_t, position, entityPositionInit, NULL)
X(CAMERA, entitycamera_t, camera, entityCameraInit, NULL) X(CAMERA, entitycamera_t, camera, entityCameraInit, NULL)
X(MESH, entitymesh_t, mesh, entityMeshInit, entityMeshDispose) X(MESH, entitymesh_t, mesh, entityMeshInit, entityMeshDispose)
+4 -2
View File
@@ -93,8 +93,10 @@ moduleBaseFunction(moduleColorToString) {
&MODULE_COLOR_PROTO, callInfo->this_value &MODULE_COLOR_PROTO, callInfo->this_value
); );
if(!color) return jerry_undefined(); if(!color) return jerry_undefined();
char_t buf[32]; char_t buf[64];
stringFormat(buf, sizeof(buf), "[ %d, %d, %d, %d ]", stringFormat(
buf, sizeof(buf),
"{ \"r\": %d, \"g\": %d, \"b\": %d, \"a\": %d }",
(int32_t)color->r, (int32_t)color->g, (int32_t)color->r, (int32_t)color->g,
(int32_t)color->b, (int32_t)color->a (int32_t)color->b, (int32_t)color->a
); );
+14 -2
View File
@@ -44,6 +44,17 @@ moduleBaseFunction(moduleScreenSetBackground) {
return jerry_undefined(); return jerry_undefined();
} }
// Functions
moduleBaseFunction(moduleScreenToString) {
char_t buf[128];
stringFormat(
buf, sizeof(buf),
"{ \"width\": %d, \"height\": %d, \"aspect\": %.2f }",
SCREEN.width, SCREEN.height, SCREEN.aspect
);
return jerry_string_sz(buf);
}
static void moduleScreen(void) { static void moduleScreen(void) {
scriptProtoInit(&MODULE_SCREEN_PROTO, "Screen", sizeof(screen_t), NULL); scriptProtoInit(&MODULE_SCREEN_PROTO, "Screen", sizeof(screen_t), NULL);
@@ -54,5 +65,6 @@ static void moduleScreen(void) {
X(aspect, moduleScreenGetAspect, NULL) X(aspect, moduleScreenGetAspect, NULL)
X(background, moduleScreenGetBackground, moduleScreenSetBackground) X(background, moduleScreenGetBackground, moduleScreenSetBackground)
#undef X #undef X
}
scriptProtoDefineToString(&MODULE_SCREEN_PROTO, moduleScreenToString);
}
@@ -61,7 +61,7 @@ moduleBaseFunction(moduleEntityCameraAdd) {
return scriptProtoCreateValue(&MODULE_ENTITY_CAMERA_PROTO, &h); return scriptProtoCreateValue(&MODULE_ENTITY_CAMERA_PROTO, &h);
} }
static void moduleEntityCamera(void) { static void moduleEntityCAMERA(void) {
scriptProtoInit( scriptProtoInit(
&MODULE_ENTITY_CAMERA_PROTO, NULL, sizeof(componenthandle_t), NULL &MODULE_ENTITY_CAMERA_PROTO, NULL, sizeof(componenthandle_t), NULL
); );
@@ -69,7 +69,7 @@ moduleBaseFunction(moduleEntityMaterialAdd) {
return scriptProtoCreateValue(&MODULE_ENTITY_MATERIAL_PROTO, &h); return scriptProtoCreateValue(&MODULE_ENTITY_MATERIAL_PROTO, &h);
} }
static void moduleEntityMaterial(void) { static void moduleEntityMATERIAL(void) {
scriptProtoInit( scriptProtoInit(
&MODULE_ENTITY_MATERIAL_PROTO, &MODULE_ENTITY_MATERIAL_PROTO,
NULL, NULL,
@@ -27,6 +27,6 @@ moduleBaseFunction(moduleEntityMeshAdd) {
return scriptProtoCreateValue(&MODULE_ENTITY_MESH_PROTO, &h); return scriptProtoCreateValue(&MODULE_ENTITY_MESH_PROTO, &h);
} }
static void moduleEntityMesh(void) { static void moduleEntityMESH(void) {
scriptProtoInit(&MODULE_ENTITY_MESH_PROTO, NULL, sizeof(componenthandle_t), NULL); scriptProtoInit(&MODULE_ENTITY_MESH_PROTO, NULL, sizeof(componenthandle_t), NULL);
} }
@@ -175,7 +175,7 @@ moduleBaseFunction(moduleEntityPhysicsAdd) {
return scriptProtoCreateValue(&MODULE_ENTITY_PHYSICS_PROTO, &h); return scriptProtoCreateValue(&MODULE_ENTITY_PHYSICS_PROTO, &h);
} }
static void moduleEntityPhysics(void) { static void moduleEntityPHYSICS(void) {
scriptProtoInit(&MODULE_ENTITY_PHYSICS_PROTO, NULL, sizeof(componenthandle_t), NULL); scriptProtoInit(&MODULE_ENTITY_PHYSICS_PROTO, NULL, sizeof(componenthandle_t), NULL);
scriptProtoDefineProp(&MODULE_ENTITY_PHYSICS_PROTO, "velX", moduleEntityPhysicsGetVelX, moduleEntityPhysicsSetVelX); scriptProtoDefineProp(&MODULE_ENTITY_PHYSICS_PROTO, "velX", moduleEntityPhysicsGetVelX, moduleEntityPhysicsSetVelX);
@@ -232,7 +232,7 @@ moduleBaseFunction(moduleEntityPositionAdd) {
return scriptProtoCreateValue(&MODULE_ENTITY_POSITION_PROTO, &h); return scriptProtoCreateValue(&MODULE_ENTITY_POSITION_PROTO, &h);
} }
static void moduleEntityPosition(void) { static void moduleEntityPOSITION(void) {
scriptProtoInit(&MODULE_ENTITY_POSITION_PROTO, NULL, sizeof(componenthandle_t), NULL); scriptProtoInit(&MODULE_ENTITY_POSITION_PROTO, NULL, sizeof(componenthandle_t), NULL);
scriptProtoDefineProp(&MODULE_ENTITY_POSITION_PROTO, "x", moduleEntityPositionGetX, moduleEntityPositionSetX); scriptProtoDefineProp(&MODULE_ENTITY_POSITION_PROTO, "x", moduleEntityPositionGetX, moduleEntityPositionSetX);
+86 -69
View File
@@ -22,8 +22,58 @@ typedef struct {
} entityscript_t; } entityscript_t;
static scriptproto_t MODULE_ENTITY_PROTO; static scriptproto_t MODULE_ENTITY_PROTO;
static jerry_external_handler_t s_componentAddFns[COMPONENT_TYPE_COUNT];
// Getters
// Getter defined for each component type
static jerry_value_t moduleEntityGetComponent(
const jerry_call_info_t *callInfo,
const jerry_value_t args[],
const jerry_length_t argc,
const componenttype_t type,
scriptproto_t *proto
) {
assertNotNull(callInfo, "Call info must not be null");
assertTrue(argc >= 0, "Argc must be non-negative");
assertTrue(
type > COMPONENT_TYPE_NULL && type < COMPONENT_TYPE_COUNT,
"Invalid component type"
);
entityid_t entityId;
componentid_t compId;
// Get the entity script data.
entityscript_t *inst = (entityscript_t*)scriptProtoGetValue(
&MODULE_ENTITY_PROTO, callInfo->this_value
);
if(!inst) return jerry_undefined();
entityId = inst->id;
// Find the component ID of the requested type.
compId = entityGetComponent(entityId, type);
if(compId == 0xFF) {
return jerry_undefined();
}
componenthandle_t h = { .eid = entityId, .cid = compId };
return scriptProtoCreateValue(proto, &h);
}
#define X(enumName, type, field, init, dispose) \
moduleBaseFunction(moduleEntityGet##enumName) { \
return moduleEntityGetComponent( \
callInfo, \
args, \
argc, \
COMPONENT_TYPE_##enumName, \
&MODULE_ENTITY_##enumName##_PROTO \
); \
}
#include "entity/componentlist.h"
#undef X
// Methods
moduleBaseFunction(moduleEntityConstructor) { moduleBaseFunction(moduleEntityConstructor) {
entityscript_t *inst = (entityscript_t*)memoryAllocate(sizeof(entityscript_t)); entityscript_t *inst = (entityscript_t*)memoryAllocate(sizeof(entityscript_t));
inst->id = entityManagerAdd(); inst->id = entityManagerAdd();
@@ -32,43 +82,23 @@ moduleBaseFunction(moduleEntityConstructor) {
} }
moduleBaseFunction(moduleEntityAddComponent) { moduleBaseFunction(moduleEntityAddComponent) {
entityscript_t *inst = (entityscript_t*)scriptProtoGetValue( if(argc < 1 || !jerry_value_is_number(args[0])) {
&MODULE_ENTITY_PROTO, callInfo->this_value return moduleBaseThrow("Entity.add: expected a valid component type");
);
if(!inst) return moduleBaseThrow("Entity.add: invalid entity");
moduleBaseRequireArgs(1);
if(!jerry_value_is_object(args[0])) {
return moduleBaseThrow("Entity.add: expected a component type object");
} }
jerry_value_t typeKey = jerry_string_sz("_type"); componenttype_t type = (componenttype_t)jerry_value_as_number(args[0]);
jerry_value_t typeVal = jerry_object_get(args[0], typeKey);
jerry_value_free(typeKey);
if(!jerry_value_is_number(typeVal)) {
jerry_value_free(typeVal);
return moduleBaseThrow("Entity.add: expected a component type object");
}
componenttype_t type = (componenttype_t)(int32_t)jerry_value_as_number(typeVal);
jerry_value_free(typeVal);
if(type <= COMPONENT_TYPE_NULL || type >= COMPONENT_TYPE_COUNT) { if(type <= COMPONENT_TYPE_NULL || type >= COMPONENT_TYPE_COUNT) {
return moduleBaseThrow("Entity.add: invalid component type"); return moduleBaseThrow("Entity.add: invalid component type");
} }
jerry_external_handler_t addFn = s_componentAddFns[type]; // Get the entity script data.
if(!addFn) return moduleBaseThrow("Entity.add: no handler for this component type"); entityscript_t *inst = (entityscript_t*)scriptProtoGetValue(
&MODULE_ENTITY_PROTO, callInfo->this_value
);
if(!inst) return moduleBaseThrow("Entity.add: invalid entity");
jerry_value_t idVal = jerry_number((double)inst->id); componentid_t id = entityAddComponent(inst->id, type);
jerry_value_t handle = addFn(callInfo, &idVal, 1); return jerry_number(id);
jerry_value_free(idVal);
jerry_value_t propKey = jerry_string_sz(COMPONENT_DEFINITIONS[type].name);
jerry_object_set(callInfo->this_value, propKey, handle);
jerry_value_free(propKey);
return handle;
} }
moduleBaseFunction(moduleEntityDisposeMethod) { moduleBaseFunction(moduleEntityDisposeMethod) {
@@ -81,12 +111,7 @@ moduleBaseFunction(moduleEntityDisposeMethod) {
} }
static void moduleEntity(void) { static void moduleEntity(void) {
moduleEntityPosition(); // Init the entity prototype
moduleEntityCamera();
moduleEntityMesh();
moduleEntityMaterial();
moduleEntityPhysics();
scriptProtoInit( scriptProtoInit(
&MODULE_ENTITY_PROTO, &MODULE_ENTITY_PROTO,
"Entity", "Entity",
@@ -94,40 +119,32 @@ static void moduleEntity(void) {
moduleEntityConstructor moduleEntityConstructor
); );
scriptProtoDefineFunc(&MODULE_ENTITY_PROTO, "add", moduleEntityAddComponent); // Entity Methods
scriptProtoDefineFunc(&MODULE_ENTITY_PROTO, "dispose", moduleEntityDisposeMethod); scriptProtoDefineFunc(
&MODULE_ENTITY_PROTO, "add", moduleEntityAddComponent
);
scriptProtoDefineFunc(
&MODULE_ENTITY_PROTO, "dispose", moduleEntityDisposeMethod
);
// Lookup table: componenttype_t → add handler. Indexed directly, O(1) dispatch. // Init component type modules.
memoryZero(s_componentAddFns, sizeof(s_componentAddFns)); char_t buffer[64];
s_componentAddFns[COMPONENT_TYPE_POSITION] = moduleEntityPositionAdd;
s_componentAddFns[COMPONENT_TYPE_CAMERA] = moduleEntityCameraAdd;
s_componentAddFns[COMPONENT_TYPE_MESH] = moduleEntityMeshAdd;
s_componentAddFns[COMPONENT_TYPE_MATERIAL] = moduleEntityMaterialAdd;
s_componentAddFns[COMPONENT_TYPE_PHYSICS] = moduleEntityPhysicsAdd;
// Register component type objects as globals and as Entity.POSITION etc. #define X(enumName, type, field, iMethod, dMethod) \
// Each object stores _type (numeric componenttype_t) for O(1) dispatch, moduleEntity##enumName(); \
// and .name (lowercase field name) matching COMPONENT_DEFINITIONS. scriptProtoDefineProp( \
jerry_value_t global = jerry_current_realm(); &MODULE_ENTITY_PROTO, \
#define X(enumName, type, field, init, dispose) { \ COMPONENT_DEFINITIONS[COMPONENT_TYPE_##enumName].name, \
jerry_value_t ctObj = jerry_object(); \ moduleEntityGet##enumName, \
jerry_value_t tk = jerry_string_sz("_type"); \ NULL \
jerry_value_t tv = jerry_number((double)COMPONENT_TYPE_##enumName); \ ); \
jerry_object_set(ctObj, tk, tv); \ snprintf( \
jerry_value_free(tv); jerry_value_free(tk); \ buffer, sizeof(buffer), \
jerry_value_t nk = jerry_string_sz("name"); \ "%s = %d\n", \
jerry_value_t nv = jerry_string_sz(#field); \ #enumName, \
jerry_object_set(ctObj, nk, nv); \ COMPONENT_TYPE_##enumName \
jerry_value_free(nv); jerry_value_free(nk); \ ); \
jerry_value_t gk = jerry_string_sz(#enumName); \ moduleBaseEval(buffer);
jerry_object_set(global, gk, ctObj); \
jerry_value_free(gk); \
jerry_value_t ek = jerry_string_sz(#enumName); \
jerry_object_set(MODULE_ENTITY_PROTO.constructor, ek, ctObj); \
jerry_value_free(ek); \
jerry_value_free(ctObj); \
}
#include "entity/componentlist.h" #include "entity/componentlist.h"
#undef X #undef X
jerry_value_free(global);
} }