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() {
Entity.call(this);
this.add(POSITION);
this.add(MESH);
this.add(MATERIAL);
this.position.x = 0;
this.position.y = 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() {
var speed = 3.0;
+2 -1
View File
@@ -3,11 +3,12 @@ var Cube = include('entities/cube.js');
function CubeScene() {
this.cam = new Entity();
this.cam.add(POSITION);
this.cam.add(CAMERA);
this.cam.position.x = 3;
this.cam.position.y = 3;
this.cam.position.z = 3;
this.cam.position.lookAt(0, 0, 0);
this.cam.add(CAMERA);
this.cube = new Cube();
}
+8 -2
View File
@@ -12,8 +12,14 @@
componentdefinition_t COMPONENT_DEFINITIONS[] = {
[COMPONENT_TYPE_NULL] = { 0 },
#define X(enumName, type, field, iMethod, dMethod) \
[COMPONENT_TYPE_##enumName] = { .name = #field, .init = iMethod, .dispose = dMethod },
#define X(enm, type, field, iMethod, dMethod) \
[COMPONENT_TYPE_##enm] = { \
.enumName = #enm, \
.name = #field, \
.init = iMethod, \
.dispose = dMethod \
},
#include "componentlist.h"
#undef X
+1
View File
@@ -20,6 +20,7 @@ typedef union {
} componentdata_t;
typedef struct {
const char_t *enumName;
const char_t *name;
void (*init)(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/physics/entityphysics.h"
// Name (Uppercase)
// Structure
// Field name (lowercase)
// Init function (optional)
// Dispose function (optional)
X(POSITION, entityposition_t, position, entityPositionInit, NULL)
X(CAMERA, entitycamera_t, camera, entityCameraInit, NULL)
X(MESH, entitymesh_t, mesh, entityMeshInit, entityMeshDispose)
+4 -2
View File
@@ -93,8 +93,10 @@ moduleBaseFunction(moduleColorToString) {
&MODULE_COLOR_PROTO, callInfo->this_value
);
if(!color) return jerry_undefined();
char_t buf[32];
stringFormat(buf, sizeof(buf), "[ %d, %d, %d, %d ]",
char_t buf[64];
stringFormat(
buf, sizeof(buf),
"{ \"r\": %d, \"g\": %d, \"b\": %d, \"a\": %d }",
(int32_t)color->r, (int32_t)color->g,
(int32_t)color->b, (int32_t)color->a
);
+14 -2
View File
@@ -44,6 +44,17 @@ moduleBaseFunction(moduleScreenSetBackground) {
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) {
scriptProtoInit(&MODULE_SCREEN_PROTO, "Screen", sizeof(screen_t), NULL);
@@ -54,5 +65,6 @@ static void moduleScreen(void) {
X(aspect, moduleScreenGetAspect, NULL)
X(background, moduleScreenGetBackground, moduleScreenSetBackground)
#undef X
}
scriptProtoDefineToString(&MODULE_SCREEN_PROTO, moduleScreenToString);
}
@@ -61,7 +61,7 @@ moduleBaseFunction(moduleEntityCameraAdd) {
return scriptProtoCreateValue(&MODULE_ENTITY_CAMERA_PROTO, &h);
}
static void moduleEntityCamera(void) {
static void moduleEntityCAMERA(void) {
scriptProtoInit(
&MODULE_ENTITY_CAMERA_PROTO, NULL, sizeof(componenthandle_t), NULL
);
@@ -69,7 +69,7 @@ moduleBaseFunction(moduleEntityMaterialAdd) {
return scriptProtoCreateValue(&MODULE_ENTITY_MATERIAL_PROTO, &h);
}
static void moduleEntityMaterial(void) {
static void moduleEntityMATERIAL(void) {
scriptProtoInit(
&MODULE_ENTITY_MATERIAL_PROTO,
NULL,
@@ -27,6 +27,6 @@ moduleBaseFunction(moduleEntityMeshAdd) {
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);
}
@@ -175,7 +175,7 @@ moduleBaseFunction(moduleEntityPhysicsAdd) {
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);
scriptProtoDefineProp(&MODULE_ENTITY_PHYSICS_PROTO, "velX", moduleEntityPhysicsGetVelX, moduleEntityPhysicsSetVelX);
@@ -232,7 +232,7 @@ moduleBaseFunction(moduleEntityPositionAdd) {
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);
scriptProtoDefineProp(&MODULE_ENTITY_POSITION_PROTO, "x", moduleEntityPositionGetX, moduleEntityPositionSetX);
+86 -69
View File
@@ -22,8 +22,58 @@ typedef struct {
} entityscript_t;
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) {
entityscript_t *inst = (entityscript_t*)memoryAllocate(sizeof(entityscript_t));
inst->id = entityManagerAdd();
@@ -32,43 +82,23 @@ moduleBaseFunction(moduleEntityConstructor) {
}
moduleBaseFunction(moduleEntityAddComponent) {
entityscript_t *inst = (entityscript_t*)scriptProtoGetValue(
&MODULE_ENTITY_PROTO, callInfo->this_value
);
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");
if(argc < 1 || !jerry_value_is_number(args[0])) {
return moduleBaseThrow("Entity.add: expected a valid component type");
}
jerry_value_t typeKey = jerry_string_sz("_type");
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);
componenttype_t type = (componenttype_t)jerry_value_as_number(args[0]);
if(type <= COMPONENT_TYPE_NULL || type >= COMPONENT_TYPE_COUNT) {
return moduleBaseThrow("Entity.add: invalid component type");
}
jerry_external_handler_t addFn = s_componentAddFns[type];
if(!addFn) return moduleBaseThrow("Entity.add: no handler for this component type");
// Get the entity script data.
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);
jerry_value_t handle = addFn(callInfo, &idVal, 1);
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;
componentid_t id = entityAddComponent(inst->id, type);
return jerry_number(id);
}
moduleBaseFunction(moduleEntityDisposeMethod) {
@@ -81,12 +111,7 @@ moduleBaseFunction(moduleEntityDisposeMethod) {
}
static void moduleEntity(void) {
moduleEntityPosition();
moduleEntityCamera();
moduleEntityMesh();
moduleEntityMaterial();
moduleEntityPhysics();
// Init the entity prototype
scriptProtoInit(
&MODULE_ENTITY_PROTO,
"Entity",
@@ -94,40 +119,32 @@ static void moduleEntity(void) {
moduleEntityConstructor
);
scriptProtoDefineFunc(&MODULE_ENTITY_PROTO, "add", moduleEntityAddComponent);
scriptProtoDefineFunc(&MODULE_ENTITY_PROTO, "dispose", moduleEntityDisposeMethod);
// Entity Methods
scriptProtoDefineFunc(
&MODULE_ENTITY_PROTO, "add", moduleEntityAddComponent
);
scriptProtoDefineFunc(
&MODULE_ENTITY_PROTO, "dispose", moduleEntityDisposeMethod
);
// Lookup table: componenttype_t → add handler. Indexed directly, O(1) dispatch.
memoryZero(s_componentAddFns, sizeof(s_componentAddFns));
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;
// Init component type modules.
char_t buffer[64];
// Register component type objects as globals and as Entity.POSITION etc.
// Each object stores _type (numeric componenttype_t) for O(1) dispatch,
// and .name (lowercase field name) matching COMPONENT_DEFINITIONS.
jerry_value_t global = jerry_current_realm();
#define X(enumName, type, field, init, dispose) { \
jerry_value_t ctObj = jerry_object(); \
jerry_value_t tk = jerry_string_sz("_type"); \
jerry_value_t tv = jerry_number((double)COMPONENT_TYPE_##enumName); \
jerry_object_set(ctObj, tk, tv); \
jerry_value_free(tv); jerry_value_free(tk); \
jerry_value_t nk = jerry_string_sz("name"); \
jerry_value_t nv = jerry_string_sz(#field); \
jerry_object_set(ctObj, nk, nv); \
jerry_value_free(nv); jerry_value_free(nk); \
jerry_value_t gk = jerry_string_sz(#enumName); \
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); \
}
#define X(enumName, type, field, iMethod, dMethod) \
moduleEntity##enumName(); \
scriptProtoDefineProp( \
&MODULE_ENTITY_PROTO, \
COMPONENT_DEFINITIONS[COMPONENT_TYPE_##enumName].name, \
moduleEntityGet##enumName, \
NULL \
); \
snprintf( \
buffer, sizeof(buffer), \
"%s = %d\n", \
#enumName, \
COMPONENT_TYPE_##enumName \
); \
moduleBaseEval(buffer);
#include "entity/componentlist.h"
#undef X
jerry_value_free(global);
}