Bit more cleanup
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user