From 010900fe21491c556b7dd9e539f87a0b4f614aad Mon Sep 17 00:00:00 2001 From: Dominic Masters Date: Wed, 29 Apr 2026 23:26:21 -0500 Subject: [PATCH] Better again. --- src/dusk/input/input.c | 10 + src/dusk/input/input.h | 16 + .../entity/component/moduleentitycamera.h | 84 ++--- .../entity/component/moduleentitymaterial.h | 51 ++- .../entity/component/moduleentitymesh.h | 57 +--- .../entity/component/moduleentityphysics.h | 152 ++++----- .../entity/component/moduleentityposition.h | 244 +++++--------- src/dusk/script/module/entity/moduleentity.h | 58 ++-- src/dusk/script/module/math/modulemat4.h | 250 +++++--------- src/dusk/script/module/math/modulevec2.h | 252 +++++--------- src/dusk/script/module/math/modulevec3.h | 285 +++++----------- src/dusk/script/module/math/modulevec4.h | 318 ++++++------------ 12 files changed, 622 insertions(+), 1155 deletions(-) diff --git a/src/dusk/input/input.c b/src/dusk/input/input.c index e7fdb267..e2d1b9a4 100644 --- a/src/dusk/input/input.c +++ b/src/dusk/input/input.c @@ -171,6 +171,16 @@ float_t inputAxis(const inputaction_t neg, const inputaction_t pos) { return inputGetCurrentValue(pos) - inputGetCurrentValue(neg); } +void inputAxis2D( + const inputaction_t negX, const inputaction_t posX, + const inputaction_t negY, const inputaction_t posY, + vec2 result +) { + assertNotNull(result, "Result vector cannot be null"); + result[0] = inputAxis(negX, posX); + result[1] = inputAxis(negY, posY); +} + void inputBind(const inputbutton_t button, const inputaction_t act) { assertTrue( act < INPUT_ACTION_COUNT, diff --git a/src/dusk/input/input.h b/src/dusk/input/input.h index c597321c..a6013fe3 100644 --- a/src/dusk/input/input.h +++ b/src/dusk/input/input.h @@ -120,6 +120,22 @@ bool_t inputReleased(const inputaction_t action); */ float_t inputAxis(const inputaction_t neg, const inputaction_t pos); +/** + * Gets the values of a 2D input axis, defined by two pairs of actions (negative + * and positive for each axis). + * + * @param negX The action representing the negative direction of the X axis. + * @param posX The action representing the positive direction of the X axis. + * @param negY The action representing the negative direction of the Y axis. + * @param posY The action representing the positive direction of the Y axis. + * @param result A vec2 to store the resulting axis values (-1.0f to 1.0f). + */ +void inputAxis2D( + const inputaction_t negX, const inputaction_t posX, + const inputaction_t negY, const inputaction_t posY, + vec2 result +); + /** * Binds an input button to an action. * diff --git a/src/dusk/script/module/entity/component/moduleentitycamera.h b/src/dusk/script/module/entity/component/moduleentitycamera.h index bf8e5185..50c9e75a 100644 --- a/src/dusk/script/module/entity/component/moduleentitycamera.h +++ b/src/dusk/script/module/entity/component/moduleentitycamera.h @@ -7,69 +7,71 @@ #pragma once #include "script/module/modulebase.h" +#include "script/scriptproto.h" #include "entity/entity.h" #include "entity/component/display/entitycamera.h" #include "moduleentityposition.h" -// ---- camera prototype ---- - -static jerry_value_t s_camProto = 0; - -// -- zNear getter/setter -- +static scriptproto_t MODULE_ENTITY_CAMERA_PROTO; +// Getters moduleBaseFunction(moduleEntityCameraGetZNear) { - entityid_t eid = getEntityId(callInfo->this_value); - componentid_t cid = getCompId(callInfo->this_value); - return jerry_number((double)entityCameraGetZNear(eid, cid)); + componenthandle_t *h = scriptProtoGetValue( + &MODULE_ENTITY_CAMERA_PROTO, callInfo->this_value + ); + if(!h) return jerry_undefined(); + return jerry_number((double)entityCameraGetZNear(h->eid, h->cid)); } -moduleBaseFunction(moduleEntityCameraSetZNear) { - moduleBaseRequireArgs(1); moduleBaseRequireNumber(0); - entityid_t eid = getEntityId(callInfo->this_value); - componentid_t cid = getCompId(callInfo->this_value); - entityCameraSetZNear(eid, cid, (float_t)jerry_value_as_number(args[0])); - return jerry_undefined(); -} - -// -- zFar getter/setter -- - moduleBaseFunction(moduleEntityCameraGetZFar) { - entityid_t eid = getEntityId(callInfo->this_value); - componentid_t cid = getCompId(callInfo->this_value); - return jerry_number((double)entityCameraGetZFar(eid, cid)); + componenthandle_t *h = scriptProtoGetValue( + &MODULE_ENTITY_CAMERA_PROTO, callInfo->this_value + ); + if(!h) return jerry_undefined(); + return jerry_number((double)entityCameraGetZFar(h->eid, h->cid)); +} + +// Setters +moduleBaseFunction(moduleEntityCameraSetZNear) { + moduleBaseRequireArgs(1); moduleBaseRequireNumber(0); + componenthandle_t *h = scriptProtoGetValue( + &MODULE_ENTITY_CAMERA_PROTO, callInfo->this_value + ); + if(!h) return jerry_undefined(); + entityCameraSetZNear(h->eid, h->cid, (float_t)jerry_value_as_number(args[0])); + return jerry_undefined(); } moduleBaseFunction(moduleEntityCameraSetZFar) { moduleBaseRequireArgs(1); moduleBaseRequireNumber(0); - entityid_t eid = getEntityId(callInfo->this_value); - componentid_t cid = getCompId(callInfo->this_value); - entityCameraSetZFar(eid, cid, (float_t)jerry_value_as_number(args[0])); + componenthandle_t *h = scriptProtoGetValue( + &MODULE_ENTITY_CAMERA_PROTO, callInfo->this_value + ); + if(!h) return jerry_undefined(); + entityCameraSetZFar(h->eid, h->cid, (float_t)jerry_value_as_number(args[0])); return jerry_undefined(); } -// -- add function -- - -/** - * Adds a camera component to an entity and returns a handle object. - * Arg 0: entity id (number). - */ +// Adder for this component. moduleBaseFunction(moduleEntityCameraAdd) { moduleBaseRequireArgs(1); moduleBaseRequireNumber(0); entityid_t id = (entityid_t)jerry_value_as_number(args[0]); componentid_t comp = entityAddComponent(id, COMPONENT_TYPE_CAMERA); - jerry_value_t handle = makeEntityHandle(id, comp); - if(s_camProto != 0) jerry_object_set_proto(handle, s_camProto); - return handle; + componenthandle_t h = { .eid = id, .cid = comp }; + return scriptProtoCreateValue(&MODULE_ENTITY_CAMERA_PROTO, &h); } -/** - * Registers the camera component prototype and entityCameraAdd global. - */ static void moduleEntityCamera(void) { - s_camProto = jerry_object(); + scriptProtoInit( + &MODULE_ENTITY_CAMERA_PROTO, NULL, sizeof(componenthandle_t), NULL + ); - moduleBaseDefineProperty(s_camProto, "zNear", moduleEntityCameraGetZNear, moduleEntityCameraSetZNear); - moduleBaseDefineProperty(s_camProto, "zFar", moduleEntityCameraGetZFar, moduleEntityCameraSetZFar); - - moduleBaseFunctionRegister("entityCameraAdd", moduleEntityCameraAdd); + scriptProtoDefineProp( + &MODULE_ENTITY_CAMERA_PROTO, "zNear", + moduleEntityCameraGetZNear, moduleEntityCameraSetZNear + ); + scriptProtoDefineProp( + &MODULE_ENTITY_CAMERA_PROTO, "zFar", + moduleEntityCameraGetZFar, moduleEntityCameraSetZFar + ); } diff --git a/src/dusk/script/module/entity/component/moduleentitymaterial.h b/src/dusk/script/module/entity/component/moduleentitymaterial.h index 2a5d91a1..38ffd8ab 100644 --- a/src/dusk/script/module/entity/component/moduleentitymaterial.h +++ b/src/dusk/script/module/entity/component/moduleentitymaterial.h @@ -7,29 +7,26 @@ #pragma once #include "script/module/modulebase.h" +#include "script/scriptproto.h" #include "entity/entity.h" #include "entity/component/display/entitymaterial.h" #include "display/color.h" #include "moduleentityposition.h" -// ---- material prototype ---- +static scriptproto_t MODULE_ENTITY_MATERIAL_PROTO; -static jerry_value_t s_matProto = 0; +// Getters -// -- methods -- - -/** - * Sets the material's unlit color from a color object with r, g, b, a - * properties (each a number 0-255). - * Args: colorObj (object). - */ +// Setters moduleBaseFunction(moduleEntityMaterialSetColor) { moduleBaseRequireArgs(1); if(!jerry_value_is_object(args[0])) { return moduleBaseThrow("expected color object"); } - entityid_t eid = getEntityId(callInfo->this_value); - componentid_t cid = getCompId(callInfo->this_value); + componenthandle_t *h = scriptProtoGetValue( + &MODULE_ENTITY_MATERIAL_PROTO, callInfo->this_value + ); + if(!h) return jerry_undefined(); jerry_value_t key; jerry_value_t v; @@ -59,32 +56,30 @@ moduleBaseFunction(moduleEntityMaterialSetColor) { col.a = (colorchannel8_t)jerry_value_as_number(v); jerry_value_free(v); - entityMaterialSetColor(eid, cid, col); + entityMaterialSetColor(h->eid, h->cid, col); return jerry_undefined(); } -// -- add function -- - -/** - * Adds a material component to an entity and returns a handle object. - * Arg 0: entity id (number). - */ +// Component add method moduleBaseFunction(moduleEntityMaterialAdd) { moduleBaseRequireArgs(1); moduleBaseRequireNumber(0); entityid_t id = (entityid_t)jerry_value_as_number(args[0]); componentid_t comp = entityAddComponent(id, COMPONENT_TYPE_MATERIAL); - jerry_value_t handle = makeEntityHandle(id, comp); - if(s_matProto != 0) jerry_object_set_proto(handle, s_matProto); - return handle; + componenthandle_t h = { .eid = id, .cid = comp }; + return scriptProtoCreateValue(&MODULE_ENTITY_MATERIAL_PROTO, &h); } -/** - * Registers the material component prototype and entityMaterialAdd global. - */ static void moduleEntityMaterial(void) { - s_matProto = jerry_object(); + scriptProtoInit( + &MODULE_ENTITY_MATERIAL_PROTO, + NULL, + sizeof(componenthandle_t), + NULL + ); - moduleBaseDefineMethod(s_matProto, "setColor", moduleEntityMaterialSetColor); - - moduleBaseFunctionRegister("entityMaterialAdd", moduleEntityMaterialAdd); + scriptProtoDefineFunc( + &MODULE_ENTITY_MATERIAL_PROTO, + "setColor", + moduleEntityMaterialSetColor + ); } diff --git a/src/dusk/script/module/entity/component/moduleentitymesh.h b/src/dusk/script/module/entity/component/moduleentitymesh.h index add666a6..c824883b 100644 --- a/src/dusk/script/module/entity/component/moduleentitymesh.h +++ b/src/dusk/script/module/entity/component/moduleentitymesh.h @@ -7,67 +7,26 @@ #pragma once #include "script/module/modulebase.h" +#include "script/scriptproto.h" #include "entity/entity.h" #include "entity/component/display/entitymesh.h" #include "moduleentityposition.h" -// ---- mesh prototype ---- +static scriptproto_t MODULE_ENTITY_MESH_PROTO; -static jerry_value_t s_meshProto = 0; +// Getters -// -- methods -- +// Setters -/** - * Generates an XZ-aligned plane mesh owned by this component. - * Args: width (number), depth (number). - */ -moduleBaseFunction(moduleEntityMeshGeneratePlane) { - moduleBaseRequireArgs(2); - entityid_t eid = getEntityId(callInfo->this_value); - componentid_t cid = getCompId(callInfo->this_value); - float_t w = (float_t)jerry_value_as_number(args[0]); - float_t d = (float_t)jerry_value_as_number(args[1]); - entityMeshGeneratePlane(eid, cid, w, d); - return jerry_undefined(); -} - -/** - * Generates a Y-axis capsule mesh owned by this component. - * Args: radius (number), halfHeight (number). - */ -moduleBaseFunction(moduleEntityMeshGenerateCapsule) { - moduleBaseRequireArgs(2); - entityid_t eid = getEntityId(callInfo->this_value); - componentid_t cid = getCompId(callInfo->this_value); - float_t r = (float_t)jerry_value_as_number(args[0]); - float_t hh = (float_t)jerry_value_as_number(args[1]); - entityMeshGenerateCapsule(eid, cid, r, hh); - return jerry_undefined(); -} - -// -- add function -- - -/** - * Adds a mesh component to an entity and returns a handle object. - * Arg 0: entity id (number). - */ +// Component add moduleBaseFunction(moduleEntityMeshAdd) { moduleBaseRequireArgs(1); moduleBaseRequireNumber(0); entityid_t id = (entityid_t)jerry_value_as_number(args[0]); componentid_t comp = entityAddComponent(id, COMPONENT_TYPE_MESH); - jerry_value_t handle = makeEntityHandle(id, comp); - if(s_meshProto != 0) jerry_object_set_proto(handle, s_meshProto); - return handle; + componenthandle_t h = { .eid = id, .cid = comp }; + return scriptProtoCreateValue(&MODULE_ENTITY_MESH_PROTO, &h); } -/** - * Registers the mesh component prototype and entityMeshAdd global. - */ static void moduleEntityMesh(void) { - s_meshProto = jerry_object(); - - moduleBaseDefineMethod(s_meshProto, "generatePlane", moduleEntityMeshGeneratePlane); - moduleBaseDefineMethod(s_meshProto, "generateCapsule", moduleEntityMeshGenerateCapsule); - - moduleBaseFunctionRegister("entityMeshAdd", moduleEntityMeshAdd); + scriptProtoInit(&MODULE_ENTITY_MESH_PROTO, NULL, sizeof(componenthandle_t), NULL); } diff --git a/src/dusk/script/module/entity/component/moduleentityphysics.h b/src/dusk/script/module/entity/component/moduleentityphysics.h index fc61cc93..ce5a45d6 100644 --- a/src/dusk/script/module/entity/component/moduleentityphysics.h +++ b/src/dusk/script/module/entity/component/moduleentityphysics.h @@ -7,95 +7,94 @@ #pragma once #include "script/module/modulebase.h" +#include "script/scriptproto.h" #include "entity/entity.h" #include "entity/component/physics/entityphysics.h" #include "moduleentityposition.h" -// ---- physics prototype ---- - -static jerry_value_t s_physProto = 0; +static scriptproto_t MODULE_ENTITY_PHYSICS_PROTO; // -- velocity getters/setters -- moduleBaseFunction(moduleEntityPhysicsGetVelX) { - entityid_t eid = getEntityId(callInfo->this_value); - componentid_t cid = getCompId(callInfo->this_value); + componenthandle_t *h = scriptProtoGetValue(&MODULE_ENTITY_PHYSICS_PROTO, callInfo->this_value); + if(!h) return jerry_undefined(); vec3 v; - entityPhysicsGetVelocity(eid, cid, v); + entityPhysicsGetVelocity(h->eid, h->cid, v); return jerry_number(v[0]); } moduleBaseFunction(moduleEntityPhysicsSetVelX) { moduleBaseRequireArgs(1); moduleBaseRequireNumber(0); - entityid_t eid = getEntityId(callInfo->this_value); - componentid_t cid = getCompId(callInfo->this_value); + componenthandle_t *h = scriptProtoGetValue(&MODULE_ENTITY_PHYSICS_PROTO, callInfo->this_value); + if(!h) return jerry_undefined(); vec3 v; - entityPhysicsGetVelocity(eid, cid, v); + entityPhysicsGetVelocity(h->eid, h->cid, v); v[0] = (float_t)jerry_value_as_number(args[0]); - entityPhysicsSetVelocity(eid, cid, v); + entityPhysicsSetVelocity(h->eid, h->cid, v); return jerry_undefined(); } moduleBaseFunction(moduleEntityPhysicsGetVelY) { - entityid_t eid = getEntityId(callInfo->this_value); - componentid_t cid = getCompId(callInfo->this_value); + componenthandle_t *h = scriptProtoGetValue(&MODULE_ENTITY_PHYSICS_PROTO, callInfo->this_value); + if(!h) return jerry_undefined(); vec3 v; - entityPhysicsGetVelocity(eid, cid, v); + entityPhysicsGetVelocity(h->eid, h->cid, v); return jerry_number(v[1]); } moduleBaseFunction(moduleEntityPhysicsSetVelY) { moduleBaseRequireArgs(1); moduleBaseRequireNumber(0); - entityid_t eid = getEntityId(callInfo->this_value); - componentid_t cid = getCompId(callInfo->this_value); + componenthandle_t *h = scriptProtoGetValue(&MODULE_ENTITY_PHYSICS_PROTO, callInfo->this_value); + if(!h) return jerry_undefined(); vec3 v; - entityPhysicsGetVelocity(eid, cid, v); + entityPhysicsGetVelocity(h->eid, h->cid, v); v[1] = (float_t)jerry_value_as_number(args[0]); - entityPhysicsSetVelocity(eid, cid, v); + entityPhysicsSetVelocity(h->eid, h->cid, v); return jerry_undefined(); } moduleBaseFunction(moduleEntityPhysicsGetVelZ) { - entityid_t eid = getEntityId(callInfo->this_value); - componentid_t cid = getCompId(callInfo->this_value); + componenthandle_t *h = scriptProtoGetValue(&MODULE_ENTITY_PHYSICS_PROTO, callInfo->this_value); + if(!h) return jerry_undefined(); vec3 v; - entityPhysicsGetVelocity(eid, cid, v); + entityPhysicsGetVelocity(h->eid, h->cid, v); return jerry_number(v[2]); } moduleBaseFunction(moduleEntityPhysicsSetVelZ) { moduleBaseRequireArgs(1); moduleBaseRequireNumber(0); - entityid_t eid = getEntityId(callInfo->this_value); - componentid_t cid = getCompId(callInfo->this_value); + componenthandle_t *h = scriptProtoGetValue(&MODULE_ENTITY_PHYSICS_PROTO, callInfo->this_value); + if(!h) return jerry_undefined(); vec3 v; - entityPhysicsGetVelocity(eid, cid, v); + entityPhysicsGetVelocity(h->eid, h->cid, v); v[2] = (float_t)jerry_value_as_number(args[0]); - entityPhysicsSetVelocity(eid, cid, v); + entityPhysicsSetVelocity(h->eid, h->cid, v); return jerry_undefined(); } // -- onGround getter (read-only) -- moduleBaseFunction(moduleEntityPhysicsGetOnGround) { - entityid_t eid = getEntityId(callInfo->this_value); - componentid_t cid = getCompId(callInfo->this_value); - return jerry_boolean(entityPhysicsIsOnGround(eid, cid)); + componenthandle_t *h = scriptProtoGetValue(&MODULE_ENTITY_PHYSICS_PROTO, callInfo->this_value); + if(!h) return jerry_undefined(); + return jerry_boolean(entityPhysicsIsOnGround(h->eid, h->cid)); } // -- bodyType getter/setter -- moduleBaseFunction(moduleEntityPhysicsGetBodyType) { - entityid_t eid = getEntityId(callInfo->this_value); - componentid_t cid = getCompId(callInfo->this_value); - return jerry_number((double)entityPhysicsGetBodyType(eid, cid)); + componenthandle_t *h = scriptProtoGetValue(&MODULE_ENTITY_PHYSICS_PROTO, callInfo->this_value); + if(!h) return jerry_undefined(); + return jerry_number((double)entityPhysicsGetBodyType(h->eid, h->cid)); } moduleBaseFunction(moduleEntityPhysicsSetBodyType) { moduleBaseRequireArgs(1); moduleBaseRequireNumber(0); - entityid_t eid = getEntityId(callInfo->this_value); - componentid_t cid = getCompId(callInfo->this_value); + componenthandle_t *h = scriptProtoGetValue(&MODULE_ENTITY_PHYSICS_PROTO, callInfo->this_value); + if(!h) return jerry_undefined(); entityPhysicsSetBodyType( - eid, cid, + h->eid, h->cid, (physicsbodytype_t)(int32_t)jerry_value_as_number(args[0]) ); return jerry_undefined(); @@ -103,124 +102,93 @@ moduleBaseFunction(moduleEntityPhysicsSetBodyType) { // -- methods -- -/** - * Applies an immediate velocity impulse to the physics body. - * Args: x, y, z (numbers). - */ moduleBaseFunction(moduleEntityPhysicsApplyImpulse) { moduleBaseRequireArgs(3); - entityid_t eid = getEntityId(callInfo->this_value); - componentid_t cid = getCompId(callInfo->this_value); + componenthandle_t *h = scriptProtoGetValue(&MODULE_ENTITY_PHYSICS_PROTO, callInfo->this_value); + if(!h) return jerry_undefined(); vec3 impulse = { (float_t)jerry_value_as_number(args[0]), (float_t)jerry_value_as_number(args[1]), (float_t)jerry_value_as_number(args[2]) }; - entityPhysicsApplyImpulse(eid, cid, impulse); + entityPhysicsApplyImpulse(h->eid, h->cid, impulse); return jerry_undefined(); } -/** - * Sets the physics shape to an axis-aligned box. - * Args: halfX, halfY, halfZ (numbers). - */ moduleBaseFunction(moduleEntityPhysicsSetShapeCube) { moduleBaseRequireArgs(3); - entityid_t eid = getEntityId(callInfo->this_value); - componentid_t cid = getCompId(callInfo->this_value); + componenthandle_t *h = scriptProtoGetValue(&MODULE_ENTITY_PHYSICS_PROTO, callInfo->this_value); + if(!h) return jerry_undefined(); physicsshape_t shape; shape.type = PHYSICS_SHAPE_CUBE; shape.data.cube.halfExtents[0] = (float_t)jerry_value_as_number(args[0]); shape.data.cube.halfExtents[1] = (float_t)jerry_value_as_number(args[1]); shape.data.cube.halfExtents[2] = (float_t)jerry_value_as_number(args[2]); - entityPhysicsSetShape(eid, cid, shape); + entityPhysicsSetShape(h->eid, h->cid, shape); return jerry_undefined(); } -/** - * Sets the physics shape to a sphere. - * Args: radius (number). - */ moduleBaseFunction(moduleEntityPhysicsSetShapeSphere) { moduleBaseRequireArgs(1); - entityid_t eid = getEntityId(callInfo->this_value); - componentid_t cid = getCompId(callInfo->this_value); + componenthandle_t *h = scriptProtoGetValue(&MODULE_ENTITY_PHYSICS_PROTO, callInfo->this_value); + if(!h) return jerry_undefined(); physicsshape_t shape; shape.type = PHYSICS_SHAPE_SPHERE; shape.data.sphere.radius = (float_t)jerry_value_as_number(args[0]); - entityPhysicsSetShape(eid, cid, shape); + entityPhysicsSetShape(h->eid, h->cid, shape); return jerry_undefined(); } -/** - * Sets the physics shape to a Y-axis capsule. - * Args: radius (number), halfHeight (number). - */ moduleBaseFunction(moduleEntityPhysicsSetShapeCapsule) { moduleBaseRequireArgs(2); - entityid_t eid = getEntityId(callInfo->this_value); - componentid_t cid = getCompId(callInfo->this_value); + componenthandle_t *h = scriptProtoGetValue(&MODULE_ENTITY_PHYSICS_PROTO, callInfo->this_value); + if(!h) return jerry_undefined(); physicsshape_t shape; shape.type = PHYSICS_SHAPE_CAPSULE; shape.data.capsule.radius = (float_t)jerry_value_as_number(args[0]); shape.data.capsule.halfHeight = (float_t)jerry_value_as_number(args[1]); - entityPhysicsSetShape(eid, cid, shape); + entityPhysicsSetShape(h->eid, h->cid, shape); return jerry_undefined(); } -/** - * Sets the physics shape to an infinite plane. - * Args: normalX, normalY, normalZ, distance (numbers). - */ moduleBaseFunction(moduleEntityPhysicsSetShapePlane) { moduleBaseRequireArgs(4); - entityid_t eid = getEntityId(callInfo->this_value); - componentid_t cid = getCompId(callInfo->this_value); + componenthandle_t *h = scriptProtoGetValue(&MODULE_ENTITY_PHYSICS_PROTO, callInfo->this_value); + if(!h) return jerry_undefined(); physicsshape_t shape; shape.type = PHYSICS_SHAPE_PLANE; shape.data.plane.normal[0] = (float_t)jerry_value_as_number(args[0]); shape.data.plane.normal[1] = (float_t)jerry_value_as_number(args[1]); shape.data.plane.normal[2] = (float_t)jerry_value_as_number(args[2]); shape.data.plane.distance = (float_t)jerry_value_as_number(args[3]); - entityPhysicsSetShape(eid, cid, shape); + entityPhysicsSetShape(h->eid, h->cid, shape); return jerry_undefined(); } // -- add function -- -/** - * Adds a physics component to an entity and returns a handle object. - * Arg 0: entity id (number). - */ moduleBaseFunction(moduleEntityPhysicsAdd) { moduleBaseRequireArgs(1); moduleBaseRequireNumber(0); entityid_t id = (entityid_t)jerry_value_as_number(args[0]); componentid_t comp = entityAddComponent(id, COMPONENT_TYPE_PHYSICS); - jerry_value_t handle = makeEntityHandle(id, comp); - if(s_physProto != 0) jerry_object_set_proto(handle, s_physProto); - return handle; + componenthandle_t h = { .eid = id, .cid = comp }; + return scriptProtoCreateValue(&MODULE_ENTITY_PHYSICS_PROTO, &h); } -/** - * Registers the physics component prototype, entityPhysicsAdd global, - * and PHYSICS_BODY_* / PHYSICS_SHAPE_* integer constants. - */ static void moduleEntityPhysics(void) { - s_physProto = jerry_object(); + scriptProtoInit(&MODULE_ENTITY_PHYSICS_PROTO, NULL, sizeof(componenthandle_t), NULL); - moduleBaseDefineProperty(s_physProto, "velX", moduleEntityPhysicsGetVelX, moduleEntityPhysicsSetVelX); - moduleBaseDefineProperty(s_physProto, "velY", moduleEntityPhysicsGetVelY, moduleEntityPhysicsSetVelY); - moduleBaseDefineProperty(s_physProto, "velZ", moduleEntityPhysicsGetVelZ, moduleEntityPhysicsSetVelZ); - moduleBaseDefineProperty(s_physProto, "onGround", moduleEntityPhysicsGetOnGround, NULL); - moduleBaseDefineProperty(s_physProto, "bodyType", moduleEntityPhysicsGetBodyType, moduleEntityPhysicsSetBodyType); + scriptProtoDefineProp(&MODULE_ENTITY_PHYSICS_PROTO, "velX", moduleEntityPhysicsGetVelX, moduleEntityPhysicsSetVelX); + scriptProtoDefineProp(&MODULE_ENTITY_PHYSICS_PROTO, "velY", moduleEntityPhysicsGetVelY, moduleEntityPhysicsSetVelY); + scriptProtoDefineProp(&MODULE_ENTITY_PHYSICS_PROTO, "velZ", moduleEntityPhysicsGetVelZ, moduleEntityPhysicsSetVelZ); + scriptProtoDefineProp(&MODULE_ENTITY_PHYSICS_PROTO, "onGround", moduleEntityPhysicsGetOnGround, NULL); + scriptProtoDefineProp(&MODULE_ENTITY_PHYSICS_PROTO, "bodyType", moduleEntityPhysicsGetBodyType, moduleEntityPhysicsSetBodyType); - moduleBaseDefineMethod(s_physProto, "applyImpulse", moduleEntityPhysicsApplyImpulse); - moduleBaseDefineMethod(s_physProto, "setShapeCube", moduleEntityPhysicsSetShapeCube); - moduleBaseDefineMethod(s_physProto, "setShapeSphere", moduleEntityPhysicsSetShapeSphere); - moduleBaseDefineMethod(s_physProto, "setShapeCapsule", moduleEntityPhysicsSetShapeCapsule); - moduleBaseDefineMethod(s_physProto, "setShapePlane", moduleEntityPhysicsSetShapePlane); - - moduleBaseFunctionRegister("entityPhysicsAdd", moduleEntityPhysicsAdd); + scriptProtoDefineFunc(&MODULE_ENTITY_PHYSICS_PROTO, "applyImpulse", moduleEntityPhysicsApplyImpulse); + scriptProtoDefineFunc(&MODULE_ENTITY_PHYSICS_PROTO, "setShapeCube", moduleEntityPhysicsSetShapeCube); + scriptProtoDefineFunc(&MODULE_ENTITY_PHYSICS_PROTO, "setShapeSphere", moduleEntityPhysicsSetShapeSphere); + scriptProtoDefineFunc(&MODULE_ENTITY_PHYSICS_PROTO, "setShapeCapsule", moduleEntityPhysicsSetShapeCapsule); + scriptProtoDefineFunc(&MODULE_ENTITY_PHYSICS_PROTO, "setShapePlane", moduleEntityPhysicsSetShapePlane); moduleBaseSetInt("PHYSICS_BODY_STATIC", PHYSICS_BODY_STATIC); moduleBaseSetInt("PHYSICS_BODY_DYNAMIC", PHYSICS_BODY_DYNAMIC); diff --git a/src/dusk/script/module/entity/component/moduleentityposition.h b/src/dusk/script/module/entity/component/moduleentityposition.h index 862a891f..051cf433 100644 --- a/src/dusk/script/module/entity/component/moduleentityposition.h +++ b/src/dusk/script/module/entity/component/moduleentityposition.h @@ -7,258 +7,204 @@ #pragma once #include "script/module/modulebase.h" +#include "script/scriptproto.h" #include "entity/entity.h" #include "entity/component/display/entityposition.h" -// ---- shared entity handle helpers (included once via this file) ---- +// Shared component handle struct — defined once, used by all component modules. +#ifndef COMPONENT_HANDLE_DEFINED +#define COMPONENT_HANDLE_DEFINED +typedef struct { + entityid_t eid; + componentid_t cid; +} componenthandle_t; +#endif -#ifndef ENTITY_HANDLE_HELPERS -#define ENTITY_HANDLE_HELPERS - -/** - * Create a plain JS object carrying _eid and _cid number properties. - * The caller is responsible for freeing the returned value. - */ -static inline jerry_value_t makeEntityHandle( - entityid_t eid, - componentid_t cid -) { - jerry_value_t obj = jerry_object(); - jerry_value_t key; - jerry_value_t val; - - key = jerry_string_sz("_eid"); - val = jerry_number((double)eid); - jerry_object_set(obj, key, val); - jerry_value_free(val); - jerry_value_free(key); - - key = jerry_string_sz("_cid"); - val = jerry_number((double)cid); - jerry_object_set(obj, key, val); - jerry_value_free(val); - jerry_value_free(key); - - return obj; -} - -/** - * Extract the entity ID stored in a handle object's _eid property. - */ -static inline entityid_t getEntityId(jerry_value_t handle) { - jerry_value_t key = jerry_string_sz("_eid"); - jerry_value_t val = jerry_object_get(handle, key); - jerry_value_free(key); - entityid_t id = (entityid_t)jerry_value_as_number(val); - jerry_value_free(val); - return id; -} - -/** - * Extract the component ID stored in a handle object's _cid property. - */ -static inline componentid_t getCompId(jerry_value_t handle) { - jerry_value_t key = jerry_string_sz("_cid"); - jerry_value_t val = jerry_object_get(handle, key); - jerry_value_free(key); - componentid_t id = (componentid_t)jerry_value_as_number(val); - jerry_value_free(val); - return id; -} - -#endif /* ENTITY_HANDLE_HELPERS */ - -// ---- position prototype ---- - -static jerry_value_t s_posProto = 0; +static scriptproto_t MODULE_ENTITY_POSITION_PROTO; // -- position getters/setters -- moduleBaseFunction(moduleEntityPositionGetX) { - entityid_t eid = getEntityId(callInfo->this_value); - componentid_t cid = getCompId(callInfo->this_value); + componenthandle_t *h = scriptProtoGetValue(&MODULE_ENTITY_POSITION_PROTO, callInfo->this_value); + if(!h) return jerry_undefined(); vec3 v; - entityPositionGetPosition(eid, cid, v); + entityPositionGetPosition(h->eid, h->cid, v); return jerry_number(v[0]); } moduleBaseFunction(moduleEntityPositionSetX) { moduleBaseRequireArgs(1); moduleBaseRequireNumber(0); - entityid_t eid = getEntityId(callInfo->this_value); - componentid_t cid = getCompId(callInfo->this_value); + componenthandle_t *h = scriptProtoGetValue(&MODULE_ENTITY_POSITION_PROTO, callInfo->this_value); + if(!h) return jerry_undefined(); vec3 v; - entityPositionGetPosition(eid, cid, v); + entityPositionGetPosition(h->eid, h->cid, v); v[0] = (float_t)jerry_value_as_number(args[0]); - entityPositionSetPosition(eid, cid, v); + entityPositionSetPosition(h->eid, h->cid, v); return jerry_undefined(); } moduleBaseFunction(moduleEntityPositionGetY) { - entityid_t eid = getEntityId(callInfo->this_value); - componentid_t cid = getCompId(callInfo->this_value); + componenthandle_t *h = scriptProtoGetValue(&MODULE_ENTITY_POSITION_PROTO, callInfo->this_value); + if(!h) return jerry_undefined(); vec3 v; - entityPositionGetPosition(eid, cid, v); + entityPositionGetPosition(h->eid, h->cid, v); return jerry_number(v[1]); } moduleBaseFunction(moduleEntityPositionSetY) { moduleBaseRequireArgs(1); moduleBaseRequireNumber(0); - entityid_t eid = getEntityId(callInfo->this_value); - componentid_t cid = getCompId(callInfo->this_value); + componenthandle_t *h = scriptProtoGetValue(&MODULE_ENTITY_POSITION_PROTO, callInfo->this_value); + if(!h) return jerry_undefined(); vec3 v; - entityPositionGetPosition(eid, cid, v); + entityPositionGetPosition(h->eid, h->cid, v); v[1] = (float_t)jerry_value_as_number(args[0]); - entityPositionSetPosition(eid, cid, v); + entityPositionSetPosition(h->eid, h->cid, v); return jerry_undefined(); } moduleBaseFunction(moduleEntityPositionGetZ) { - entityid_t eid = getEntityId(callInfo->this_value); - componentid_t cid = getCompId(callInfo->this_value); + componenthandle_t *h = scriptProtoGetValue(&MODULE_ENTITY_POSITION_PROTO, callInfo->this_value); + if(!h) return jerry_undefined(); vec3 v; - entityPositionGetPosition(eid, cid, v); + entityPositionGetPosition(h->eid, h->cid, v); return jerry_number(v[2]); } moduleBaseFunction(moduleEntityPositionSetZ) { moduleBaseRequireArgs(1); moduleBaseRequireNumber(0); - entityid_t eid = getEntityId(callInfo->this_value); - componentid_t cid = getCompId(callInfo->this_value); + componenthandle_t *h = scriptProtoGetValue(&MODULE_ENTITY_POSITION_PROTO, callInfo->this_value); + if(!h) return jerry_undefined(); vec3 v; - entityPositionGetPosition(eid, cid, v); + entityPositionGetPosition(h->eid, h->cid, v); v[2] = (float_t)jerry_value_as_number(args[0]); - entityPositionSetPosition(eid, cid, v); + entityPositionSetPosition(h->eid, h->cid, v); return jerry_undefined(); } // -- rotation getters/setters -- moduleBaseFunction(moduleEntityPositionGetRotX) { - entityid_t eid = getEntityId(callInfo->this_value); - componentid_t cid = getCompId(callInfo->this_value); + componenthandle_t *h = scriptProtoGetValue(&MODULE_ENTITY_POSITION_PROTO, callInfo->this_value); + if(!h) return jerry_undefined(); vec3 v; - entityPositionGetRotation(eid, cid, v); + entityPositionGetRotation(h->eid, h->cid, v); return jerry_number(v[0]); } moduleBaseFunction(moduleEntityPositionSetRotX) { moduleBaseRequireArgs(1); moduleBaseRequireNumber(0); - entityid_t eid = getEntityId(callInfo->this_value); - componentid_t cid = getCompId(callInfo->this_value); + componenthandle_t *h = scriptProtoGetValue(&MODULE_ENTITY_POSITION_PROTO, callInfo->this_value); + if(!h) return jerry_undefined(); vec3 v; - entityPositionGetRotation(eid, cid, v); + entityPositionGetRotation(h->eid, h->cid, v); v[0] = (float_t)jerry_value_as_number(args[0]); - entityPositionSetRotation(eid, cid, v); + entityPositionSetRotation(h->eid, h->cid, v); return jerry_undefined(); } moduleBaseFunction(moduleEntityPositionGetRotY) { - entityid_t eid = getEntityId(callInfo->this_value); - componentid_t cid = getCompId(callInfo->this_value); + componenthandle_t *h = scriptProtoGetValue(&MODULE_ENTITY_POSITION_PROTO, callInfo->this_value); + if(!h) return jerry_undefined(); vec3 v; - entityPositionGetRotation(eid, cid, v); + entityPositionGetRotation(h->eid, h->cid, v); return jerry_number(v[1]); } moduleBaseFunction(moduleEntityPositionSetRotY) { moduleBaseRequireArgs(1); moduleBaseRequireNumber(0); - entityid_t eid = getEntityId(callInfo->this_value); - componentid_t cid = getCompId(callInfo->this_value); + componenthandle_t *h = scriptProtoGetValue(&MODULE_ENTITY_POSITION_PROTO, callInfo->this_value); + if(!h) return jerry_undefined(); vec3 v; - entityPositionGetRotation(eid, cid, v); + entityPositionGetRotation(h->eid, h->cid, v); v[1] = (float_t)jerry_value_as_number(args[0]); - entityPositionSetRotation(eid, cid, v); + entityPositionSetRotation(h->eid, h->cid, v); return jerry_undefined(); } moduleBaseFunction(moduleEntityPositionGetRotZ) { - entityid_t eid = getEntityId(callInfo->this_value); - componentid_t cid = getCompId(callInfo->this_value); + componenthandle_t *h = scriptProtoGetValue(&MODULE_ENTITY_POSITION_PROTO, callInfo->this_value); + if(!h) return jerry_undefined(); vec3 v; - entityPositionGetRotation(eid, cid, v); + entityPositionGetRotation(h->eid, h->cid, v); return jerry_number(v[2]); } moduleBaseFunction(moduleEntityPositionSetRotZ) { moduleBaseRequireArgs(1); moduleBaseRequireNumber(0); - entityid_t eid = getEntityId(callInfo->this_value); - componentid_t cid = getCompId(callInfo->this_value); + componenthandle_t *h = scriptProtoGetValue(&MODULE_ENTITY_POSITION_PROTO, callInfo->this_value); + if(!h) return jerry_undefined(); vec3 v; - entityPositionGetRotation(eid, cid, v); + entityPositionGetRotation(h->eid, h->cid, v); v[2] = (float_t)jerry_value_as_number(args[0]); - entityPositionSetRotation(eid, cid, v); + entityPositionSetRotation(h->eid, h->cid, v); return jerry_undefined(); } // -- scale getters/setters -- moduleBaseFunction(moduleEntityPositionGetScaleX) { - entityid_t eid = getEntityId(callInfo->this_value); - componentid_t cid = getCompId(callInfo->this_value); + componenthandle_t *h = scriptProtoGetValue(&MODULE_ENTITY_POSITION_PROTO, callInfo->this_value); + if(!h) return jerry_undefined(); vec3 v; - entityPositionGetScale(eid, cid, v); + entityPositionGetScale(h->eid, h->cid, v); return jerry_number(v[0]); } moduleBaseFunction(moduleEntityPositionSetScaleX) { moduleBaseRequireArgs(1); moduleBaseRequireNumber(0); - entityid_t eid = getEntityId(callInfo->this_value); - componentid_t cid = getCompId(callInfo->this_value); + componenthandle_t *h = scriptProtoGetValue(&MODULE_ENTITY_POSITION_PROTO, callInfo->this_value); + if(!h) return jerry_undefined(); vec3 v; - entityPositionGetScale(eid, cid, v); + entityPositionGetScale(h->eid, h->cid, v); v[0] = (float_t)jerry_value_as_number(args[0]); - entityPositionSetScale(eid, cid, v); + entityPositionSetScale(h->eid, h->cid, v); return jerry_undefined(); } moduleBaseFunction(moduleEntityPositionGetScaleY) { - entityid_t eid = getEntityId(callInfo->this_value); - componentid_t cid = getCompId(callInfo->this_value); + componenthandle_t *h = scriptProtoGetValue(&MODULE_ENTITY_POSITION_PROTO, callInfo->this_value); + if(!h) return jerry_undefined(); vec3 v; - entityPositionGetScale(eid, cid, v); + entityPositionGetScale(h->eid, h->cid, v); return jerry_number(v[1]); } moduleBaseFunction(moduleEntityPositionSetScaleY) { moduleBaseRequireArgs(1); moduleBaseRequireNumber(0); - entityid_t eid = getEntityId(callInfo->this_value); - componentid_t cid = getCompId(callInfo->this_value); + componenthandle_t *h = scriptProtoGetValue(&MODULE_ENTITY_POSITION_PROTO, callInfo->this_value); + if(!h) return jerry_undefined(); vec3 v; - entityPositionGetScale(eid, cid, v); + entityPositionGetScale(h->eid, h->cid, v); v[1] = (float_t)jerry_value_as_number(args[0]); - entityPositionSetScale(eid, cid, v); + entityPositionSetScale(h->eid, h->cid, v); return jerry_undefined(); } moduleBaseFunction(moduleEntityPositionGetScaleZ) { - entityid_t eid = getEntityId(callInfo->this_value); - componentid_t cid = getCompId(callInfo->this_value); + componenthandle_t *h = scriptProtoGetValue(&MODULE_ENTITY_POSITION_PROTO, callInfo->this_value); + if(!h) return jerry_undefined(); vec3 v; - entityPositionGetScale(eid, cid, v); + entityPositionGetScale(h->eid, h->cid, v); return jerry_number(v[2]); } moduleBaseFunction(moduleEntityPositionSetScaleZ) { moduleBaseRequireArgs(1); moduleBaseRequireNumber(0); - entityid_t eid = getEntityId(callInfo->this_value); - componentid_t cid = getCompId(callInfo->this_value); + componenthandle_t *h = scriptProtoGetValue(&MODULE_ENTITY_POSITION_PROTO, callInfo->this_value); + if(!h) return jerry_undefined(); vec3 v; - entityPositionGetScale(eid, cid, v); + entityPositionGetScale(h->eid, h->cid, v); v[2] = (float_t)jerry_value_as_number(args[0]); - entityPositionSetScale(eid, cid, v); + entityPositionSetScale(h->eid, h->cid, v); return jerry_undefined(); } // -- lookAt method -- -/** - * Rotates the entity to face a world-space target point. - * Args: target x, y, z [, up x, y, z]. Up defaults to (0,1,0). - */ moduleBaseFunction(moduleEntityPositionLookAt) { moduleBaseRequireArgs(3); - entityid_t eid = getEntityId(callInfo->this_value); - componentid_t cid = getCompId(callInfo->this_value); + componenthandle_t *h = scriptProtoGetValue(&MODULE_ENTITY_POSITION_PROTO, callInfo->this_value); + if(!h) return jerry_undefined(); vec3 target = { (float_t)jerry_value_as_number(args[0]), (float_t)jerry_value_as_number(args[1]), @@ -271,43 +217,33 @@ moduleBaseFunction(moduleEntityPositionLookAt) { up[2] = (float_t)jerry_value_as_number(args[5]); } vec3 eye; - entityPositionGetPosition(eid, cid, eye); - entityPositionLookAt(eid, cid, target, up, eye); + entityPositionGetPosition(h->eid, h->cid, eye); + entityPositionLookAt(h->eid, h->cid, target, up, eye); return jerry_undefined(); } // -- add function -- -/** - * Adds a position component to an entity and returns a handle object. - * Arg 0: entity id (number). - */ moduleBaseFunction(moduleEntityPositionAdd) { moduleBaseRequireArgs(1); moduleBaseRequireNumber(0); entityid_t id = (entityid_t)jerry_value_as_number(args[0]); componentid_t comp = entityAddComponent(id, COMPONENT_TYPE_POSITION); - jerry_value_t handle = makeEntityHandle(id, comp); - if(s_posProto != 0) jerry_object_set_proto(handle, s_posProto); - return handle; + componenthandle_t h = { .eid = id, .cid = comp }; + return scriptProtoCreateValue(&MODULE_ENTITY_POSITION_PROTO, &h); } -/** - * Registers the position component prototype and entityPositionAdd global. - */ static void moduleEntityPosition(void) { - s_posProto = jerry_object(); + scriptProtoInit(&MODULE_ENTITY_POSITION_PROTO, NULL, sizeof(componenthandle_t), NULL); - moduleBaseDefineProperty(s_posProto, "x", moduleEntityPositionGetX, moduleEntityPositionSetX); - moduleBaseDefineProperty(s_posProto, "y", moduleEntityPositionGetY, moduleEntityPositionSetY); - moduleBaseDefineProperty(s_posProto, "z", moduleEntityPositionGetZ, moduleEntityPositionSetZ); - moduleBaseDefineProperty(s_posProto, "rotX", moduleEntityPositionGetRotX, moduleEntityPositionSetRotX); - moduleBaseDefineProperty(s_posProto, "rotY", moduleEntityPositionGetRotY, moduleEntityPositionSetRotY); - moduleBaseDefineProperty(s_posProto, "rotZ", moduleEntityPositionGetRotZ, moduleEntityPositionSetRotZ); - moduleBaseDefineProperty(s_posProto, "scaleX", moduleEntityPositionGetScaleX, moduleEntityPositionSetScaleX); - moduleBaseDefineProperty(s_posProto, "scaleY", moduleEntityPositionGetScaleY, moduleEntityPositionSetScaleY); - moduleBaseDefineProperty(s_posProto, "scaleZ", moduleEntityPositionGetScaleZ, moduleEntityPositionSetScaleZ); + scriptProtoDefineProp(&MODULE_ENTITY_POSITION_PROTO, "x", moduleEntityPositionGetX, moduleEntityPositionSetX); + scriptProtoDefineProp(&MODULE_ENTITY_POSITION_PROTO, "y", moduleEntityPositionGetY, moduleEntityPositionSetY); + scriptProtoDefineProp(&MODULE_ENTITY_POSITION_PROTO, "z", moduleEntityPositionGetZ, moduleEntityPositionSetZ); + scriptProtoDefineProp(&MODULE_ENTITY_POSITION_PROTO, "rotX", moduleEntityPositionGetRotX, moduleEntityPositionSetRotX); + scriptProtoDefineProp(&MODULE_ENTITY_POSITION_PROTO, "rotY", moduleEntityPositionGetRotY, moduleEntityPositionSetRotY); + scriptProtoDefineProp(&MODULE_ENTITY_POSITION_PROTO, "rotZ", moduleEntityPositionGetRotZ, moduleEntityPositionSetRotZ); + scriptProtoDefineProp(&MODULE_ENTITY_POSITION_PROTO, "scaleX", moduleEntityPositionGetScaleX, moduleEntityPositionSetScaleX); + scriptProtoDefineProp(&MODULE_ENTITY_POSITION_PROTO, "scaleY", moduleEntityPositionGetScaleY, moduleEntityPositionSetScaleY); + scriptProtoDefineProp(&MODULE_ENTITY_POSITION_PROTO, "scaleZ", moduleEntityPositionGetScaleZ, moduleEntityPositionSetScaleZ); - moduleBaseDefineMethod(s_posProto, "lookAt", moduleEntityPositionLookAt); - - moduleBaseFunctionRegister("entityPositionAdd", moduleEntityPositionAdd); + scriptProtoDefineFunc(&MODULE_ENTITY_POSITION_PROTO, "lookAt", moduleEntityPositionLookAt); } diff --git a/src/dusk/script/module/entity/moduleentity.h b/src/dusk/script/module/entity/moduleentity.h index 8171dcde..f9b560af 100644 --- a/src/dusk/script/module/entity/moduleentity.h +++ b/src/dusk/script/module/entity/moduleentity.h @@ -22,6 +22,7 @@ typedef struct { } entityscript_t; static scriptproto_t MODULE_ENTITY_PROTO; +static jerry_external_handler_t s_componentAddFns[COMPONENT_TYPE_COUNT]; moduleBaseFunction(moduleEntityConstructor) { entityscript_t *inst = (entityscript_t*)memoryAllocate(sizeof(entityscript_t)); @@ -41,41 +42,30 @@ moduleBaseFunction(moduleEntityAddComponent) { return moduleBaseThrow("Entity.add: expected a component type object"); } - jerry_value_t nameKey = jerry_string_sz("name"); - jerry_value_t nameJsVal = jerry_object_get(args[0], nameKey); - jerry_value_free(nameKey); + 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_string(nameJsVal)) { - jerry_value_free(nameJsVal); - return moduleBaseThrow("Entity.add: component type must have a .name property"); + if(!jerry_value_is_number(typeVal)) { + jerry_value_free(typeVal); + return moduleBaseThrow("Entity.add: expected a component type object"); } - char_t nameStr[64]; - moduleBaseToString(nameJsVal, nameStr, sizeof(nameStr)); - jerry_value_free(nameJsVal); + componenttype_t type = (componenttype_t)(int32_t)jerry_value_as_number(typeVal); + jerry_value_free(typeVal); - jerry_external_handler_t addFn = NULL; - const char_t *propName = NULL; - - if(stringCompare(nameStr, "POSITION") == 0) { - addFn = moduleEntityPositionAdd; propName = "position"; - } else if(stringCompare(nameStr, "CAMERA") == 0) { - addFn = moduleEntityCameraAdd; propName = "camera"; - } else if(stringCompare(nameStr, "MESH") == 0) { - addFn = moduleEntityMeshAdd; propName = "mesh"; - } else if(stringCompare(nameStr, "MATERIAL") == 0) { - addFn = moduleEntityMaterialAdd; propName = "material"; - } else if(stringCompare(nameStr, "PHYSICS") == 0) { - addFn = moduleEntityPhysicsAdd; propName = "physics"; + if(type <= COMPONENT_TYPE_NULL || type >= COMPONENT_TYPE_COUNT) { + return moduleBaseThrow("Entity.add: invalid component type"); } - if(!addFn) return moduleBaseThrow("Entity.add: unknown component type"); + jerry_external_handler_t addFn = s_componentAddFns[type]; + if(!addFn) return moduleBaseThrow("Entity.add: no handler for this component type"); 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(propName); + 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; @@ -107,16 +97,28 @@ static void moduleEntity(void) { 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; + // Register component type objects as globals and as Entity.POSITION etc. - // Each object has a .name property with the uppercase enum name, e.g. "POSITION". + // 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(#enumName); \ + jerry_value_t nv = jerry_string_sz(#field); \ jerry_object_set(ctObj, nk, nv); \ - jerry_value_free(nv); \ - jerry_value_free(nk); \ + 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); \ diff --git a/src/dusk/script/module/math/modulemat4.h b/src/dusk/script/module/math/modulemat4.h index cd8e712f..a04b984d 100644 --- a/src/dusk/script/module/math/modulemat4.h +++ b/src/dusk/script/module/math/modulemat4.h @@ -7,88 +7,68 @@ #pragma once #include "script/module/modulebase.h" -#include "assert/assert.h" +#include "script/scriptproto.h" #include "cglm/cglm.h" #include "modulevec3.h" #include "modulevec4.h" -// Native info for heap-allocated mat4 (float[4][4]) -static void freeMat4Native(void *ptr, jerry_object_native_info_t *info) { - (void)info; - free(ptr); -} -static const jerry_object_native_info_t MAT4_NATIVE_INFO = { - .free_cb = freeMat4Native, - .number_of_references = 0, - .offset_of_references = 0 -}; -static jerry_value_t s_mat4Proto = 0; +static scriptproto_t MODULE_MAT4_PROTO; // --------------------------------------------------------------------------- -// Methods +// Constructor — creates an identity matrix +// --------------------------------------------------------------------------- + +moduleBaseFunction(moduleMatConstructor) { + float_t (*ptr)[4] = (float_t (*)[4])memoryAllocate(sizeof(mat4)); + glm_mat4_identity(ptr); + jerry_object_set_native_ptr(callInfo->this_value, &MODULE_MAT4_PROTO.info, ptr); + return jerry_undefined(); +} + +// --------------------------------------------------------------------------- +// Instance methods // --------------------------------------------------------------------------- moduleBaseFunction(moduleMatMul) { moduleBaseRequireArgs(1); - float_t (*a)[4] = (float_t (*)[4])jerry_object_get_native_ptr( - callInfo->this_value, &MAT4_NATIVE_INFO - ); - if(!a) return moduleBaseThrow("mat4.mul: invalid this"); - float_t (*b)[4] = (float_t (*)[4])jerry_object_get_native_ptr( - args[0], &MAT4_NATIVE_INFO - ); - if(!b) return moduleBaseThrow("mat4.mul: argument must be a mat4"); - float_t (*r)[4] = (float_t (*)[4])malloc(sizeof(mat4)); + float_t (*a)[4] = (float_t (*)[4])scriptProtoGetValue(&MODULE_MAT4_PROTO, callInfo->this_value); + if(!a) return moduleBaseThrow("Mat4.mul: invalid this"); + float_t (*b)[4] = (float_t (*)[4])scriptProtoGetValue(&MODULE_MAT4_PROTO, args[0]); + if(!b) return moduleBaseThrow("Mat4.mul: argument must be a Mat4"); + mat4 r; glm_mat4_mul(a, b, r); - jerry_value_t obj = jerry_object(); - jerry_object_set_native_ptr(obj, &MAT4_NATIVE_INFO, r); - jerry_object_set_proto(obj, s_mat4Proto); - return obj; + return scriptProtoCreateValue(&MODULE_MAT4_PROTO, r); } moduleBaseFunction(moduleMatTranspose) { - float_t (*m)[4] = (float_t (*)[4])jerry_object_get_native_ptr( - callInfo->this_value, &MAT4_NATIVE_INFO - ); - if(!m) return moduleBaseThrow("mat4.transpose: invalid this"); - float_t (*r)[4] = (float_t (*)[4])malloc(sizeof(mat4)); + float_t (*m)[4] = (float_t (*)[4])scriptProtoGetValue(&MODULE_MAT4_PROTO, callInfo->this_value); + if(!m) return moduleBaseThrow("Mat4.transpose: invalid this"); + mat4 r; glm_mat4_transpose_to(m, r); - jerry_value_t obj = jerry_object(); - jerry_object_set_native_ptr(obj, &MAT4_NATIVE_INFO, r); - jerry_object_set_proto(obj, s_mat4Proto); - return obj; + return scriptProtoCreateValue(&MODULE_MAT4_PROTO, r); } moduleBaseFunction(moduleMatInverse) { - float_t (*m)[4] = (float_t (*)[4])jerry_object_get_native_ptr( - callInfo->this_value, &MAT4_NATIVE_INFO - ); - if(!m) return moduleBaseThrow("mat4.inverse: invalid this"); - float_t (*r)[4] = (float_t (*)[4])malloc(sizeof(mat4)); + float_t (*m)[4] = (float_t (*)[4])scriptProtoGetValue(&MODULE_MAT4_PROTO, callInfo->this_value); + if(!m) return moduleBaseThrow("Mat4.inverse: invalid this"); + mat4 r; glm_mat4_inv(m, r); - jerry_value_t obj = jerry_object(); - jerry_object_set_native_ptr(obj, &MAT4_NATIVE_INFO, r); - jerry_object_set_proto(obj, s_mat4Proto); - return obj; + return scriptProtoCreateValue(&MODULE_MAT4_PROTO, r); } moduleBaseFunction(moduleMatDeterminant) { - float_t (*m)[4] = (float_t (*)[4])jerry_object_get_native_ptr( - callInfo->this_value, &MAT4_NATIVE_INFO - ); - if(!m) return moduleBaseThrow("mat4.determinant: invalid this"); + float_t (*m)[4] = (float_t (*)[4])scriptProtoGetValue(&MODULE_MAT4_PROTO, callInfo->this_value); + if(!m) return moduleBaseThrow("Mat4.determinant: invalid this"); return jerry_number(glm_mat4_det(m)); } moduleBaseFunction(moduleMatMulVec3) { moduleBaseRequireArgs(1); - float_t (*m)[4] = (float_t (*)[4])jerry_object_get_native_ptr( - callInfo->this_value, &MAT4_NATIVE_INFO - ); - if(!m) return moduleBaseThrow("mat4.mulVec3: invalid this"); + float_t (*m)[4] = (float_t (*)[4])scriptProtoGetValue(&MODULE_MAT4_PROTO, callInfo->this_value); + if(!m) return moduleBaseThrow("Mat4.mulVec3: invalid this"); vec3 vin; if(!moduleVec3Check(args[0], vin)) { - return moduleBaseThrow("mat4.mulVec3: first argument must be a vec3"); + return moduleBaseThrow("Mat4.mulVec3: argument must be a Vec3"); } float_t w = (argc >= 2 && jerry_value_is_number(args[1])) ? (float_t)jerry_value_as_number(args[1]) @@ -100,13 +80,11 @@ moduleBaseFunction(moduleMatMulVec3) { moduleBaseFunction(moduleMatMulVec4) { moduleBaseRequireArgs(1); - float_t (*m)[4] = (float_t (*)[4])jerry_object_get_native_ptr( - callInfo->this_value, &MAT4_NATIVE_INFO - ); - if(!m) return moduleBaseThrow("mat4.mulVec4: invalid this"); + float_t (*m)[4] = (float_t (*)[4])scriptProtoGetValue(&MODULE_MAT4_PROTO, callInfo->this_value); + if(!m) return moduleBaseThrow("Mat4.mulVec4: invalid this"); vec4 vin; if(!moduleVec4Check(args[0], vin)) { - return moduleBaseThrow("mat4.mulVec4: first argument must be a vec4"); + return moduleBaseThrow("Mat4.mulVec4: argument must be a Vec4"); } vec4 vout; glm_mat4_mulv(m, vin, vout); @@ -115,147 +93,76 @@ moduleBaseFunction(moduleMatMulVec4) { moduleBaseFunction(moduleMatTranslate) { moduleBaseRequireArgs(1); - float_t (*m)[4] = (float_t (*)[4])jerry_object_get_native_ptr( - callInfo->this_value, &MAT4_NATIVE_INFO - ); - if(!m) return moduleBaseThrow("mat4.translate: invalid this"); + float_t (*m)[4] = (float_t (*)[4])scriptProtoGetValue(&MODULE_MAT4_PROTO, callInfo->this_value); + if(!m) return moduleBaseThrow("Mat4.translate: invalid this"); vec3 tv; if(!moduleVec3Check(args[0], tv)) { - return moduleBaseThrow("mat4.translate: argument must be a vec3"); + return moduleBaseThrow("Mat4.translate: argument must be a Vec3"); } - float_t (*r)[4] = (float_t (*)[4])malloc(sizeof(mat4)); + mat4 r; glm_mat4_copy(m, r); glm_translate(r, tv); - jerry_value_t obj = jerry_object(); - jerry_object_set_native_ptr(obj, &MAT4_NATIVE_INFO, r); - jerry_object_set_proto(obj, s_mat4Proto); - return obj; + return scriptProtoCreateValue(&MODULE_MAT4_PROTO, r); } moduleBaseFunction(moduleMatScale) { moduleBaseRequireArgs(1); - float_t (*m)[4] = (float_t (*)[4])jerry_object_get_native_ptr( - callInfo->this_value, &MAT4_NATIVE_INFO - ); - if(!m) return moduleBaseThrow("mat4.scale: invalid this"); + float_t (*m)[4] = (float_t (*)[4])scriptProtoGetValue(&MODULE_MAT4_PROTO, callInfo->this_value); + if(!m) return moduleBaseThrow("Mat4.scale: invalid this"); vec3 sv; if(!moduleVec3Check(args[0], sv)) { - return moduleBaseThrow("mat4.scale: argument must be a vec3"); + return moduleBaseThrow("Mat4.scale: argument must be a Vec3"); } - float_t (*r)[4] = (float_t (*)[4])malloc(sizeof(mat4)); + mat4 r; glm_mat4_copy(m, r); glm_scale(r, sv); - jerry_value_t obj = jerry_object(); - jerry_object_set_native_ptr(obj, &MAT4_NATIVE_INFO, r); - jerry_object_set_proto(obj, s_mat4Proto); - return obj; -} - -moduleBaseFunction(moduleMatIdentityMethod) { - float_t (*r)[4] = (float_t (*)[4])malloc(sizeof(mat4)); - glm_mat4_identity(r); - jerry_value_t obj = jerry_object(); - jerry_object_set_native_ptr(obj, &MAT4_NATIVE_INFO, r); - jerry_object_set_proto(obj, s_mat4Proto); - return obj; + return scriptProtoCreateValue(&MODULE_MAT4_PROTO, r); } // --------------------------------------------------------------------------- -// Global constructor / factory functions +// Static factory methods // --------------------------------------------------------------------------- -/** - * mat4Identity() - returns a new identity matrix. - */ -moduleBaseFunction(moduleMatIdentity) { - float_t (*r)[4] = (float_t (*)[4])malloc(sizeof(mat4)); +moduleBaseFunction(moduleMatStaticIdentity) { + mat4 r; glm_mat4_identity(r); - jerry_value_t obj = jerry_object(); - jerry_object_set_native_ptr(obj, &MAT4_NATIVE_INFO, r); - jerry_object_set_proto(obj, s_mat4Proto); - return obj; + return scriptProtoCreateValue(&MODULE_MAT4_PROTO, r); } -/** - * mat4Perspective(fov, aspect, near, far) - returns a perspective projection - * matrix. - */ -moduleBaseFunction(moduleMatPerspective) { +moduleBaseFunction(moduleMatStaticPerspective) { moduleBaseRequireArgs(4); - moduleBaseRequireNumber(0); - moduleBaseRequireNumber(1); - moduleBaseRequireNumber(2); - moduleBaseRequireNumber(3); + moduleBaseRequireNumber(0); moduleBaseRequireNumber(1); + moduleBaseRequireNumber(2); moduleBaseRequireNumber(3); float_t fov = (float_t)jerry_value_as_number(args[0]); float_t aspect = (float_t)jerry_value_as_number(args[1]); float_t znear = (float_t)jerry_value_as_number(args[2]); float_t zfar = (float_t)jerry_value_as_number(args[3]); - float_t (*r)[4] = (float_t (*)[4])malloc(sizeof(mat4)); + mat4 r; glm_perspective(fov, aspect, znear, zfar, r); - jerry_value_t obj = jerry_object(); - jerry_object_set_native_ptr(obj, &MAT4_NATIVE_INFO, r); - jerry_object_set_proto(obj, s_mat4Proto); - return obj; + return scriptProtoCreateValue(&MODULE_MAT4_PROTO, r); } -/** - * mat4LookAt(eye, center, up) - returns a view matrix. - * eye, center, up are vec3 objects. - */ -moduleBaseFunction(moduleMatLookAt) { +moduleBaseFunction(moduleMatStaticLookAt) { moduleBaseRequireArgs(3); vec3 eye, center, up; - if(!moduleVec3Check(args[0], eye)) { - return moduleBaseThrow("mat4LookAt: first argument (eye) must be a vec3"); - } - if(!moduleVec3Check(args[1], center)) { - return moduleBaseThrow("mat4LookAt: second argument (center) must be a vec3"); - } - if(!moduleVec3Check(args[2], up)) { - return moduleBaseThrow("mat4LookAt: third argument (up) must be a vec3"); - } - float_t (*r)[4] = (float_t (*)[4])malloc(sizeof(mat4)); + if(!moduleVec3Check(args[0], eye)) return moduleBaseThrow("Mat4.lookAt: eye must be a Vec3"); + if(!moduleVec3Check(args[1], center)) return moduleBaseThrow("Mat4.lookAt: center must be a Vec3"); + if(!moduleVec3Check(args[2], up)) return moduleBaseThrow("Mat4.lookAt: up must be a Vec3"); + mat4 r; glm_lookat(eye, center, up, r); - jerry_value_t obj = jerry_object(); - jerry_object_set_native_ptr(obj, &MAT4_NATIVE_INFO, r); - jerry_object_set_proto(obj, s_mat4Proto); - return obj; + return scriptProtoCreateValue(&MODULE_MAT4_PROTO, r); } // --------------------------------------------------------------------------- -// Helper: push a cglm mat4 as a new JS object +// Helpers for use by other modules // --------------------------------------------------------------------------- -/** - * Wraps a copy of a cglm mat4 as a new JerryScript object. - * - * @param m Source mat4 (float[4][4]) to copy. - * @return Owned jerry_value_t with native ptr set. - */ static inline jerry_value_t moduleMat4Push(float (*m)[4]) { - float_t (*copy)[4] = (float_t (*)[4])malloc(sizeof(mat4)); - glm_mat4_copy(m, copy); - jerry_value_t obj = jerry_object(); - jerry_object_set_native_ptr(obj, &MAT4_NATIVE_INFO, copy); - jerry_object_set_proto(obj, s_mat4Proto); - return obj; + return scriptProtoCreateValue(&MODULE_MAT4_PROTO, m); } -// --------------------------------------------------------------------------- -// Helper: extract mat4 from a JS object -// --------------------------------------------------------------------------- - -/** - * Reads a JerryScript mat4 object into an existing mat4 (float[4][4]). - * - * @param val JS value to read from. - * @param out Destination mat4. - * @return true if val carries a valid mat4 native ptr. - */ static inline bool_t moduleMat4Check(jerry_value_t val, float (*out)[4]) { - float_t (*m)[4] = (float_t (*)[4])jerry_object_get_native_ptr( - val, &MAT4_NATIVE_INFO - ); + float_t (*m)[4] = (float_t (*)[4])scriptProtoGetValue(&MODULE_MAT4_PROTO, val); if(!m) return false; glm_mat4_copy(m, out); return true; @@ -265,24 +172,19 @@ static inline bool_t moduleMat4Check(jerry_value_t val, float (*out)[4]) { // Module init // --------------------------------------------------------------------------- -/** - * Creates the mat4 prototype with all methods, then registers the global - * factory functions mat4Identity(), mat4Perspective(), and mat4LookAt(). - */ static void moduleMat4(void) { - s_mat4Proto = jerry_object(); + scriptProtoInit(&MODULE_MAT4_PROTO, "Mat4", sizeof(mat4), moduleMatConstructor); - moduleBaseDefineMethod(s_mat4Proto, "mul", moduleMatMul); - moduleBaseDefineMethod(s_mat4Proto, "transpose", moduleMatTranspose); - moduleBaseDefineMethod(s_mat4Proto, "inverse", moduleMatInverse); - moduleBaseDefineMethod(s_mat4Proto, "determinant", moduleMatDeterminant); - moduleBaseDefineMethod(s_mat4Proto, "mulVec3", moduleMatMulVec3); - moduleBaseDefineMethod(s_mat4Proto, "mulVec4", moduleMatMulVec4); - moduleBaseDefineMethod(s_mat4Proto, "translate", moduleMatTranslate); - moduleBaseDefineMethod(s_mat4Proto, "scale", moduleMatScale); - moduleBaseDefineMethod(s_mat4Proto, "identity", moduleMatIdentityMethod); + scriptProtoDefineFunc(&MODULE_MAT4_PROTO, "mul", moduleMatMul); + scriptProtoDefineFunc(&MODULE_MAT4_PROTO, "transpose", moduleMatTranspose); + scriptProtoDefineFunc(&MODULE_MAT4_PROTO, "inverse", moduleMatInverse); + scriptProtoDefineFunc(&MODULE_MAT4_PROTO, "determinant", moduleMatDeterminant); + scriptProtoDefineFunc(&MODULE_MAT4_PROTO, "mulVec3", moduleMatMulVec3); + scriptProtoDefineFunc(&MODULE_MAT4_PROTO, "mulVec4", moduleMatMulVec4); + scriptProtoDefineFunc(&MODULE_MAT4_PROTO, "translate", moduleMatTranslate); + scriptProtoDefineFunc(&MODULE_MAT4_PROTO, "scale", moduleMatScale); - moduleBaseFunctionRegister("mat4Identity", moduleMatIdentity); - moduleBaseFunctionRegister("mat4Perspective", moduleMatPerspective); - moduleBaseFunctionRegister("mat4LookAt", moduleMatLookAt); + scriptProtoDefineStaticFunc(&MODULE_MAT4_PROTO, "identity", moduleMatStaticIdentity); + scriptProtoDefineStaticFunc(&MODULE_MAT4_PROTO, "perspective", moduleMatStaticPerspective); + scriptProtoDefineStaticFunc(&MODULE_MAT4_PROTO, "lookAt", moduleMatStaticLookAt); } diff --git a/src/dusk/script/module/math/modulevec2.h b/src/dusk/script/module/math/modulevec2.h index bed1f081..c220452a 100644 --- a/src/dusk/script/module/math/modulevec2.h +++ b/src/dusk/script/module/math/modulevec2.h @@ -7,49 +7,43 @@ #pragma once #include "script/module/modulebase.h" -#include "assert/assert.h" +#include "script/scriptproto.h" #include "cglm/cglm.h" -// Native info for heap-allocated vec2 (float[2]) -static void freeVec2Native(void *ptr, jerry_object_native_info_t *info) { - (void)info; - free(ptr); +static scriptproto_t MODULE_VEC2_PROTO; + +// --------------------------------------------------------------------------- +// Constructor +// --------------------------------------------------------------------------- + +moduleBaseFunction(moduleVec2Constructor) { + float_t *ptr = (float_t *)memoryAllocate(sizeof(vec2)); + ptr[0] = (argc >= 1 && jerry_value_is_number(args[0])) ? (float_t)jerry_value_as_number(args[0]) : 0.0f; + ptr[1] = (argc >= 2 && jerry_value_is_number(args[1])) ? (float_t)jerry_value_as_number(args[1]) : 0.0f; + jerry_object_set_native_ptr(callInfo->this_value, &MODULE_VEC2_PROTO.info, ptr); + return jerry_undefined(); } -static const jerry_object_native_info_t VEC2_NATIVE_INFO = { - .free_cb = freeVec2Native, - .number_of_references = 0, - .offset_of_references = 0 -}; -static jerry_value_t s_vec2Proto = 0; // --------------------------------------------------------------------------- // Property getters / setters // --------------------------------------------------------------------------- moduleBaseFunction(moduleVec2GetX) { - float_t *v = (float_t *)jerry_object_get_native_ptr( - callInfo->this_value, &VEC2_NATIVE_INFO - ); + float_t *v = (float_t *)scriptProtoGetValue(&MODULE_VEC2_PROTO, callInfo->this_value); return v ? jerry_number(v[0]) : jerry_undefined(); } moduleBaseFunction(moduleVec2SetX) { - float_t *v = (float_t *)jerry_object_get_native_ptr( - callInfo->this_value, &VEC2_NATIVE_INFO - ); + float_t *v = (float_t *)scriptProtoGetValue(&MODULE_VEC2_PROTO, callInfo->this_value); if(v && argc > 0) v[0] = (float_t)jerry_value_as_number(args[0]); return jerry_undefined(); } moduleBaseFunction(moduleVec2GetY) { - float_t *v = (float_t *)jerry_object_get_native_ptr( - callInfo->this_value, &VEC2_NATIVE_INFO - ); + float_t *v = (float_t *)scriptProtoGetValue(&MODULE_VEC2_PROTO, callInfo->this_value); return v ? jerry_number(v[1]) : jerry_undefined(); } moduleBaseFunction(moduleVec2SetY) { - float_t *v = (float_t *)jerry_object_get_native_ptr( - callInfo->this_value, &VEC2_NATIVE_INFO - ); + float_t *v = (float_t *)scriptProtoGetValue(&MODULE_VEC2_PROTO, callInfo->this_value); if(v && argc > 0) v[1] = (float_t)jerry_value_as_number(args[0]); return jerry_undefined(); } @@ -60,184 +54,102 @@ moduleBaseFunction(moduleVec2SetY) { moduleBaseFunction(moduleVec2Dot) { moduleBaseRequireArgs(1); - float_t *a = (float_t *)jerry_object_get_native_ptr( - callInfo->this_value, &VEC2_NATIVE_INFO - ); - if(!a) return moduleBaseThrow("vec2.dot: invalid this"); - float_t *b = (float_t *)jerry_object_get_native_ptr(args[0], &VEC2_NATIVE_INFO); - if(!b) return moduleBaseThrow("vec2.dot: argument must be a vec2"); + float_t *a = (float_t *)scriptProtoGetValue(&MODULE_VEC2_PROTO, callInfo->this_value); + if(!a) return moduleBaseThrow("Vec2.dot: invalid this"); + float_t *b = (float_t *)scriptProtoGetValue(&MODULE_VEC2_PROTO, args[0]); + if(!b) return moduleBaseThrow("Vec2.dot: argument must be a Vec2"); return jerry_number(glm_vec2_dot(a, b)); } moduleBaseFunction(moduleVec2Length) { - float_t *v = (float_t *)jerry_object_get_native_ptr( - callInfo->this_value, &VEC2_NATIVE_INFO - ); - if(!v) return moduleBaseThrow("vec2.length: invalid this"); + float_t *v = (float_t *)scriptProtoGetValue(&MODULE_VEC2_PROTO, callInfo->this_value); + if(!v) return moduleBaseThrow("Vec2.length: invalid this"); return jerry_number(glm_vec2_norm(v)); } moduleBaseFunction(moduleVec2LengthSq) { - float_t *v = (float_t *)jerry_object_get_native_ptr( - callInfo->this_value, &VEC2_NATIVE_INFO - ); - if(!v) return moduleBaseThrow("vec2.lengthSq: invalid this"); + float_t *v = (float_t *)scriptProtoGetValue(&MODULE_VEC2_PROTO, callInfo->this_value); + if(!v) return moduleBaseThrow("Vec2.lengthSq: invalid this"); return jerry_number(glm_vec2_norm2(v)); } moduleBaseFunction(moduleVec2Normalize) { - float_t *v = (float_t *)jerry_object_get_native_ptr( - callInfo->this_value, &VEC2_NATIVE_INFO - ); - if(!v) return moduleBaseThrow("vec2.normalize: invalid this"); - float_t *r = (float_t *)malloc(sizeof(vec2)); + float_t *v = (float_t *)scriptProtoGetValue(&MODULE_VEC2_PROTO, callInfo->this_value); + if(!v) return moduleBaseThrow("Vec2.normalize: invalid this"); + vec2 r; glm_vec2_normalize_to(v, r); - jerry_value_t obj = jerry_object(); - jerry_object_set_native_ptr(obj, &VEC2_NATIVE_INFO, r); - jerry_object_set_proto(obj, s_vec2Proto); - return obj; + return scriptProtoCreateValue(&MODULE_VEC2_PROTO, r); } moduleBaseFunction(moduleVec2Negate) { - float_t *v = (float_t *)jerry_object_get_native_ptr( - callInfo->this_value, &VEC2_NATIVE_INFO - ); - if(!v) return moduleBaseThrow("vec2.negate: invalid this"); - float_t *r = (float_t *)malloc(sizeof(vec2)); + float_t *v = (float_t *)scriptProtoGetValue(&MODULE_VEC2_PROTO, callInfo->this_value); + if(!v) return moduleBaseThrow("Vec2.negate: invalid this"); + vec2 r; glm_vec2_negate_to(v, r); - jerry_value_t obj = jerry_object(); - jerry_object_set_native_ptr(obj, &VEC2_NATIVE_INFO, r); - jerry_object_set_proto(obj, s_vec2Proto); - return obj; + return scriptProtoCreateValue(&MODULE_VEC2_PROTO, r); } moduleBaseFunction(moduleVec2Add) { moduleBaseRequireArgs(1); - float_t *a = (float_t *)jerry_object_get_native_ptr( - callInfo->this_value, &VEC2_NATIVE_INFO - ); - if(!a) return moduleBaseThrow("vec2.add: invalid this"); - float_t *b = (float_t *)jerry_object_get_native_ptr(args[0], &VEC2_NATIVE_INFO); - if(!b) return moduleBaseThrow("vec2.add: argument must be a vec2"); - float_t *r = (float_t *)malloc(sizeof(vec2)); + float_t *a = (float_t *)scriptProtoGetValue(&MODULE_VEC2_PROTO, callInfo->this_value); + if(!a) return moduleBaseThrow("Vec2.add: invalid this"); + float_t *b = (float_t *)scriptProtoGetValue(&MODULE_VEC2_PROTO, args[0]); + if(!b) return moduleBaseThrow("Vec2.add: argument must be a Vec2"); + vec2 r; glm_vec2_add(a, b, r); - jerry_value_t obj = jerry_object(); - jerry_object_set_native_ptr(obj, &VEC2_NATIVE_INFO, r); - jerry_object_set_proto(obj, s_vec2Proto); - return obj; + return scriptProtoCreateValue(&MODULE_VEC2_PROTO, r); } moduleBaseFunction(moduleVec2Sub) { moduleBaseRequireArgs(1); - float_t *a = (float_t *)jerry_object_get_native_ptr( - callInfo->this_value, &VEC2_NATIVE_INFO - ); - if(!a) return moduleBaseThrow("vec2.sub: invalid this"); - float_t *b = (float_t *)jerry_object_get_native_ptr(args[0], &VEC2_NATIVE_INFO); - if(!b) return moduleBaseThrow("vec2.sub: argument must be a vec2"); - float_t *r = (float_t *)malloc(sizeof(vec2)); + float_t *a = (float_t *)scriptProtoGetValue(&MODULE_VEC2_PROTO, callInfo->this_value); + if(!a) return moduleBaseThrow("Vec2.sub: invalid this"); + float_t *b = (float_t *)scriptProtoGetValue(&MODULE_VEC2_PROTO, args[0]); + if(!b) return moduleBaseThrow("Vec2.sub: argument must be a Vec2"); + vec2 r; glm_vec2_sub(a, b, r); - jerry_value_t obj = jerry_object(); - jerry_object_set_native_ptr(obj, &VEC2_NATIVE_INFO, r); - jerry_object_set_proto(obj, s_vec2Proto); - return obj; + return scriptProtoCreateValue(&MODULE_VEC2_PROTO, r); } moduleBaseFunction(moduleVec2Scale) { - moduleBaseRequireArgs(1); - moduleBaseRequireNumber(0); - float_t *v = (float_t *)jerry_object_get_native_ptr( - callInfo->this_value, &VEC2_NATIVE_INFO - ); - if(!v) return moduleBaseThrow("vec2.scale: invalid this"); - float_t s = (float_t)jerry_value_as_number(args[0]); - float_t *r = (float_t *)malloc(sizeof(vec2)); - glm_vec2_scale(v, s, r); - jerry_value_t obj = jerry_object(); - jerry_object_set_native_ptr(obj, &VEC2_NATIVE_INFO, r); - jerry_object_set_proto(obj, s_vec2Proto); - return obj; + moduleBaseRequireArgs(1); moduleBaseRequireNumber(0); + float_t *v = (float_t *)scriptProtoGetValue(&MODULE_VEC2_PROTO, callInfo->this_value); + if(!v) return moduleBaseThrow("Vec2.scale: invalid this"); + vec2 r; + glm_vec2_scale(v, (float_t)jerry_value_as_number(args[0]), r); + return scriptProtoCreateValue(&MODULE_VEC2_PROTO, r); } moduleBaseFunction(moduleVec2Lerp) { - moduleBaseRequireArgs(2); - moduleBaseRequireNumber(1); - float_t *a = (float_t *)jerry_object_get_native_ptr( - callInfo->this_value, &VEC2_NATIVE_INFO - ); - if(!a) return moduleBaseThrow("vec2.lerp: invalid this"); - float_t *b = (float_t *)jerry_object_get_native_ptr(args[0], &VEC2_NATIVE_INFO); - if(!b) return moduleBaseThrow("vec2.lerp: first argument must be a vec2"); - float_t t = (float_t)jerry_value_as_number(args[1]); - float_t *r = (float_t *)malloc(sizeof(vec2)); - glm_vec2_lerp(a, b, t, r); - jerry_value_t obj = jerry_object(); - jerry_object_set_native_ptr(obj, &VEC2_NATIVE_INFO, r); - jerry_object_set_proto(obj, s_vec2Proto); - return obj; + moduleBaseRequireArgs(2); moduleBaseRequireNumber(1); + float_t *a = (float_t *)scriptProtoGetValue(&MODULE_VEC2_PROTO, callInfo->this_value); + if(!a) return moduleBaseThrow("Vec2.lerp: invalid this"); + float_t *b = (float_t *)scriptProtoGetValue(&MODULE_VEC2_PROTO, args[0]); + if(!b) return moduleBaseThrow("Vec2.lerp: first argument must be a Vec2"); + vec2 r; + glm_vec2_lerp(a, b, (float_t)jerry_value_as_number(args[1]), r); + return scriptProtoCreateValue(&MODULE_VEC2_PROTO, r); } moduleBaseFunction(moduleVec2Distance) { moduleBaseRequireArgs(1); - float_t *a = (float_t *)jerry_object_get_native_ptr( - callInfo->this_value, &VEC2_NATIVE_INFO - ); - if(!a) return moduleBaseThrow("vec2.distance: invalid this"); - float_t *b = (float_t *)jerry_object_get_native_ptr(args[0], &VEC2_NATIVE_INFO); - if(!b) return moduleBaseThrow("vec2.distance: argument must be a vec2"); + float_t *a = (float_t *)scriptProtoGetValue(&MODULE_VEC2_PROTO, callInfo->this_value); + if(!a) return moduleBaseThrow("Vec2.distance: invalid this"); + float_t *b = (float_t *)scriptProtoGetValue(&MODULE_VEC2_PROTO, args[0]); + if(!b) return moduleBaseThrow("Vec2.distance: argument must be a Vec2"); return jerry_number(glm_vec2_distance(a, b)); } // --------------------------------------------------------------------------- -// Constructor +// Helpers for use by other modules // --------------------------------------------------------------------------- -moduleBaseFunction(moduleVec2Create) { - moduleBaseRequireArgs(2); - moduleBaseRequireNumber(0); - moduleBaseRequireNumber(1); - float_t *v = (float_t *)malloc(sizeof(vec2)); - v[0] = (float_t)jerry_value_as_number(args[0]); - v[1] = (float_t)jerry_value_as_number(args[1]); - jerry_value_t obj = jerry_object(); - jerry_object_set_native_ptr(obj, &VEC2_NATIVE_INFO, v); - jerry_object_set_proto(obj, s_vec2Proto); - return obj; -} - -// --------------------------------------------------------------------------- -// Helper: push a cglm vec2 as a new JS object -// --------------------------------------------------------------------------- - -/** - * Wraps a copy of a cglm vec2 as a new JerryScript object. - * - * @param v Source float[2] to copy. - * @return Owned jerry_value_t with native ptr set. - */ static inline jerry_value_t moduleVec2Push(const float_t *v) { - float_t *copy = (float_t *)malloc(sizeof(vec2)); - copy[0] = v[0]; - copy[1] = v[1]; - jerry_value_t obj = jerry_object(); - jerry_object_set_native_ptr(obj, &VEC2_NATIVE_INFO, copy); - jerry_object_set_proto(obj, s_vec2Proto); - return obj; + return scriptProtoCreateValue(&MODULE_VEC2_PROTO, v); } -// --------------------------------------------------------------------------- -// Helper: extract vec2 from a JS object -// --------------------------------------------------------------------------- - -/** - * Reads a JerryScript vec2 object into an existing float[2]. - * - * @param val JS value to read from. - * @param out Destination float[2]. - * @return true if val carries a valid vec2 native ptr. - */ static inline bool_t moduleVec2Check(jerry_value_t val, float_t *out) { - float_t *v = (float_t *)jerry_object_get_native_ptr(val, &VEC2_NATIVE_INFO); + float_t *v = (float_t *)scriptProtoGetValue(&MODULE_VEC2_PROTO, val); if(!v) return false; out[0] = v[0]; out[1] = v[1]; @@ -248,26 +160,20 @@ static inline bool_t moduleVec2Check(jerry_value_t val, float_t *out) { // Module init // --------------------------------------------------------------------------- -/** - * Creates the vec2 prototype with x/y getter-setter properties and all - * methods, then registers the global vec2() constructor. - */ static void moduleVec2(void) { - s_vec2Proto = jerry_object(); + scriptProtoInit(&MODULE_VEC2_PROTO, "Vec2", sizeof(vec2), moduleVec2Constructor); - moduleBaseDefineProperty(s_vec2Proto, "x", moduleVec2GetX, moduleVec2SetX); - moduleBaseDefineProperty(s_vec2Proto, "y", moduleVec2GetY, moduleVec2SetY); + scriptProtoDefineProp(&MODULE_VEC2_PROTO, "x", moduleVec2GetX, moduleVec2SetX); + scriptProtoDefineProp(&MODULE_VEC2_PROTO, "y", moduleVec2GetY, moduleVec2SetY); - moduleBaseDefineMethod(s_vec2Proto, "dot", moduleVec2Dot); - moduleBaseDefineMethod(s_vec2Proto, "length", moduleVec2Length); - moduleBaseDefineMethod(s_vec2Proto, "lengthSq", moduleVec2LengthSq); - moduleBaseDefineMethod(s_vec2Proto, "normalize", moduleVec2Normalize); - moduleBaseDefineMethod(s_vec2Proto, "negate", moduleVec2Negate); - moduleBaseDefineMethod(s_vec2Proto, "add", moduleVec2Add); - moduleBaseDefineMethod(s_vec2Proto, "sub", moduleVec2Sub); - moduleBaseDefineMethod(s_vec2Proto, "scale", moduleVec2Scale); - moduleBaseDefineMethod(s_vec2Proto, "lerp", moduleVec2Lerp); - moduleBaseDefineMethod(s_vec2Proto, "distance", moduleVec2Distance); - - moduleBaseFunctionRegister("vec2", moduleVec2Create); + scriptProtoDefineFunc(&MODULE_VEC2_PROTO, "dot", moduleVec2Dot); + scriptProtoDefineFunc(&MODULE_VEC2_PROTO, "length", moduleVec2Length); + scriptProtoDefineFunc(&MODULE_VEC2_PROTO, "lengthSq", moduleVec2LengthSq); + scriptProtoDefineFunc(&MODULE_VEC2_PROTO, "normalize", moduleVec2Normalize); + scriptProtoDefineFunc(&MODULE_VEC2_PROTO, "negate", moduleVec2Negate); + scriptProtoDefineFunc(&MODULE_VEC2_PROTO, "add", moduleVec2Add); + scriptProtoDefineFunc(&MODULE_VEC2_PROTO, "sub", moduleVec2Sub); + scriptProtoDefineFunc(&MODULE_VEC2_PROTO, "scale", moduleVec2Scale); + scriptProtoDefineFunc(&MODULE_VEC2_PROTO, "lerp", moduleVec2Lerp); + scriptProtoDefineFunc(&MODULE_VEC2_PROTO, "distance", moduleVec2Distance); } diff --git a/src/dusk/script/module/math/modulevec3.h b/src/dusk/script/module/math/modulevec3.h index 65afdf6e..11425a04 100644 --- a/src/dusk/script/module/math/modulevec3.h +++ b/src/dusk/script/module/math/modulevec3.h @@ -7,63 +7,54 @@ #pragma once #include "script/module/modulebase.h" -#include "assert/assert.h" +#include "script/scriptproto.h" #include "cglm/cglm.h" -// Native info for heap-allocated vec3 (float[3]) -static void freeVec3Native(void *ptr, jerry_object_native_info_t *info) { - (void)info; - free(ptr); +static scriptproto_t MODULE_VEC3_PROTO; + +// --------------------------------------------------------------------------- +// Constructor +// --------------------------------------------------------------------------- + +moduleBaseFunction(moduleVec3Constructor) { + float_t *ptr = (float_t *)memoryAllocate(sizeof(vec3)); + ptr[0] = (argc >= 1 && jerry_value_is_number(args[0])) ? (float_t)jerry_value_as_number(args[0]) : 0.0f; + ptr[1] = (argc >= 2 && jerry_value_is_number(args[1])) ? (float_t)jerry_value_as_number(args[1]) : 0.0f; + ptr[2] = (argc >= 3 && jerry_value_is_number(args[2])) ? (float_t)jerry_value_as_number(args[2]) : 0.0f; + jerry_object_set_native_ptr(callInfo->this_value, &MODULE_VEC3_PROTO.info, ptr); + return jerry_undefined(); } -static const jerry_object_native_info_t VEC3_NATIVE_INFO = { - .free_cb = freeVec3Native, - .number_of_references = 0, - .offset_of_references = 0 -}; -static jerry_value_t s_vec3Proto = 0; // --------------------------------------------------------------------------- // Property getters / setters // --------------------------------------------------------------------------- moduleBaseFunction(moduleVec3GetX) { - float_t *v = (float_t *)jerry_object_get_native_ptr( - callInfo->this_value, &VEC3_NATIVE_INFO - ); + float_t *v = (float_t *)scriptProtoGetValue(&MODULE_VEC3_PROTO, callInfo->this_value); return v ? jerry_number(v[0]) : jerry_undefined(); } moduleBaseFunction(moduleVec3SetX) { - float_t *v = (float_t *)jerry_object_get_native_ptr( - callInfo->this_value, &VEC3_NATIVE_INFO - ); + float_t *v = (float_t *)scriptProtoGetValue(&MODULE_VEC3_PROTO, callInfo->this_value); if(v && argc > 0) v[0] = (float_t)jerry_value_as_number(args[0]); return jerry_undefined(); } moduleBaseFunction(moduleVec3GetY) { - float_t *v = (float_t *)jerry_object_get_native_ptr( - callInfo->this_value, &VEC3_NATIVE_INFO - ); + float_t *v = (float_t *)scriptProtoGetValue(&MODULE_VEC3_PROTO, callInfo->this_value); return v ? jerry_number(v[1]) : jerry_undefined(); } moduleBaseFunction(moduleVec3SetY) { - float_t *v = (float_t *)jerry_object_get_native_ptr( - callInfo->this_value, &VEC3_NATIVE_INFO - ); + float_t *v = (float_t *)scriptProtoGetValue(&MODULE_VEC3_PROTO, callInfo->this_value); if(v && argc > 0) v[1] = (float_t)jerry_value_as_number(args[0]); return jerry_undefined(); } moduleBaseFunction(moduleVec3GetZ) { - float_t *v = (float_t *)jerry_object_get_native_ptr( - callInfo->this_value, &VEC3_NATIVE_INFO - ); + float_t *v = (float_t *)scriptProtoGetValue(&MODULE_VEC3_PROTO, callInfo->this_value); return v ? jerry_number(v[2]) : jerry_undefined(); } moduleBaseFunction(moduleVec3SetZ) { - float_t *v = (float_t *)jerry_object_get_native_ptr( - callInfo->this_value, &VEC3_NATIVE_INFO - ); + float_t *v = (float_t *)scriptProtoGetValue(&MODULE_VEC3_PROTO, callInfo->this_value); if(v && argc > 0) v[2] = (float_t)jerry_value_as_number(args[0]); return jerry_undefined(); } @@ -74,203 +65,113 @@ moduleBaseFunction(moduleVec3SetZ) { moduleBaseFunction(moduleVec3Dot) { moduleBaseRequireArgs(1); - float_t *a = (float_t *)jerry_object_get_native_ptr( - callInfo->this_value, &VEC3_NATIVE_INFO - ); - if(!a) return moduleBaseThrow("vec3.dot: invalid this"); - float_t *b = (float_t *)jerry_object_get_native_ptr(args[0], &VEC3_NATIVE_INFO); - if(!b) return moduleBaseThrow("vec3.dot: argument must be a vec3"); + float_t *a = (float_t *)scriptProtoGetValue(&MODULE_VEC3_PROTO, callInfo->this_value); + if(!a) return moduleBaseThrow("Vec3.dot: invalid this"); + float_t *b = (float_t *)scriptProtoGetValue(&MODULE_VEC3_PROTO, args[0]); + if(!b) return moduleBaseThrow("Vec3.dot: argument must be a Vec3"); return jerry_number(glm_vec3_dot(a, b)); } moduleBaseFunction(moduleVec3Cross) { moduleBaseRequireArgs(1); - float_t *a = (float_t *)jerry_object_get_native_ptr( - callInfo->this_value, &VEC3_NATIVE_INFO - ); - if(!a) return moduleBaseThrow("vec3.cross: invalid this"); - float_t *b = (float_t *)jerry_object_get_native_ptr(args[0], &VEC3_NATIVE_INFO); - if(!b) return moduleBaseThrow("vec3.cross: argument must be a vec3"); - float_t *r = (float_t *)malloc(sizeof(vec3)); + float_t *a = (float_t *)scriptProtoGetValue(&MODULE_VEC3_PROTO, callInfo->this_value); + if(!a) return moduleBaseThrow("Vec3.cross: invalid this"); + float_t *b = (float_t *)scriptProtoGetValue(&MODULE_VEC3_PROTO, args[0]); + if(!b) return moduleBaseThrow("Vec3.cross: argument must be a Vec3"); + vec3 r; glm_vec3_cross(a, b, r); - jerry_value_t obj = jerry_object(); - jerry_object_set_native_ptr(obj, &VEC3_NATIVE_INFO, r); - jerry_object_set_proto(obj, s_vec3Proto); - return obj; + return scriptProtoCreateValue(&MODULE_VEC3_PROTO, r); } moduleBaseFunction(moduleVec3Length) { - float_t *v = (float_t *)jerry_object_get_native_ptr( - callInfo->this_value, &VEC3_NATIVE_INFO - ); - if(!v) return moduleBaseThrow("vec3.length: invalid this"); + float_t *v = (float_t *)scriptProtoGetValue(&MODULE_VEC3_PROTO, callInfo->this_value); + if(!v) return moduleBaseThrow("Vec3.length: invalid this"); return jerry_number(glm_vec3_norm(v)); } moduleBaseFunction(moduleVec3LengthSq) { - float_t *v = (float_t *)jerry_object_get_native_ptr( - callInfo->this_value, &VEC3_NATIVE_INFO - ); - if(!v) return moduleBaseThrow("vec3.lengthSq: invalid this"); + float_t *v = (float_t *)scriptProtoGetValue(&MODULE_VEC3_PROTO, callInfo->this_value); + if(!v) return moduleBaseThrow("Vec3.lengthSq: invalid this"); return jerry_number(glm_vec3_norm2(v)); } moduleBaseFunction(moduleVec3Normalize) { - float_t *v = (float_t *)jerry_object_get_native_ptr( - callInfo->this_value, &VEC3_NATIVE_INFO - ); - if(!v) return moduleBaseThrow("vec3.normalize: invalid this"); - float_t *r = (float_t *)malloc(sizeof(vec3)); + float_t *v = (float_t *)scriptProtoGetValue(&MODULE_VEC3_PROTO, callInfo->this_value); + if(!v) return moduleBaseThrow("Vec3.normalize: invalid this"); + vec3 r; glm_vec3_normalize_to(v, r); - jerry_value_t obj = jerry_object(); - jerry_object_set_native_ptr(obj, &VEC3_NATIVE_INFO, r); - jerry_object_set_proto(obj, s_vec3Proto); - return obj; + return scriptProtoCreateValue(&MODULE_VEC3_PROTO, r); } moduleBaseFunction(moduleVec3Negate) { - float_t *v = (float_t *)jerry_object_get_native_ptr( - callInfo->this_value, &VEC3_NATIVE_INFO - ); - if(!v) return moduleBaseThrow("vec3.negate: invalid this"); - float_t *r = (float_t *)malloc(sizeof(vec3)); + float_t *v = (float_t *)scriptProtoGetValue(&MODULE_VEC3_PROTO, callInfo->this_value); + if(!v) return moduleBaseThrow("Vec3.negate: invalid this"); + vec3 r; glm_vec3_negate_to(v, r); - jerry_value_t obj = jerry_object(); - jerry_object_set_native_ptr(obj, &VEC3_NATIVE_INFO, r); - jerry_object_set_proto(obj, s_vec3Proto); - return obj; + return scriptProtoCreateValue(&MODULE_VEC3_PROTO, r); } moduleBaseFunction(moduleVec3Add) { moduleBaseRequireArgs(1); - float_t *a = (float_t *)jerry_object_get_native_ptr( - callInfo->this_value, &VEC3_NATIVE_INFO - ); - if(!a) return moduleBaseThrow("vec3.add: invalid this"); - float_t *b = (float_t *)jerry_object_get_native_ptr(args[0], &VEC3_NATIVE_INFO); - if(!b) return moduleBaseThrow("vec3.add: argument must be a vec3"); - float_t *r = (float_t *)malloc(sizeof(vec3)); + float_t *a = (float_t *)scriptProtoGetValue(&MODULE_VEC3_PROTO, callInfo->this_value); + if(!a) return moduleBaseThrow("Vec3.add: invalid this"); + float_t *b = (float_t *)scriptProtoGetValue(&MODULE_VEC3_PROTO, args[0]); + if(!b) return moduleBaseThrow("Vec3.add: argument must be a Vec3"); + vec3 r; glm_vec3_add(a, b, r); - jerry_value_t obj = jerry_object(); - jerry_object_set_native_ptr(obj, &VEC3_NATIVE_INFO, r); - jerry_object_set_proto(obj, s_vec3Proto); - return obj; + return scriptProtoCreateValue(&MODULE_VEC3_PROTO, r); } moduleBaseFunction(moduleVec3Sub) { moduleBaseRequireArgs(1); - float_t *a = (float_t *)jerry_object_get_native_ptr( - callInfo->this_value, &VEC3_NATIVE_INFO - ); - if(!a) return moduleBaseThrow("vec3.sub: invalid this"); - float_t *b = (float_t *)jerry_object_get_native_ptr(args[0], &VEC3_NATIVE_INFO); - if(!b) return moduleBaseThrow("vec3.sub: argument must be a vec3"); - float_t *r = (float_t *)malloc(sizeof(vec3)); + float_t *a = (float_t *)scriptProtoGetValue(&MODULE_VEC3_PROTO, callInfo->this_value); + if(!a) return moduleBaseThrow("Vec3.sub: invalid this"); + float_t *b = (float_t *)scriptProtoGetValue(&MODULE_VEC3_PROTO, args[0]); + if(!b) return moduleBaseThrow("Vec3.sub: argument must be a Vec3"); + vec3 r; glm_vec3_sub(a, b, r); - jerry_value_t obj = jerry_object(); - jerry_object_set_native_ptr(obj, &VEC3_NATIVE_INFO, r); - jerry_object_set_proto(obj, s_vec3Proto); - return obj; + return scriptProtoCreateValue(&MODULE_VEC3_PROTO, r); } moduleBaseFunction(moduleVec3Scale) { - moduleBaseRequireArgs(1); - moduleBaseRequireNumber(0); - float_t *v = (float_t *)jerry_object_get_native_ptr( - callInfo->this_value, &VEC3_NATIVE_INFO - ); - if(!v) return moduleBaseThrow("vec3.scale: invalid this"); - float_t s = (float_t)jerry_value_as_number(args[0]); - float_t *r = (float_t *)malloc(sizeof(vec3)); - glm_vec3_scale(v, s, r); - jerry_value_t obj = jerry_object(); - jerry_object_set_native_ptr(obj, &VEC3_NATIVE_INFO, r); - jerry_object_set_proto(obj, s_vec3Proto); - return obj; + moduleBaseRequireArgs(1); moduleBaseRequireNumber(0); + float_t *v = (float_t *)scriptProtoGetValue(&MODULE_VEC3_PROTO, callInfo->this_value); + if(!v) return moduleBaseThrow("Vec3.scale: invalid this"); + vec3 r; + glm_vec3_scale(v, (float_t)jerry_value_as_number(args[0]), r); + return scriptProtoCreateValue(&MODULE_VEC3_PROTO, r); } moduleBaseFunction(moduleVec3Lerp) { - moduleBaseRequireArgs(2); - moduleBaseRequireNumber(1); - float_t *a = (float_t *)jerry_object_get_native_ptr( - callInfo->this_value, &VEC3_NATIVE_INFO - ); - if(!a) return moduleBaseThrow("vec3.lerp: invalid this"); - float_t *b = (float_t *)jerry_object_get_native_ptr(args[0], &VEC3_NATIVE_INFO); - if(!b) return moduleBaseThrow("vec3.lerp: first argument must be a vec3"); - float_t t = (float_t)jerry_value_as_number(args[1]); - float_t *r = (float_t *)malloc(sizeof(vec3)); - glm_vec3_lerp(a, b, t, r); - jerry_value_t obj = jerry_object(); - jerry_object_set_native_ptr(obj, &VEC3_NATIVE_INFO, r); - jerry_object_set_proto(obj, s_vec3Proto); - return obj; + moduleBaseRequireArgs(2); moduleBaseRequireNumber(1); + float_t *a = (float_t *)scriptProtoGetValue(&MODULE_VEC3_PROTO, callInfo->this_value); + if(!a) return moduleBaseThrow("Vec3.lerp: invalid this"); + float_t *b = (float_t *)scriptProtoGetValue(&MODULE_VEC3_PROTO, args[0]); + if(!b) return moduleBaseThrow("Vec3.lerp: first argument must be a Vec3"); + vec3 r; + glm_vec3_lerp(a, b, (float_t)jerry_value_as_number(args[1]), r); + return scriptProtoCreateValue(&MODULE_VEC3_PROTO, r); } moduleBaseFunction(moduleVec3Distance) { moduleBaseRequireArgs(1); - float_t *a = (float_t *)jerry_object_get_native_ptr( - callInfo->this_value, &VEC3_NATIVE_INFO - ); - if(!a) return moduleBaseThrow("vec3.distance: invalid this"); - float_t *b = (float_t *)jerry_object_get_native_ptr(args[0], &VEC3_NATIVE_INFO); - if(!b) return moduleBaseThrow("vec3.distance: argument must be a vec3"); + float_t *a = (float_t *)scriptProtoGetValue(&MODULE_VEC3_PROTO, callInfo->this_value); + if(!a) return moduleBaseThrow("Vec3.distance: invalid this"); + float_t *b = (float_t *)scriptProtoGetValue(&MODULE_VEC3_PROTO, args[0]); + if(!b) return moduleBaseThrow("Vec3.distance: argument must be a Vec3"); return jerry_number(glm_vec3_distance(a, b)); } // --------------------------------------------------------------------------- -// Constructor +// Helpers for use by other modules // --------------------------------------------------------------------------- -moduleBaseFunction(moduleVec3Create) { - moduleBaseRequireArgs(3); - moduleBaseRequireNumber(0); - moduleBaseRequireNumber(1); - moduleBaseRequireNumber(2); - float_t *v = (float_t *)malloc(sizeof(vec3)); - v[0] = (float_t)jerry_value_as_number(args[0]); - v[1] = (float_t)jerry_value_as_number(args[1]); - v[2] = (float_t)jerry_value_as_number(args[2]); - jerry_value_t obj = jerry_object(); - jerry_object_set_native_ptr(obj, &VEC3_NATIVE_INFO, v); - jerry_object_set_proto(obj, s_vec3Proto); - return obj; -} - -// --------------------------------------------------------------------------- -// Helper: push a cglm vec3 as a new JS object -// --------------------------------------------------------------------------- - -/** - * Wraps a copy of a cglm vec3 as a new JerryScript object. - * - * @param v Source float[3] to copy. - * @return Owned jerry_value_t with native ptr set. - */ static inline jerry_value_t moduleVec3Push(const float_t *v) { - float_t *copy = (float_t *)malloc(sizeof(vec3)); - copy[0] = v[0]; - copy[1] = v[1]; - copy[2] = v[2]; - jerry_value_t obj = jerry_object(); - jerry_object_set_native_ptr(obj, &VEC3_NATIVE_INFO, copy); - jerry_object_set_proto(obj, s_vec3Proto); - return obj; + return scriptProtoCreateValue(&MODULE_VEC3_PROTO, v); } -// --------------------------------------------------------------------------- -// Helper: extract vec3 from a JS object -// --------------------------------------------------------------------------- - -/** - * Reads a JerryScript vec3 object into an existing float[3]. - * - * @param val JS value to read from. - * @param out Destination float[3]. - * @return true if val carries a valid vec3 native ptr. - */ static inline bool_t moduleVec3Check(jerry_value_t val, float_t *out) { - float_t *v = (float_t *)jerry_object_get_native_ptr(val, &VEC3_NATIVE_INFO); + float_t *v = (float_t *)scriptProtoGetValue(&MODULE_VEC3_PROTO, val); if(!v) return false; out[0] = v[0]; out[1] = v[1]; @@ -282,28 +183,22 @@ static inline bool_t moduleVec3Check(jerry_value_t val, float_t *out) { // Module init // --------------------------------------------------------------------------- -/** - * Creates the vec3 prototype with x/y/z getter-setter properties and all - * methods, then registers the global vec3() constructor. - */ static void moduleVec3(void) { - s_vec3Proto = jerry_object(); + scriptProtoInit(&MODULE_VEC3_PROTO, "Vec3", sizeof(vec3), moduleVec3Constructor); - moduleBaseDefineProperty(s_vec3Proto, "x", moduleVec3GetX, moduleVec3SetX); - moduleBaseDefineProperty(s_vec3Proto, "y", moduleVec3GetY, moduleVec3SetY); - moduleBaseDefineProperty(s_vec3Proto, "z", moduleVec3GetZ, moduleVec3SetZ); + scriptProtoDefineProp(&MODULE_VEC3_PROTO, "x", moduleVec3GetX, moduleVec3SetX); + scriptProtoDefineProp(&MODULE_VEC3_PROTO, "y", moduleVec3GetY, moduleVec3SetY); + scriptProtoDefineProp(&MODULE_VEC3_PROTO, "z", moduleVec3GetZ, moduleVec3SetZ); - moduleBaseDefineMethod(s_vec3Proto, "dot", moduleVec3Dot); - moduleBaseDefineMethod(s_vec3Proto, "cross", moduleVec3Cross); - moduleBaseDefineMethod(s_vec3Proto, "length", moduleVec3Length); - moduleBaseDefineMethod(s_vec3Proto, "lengthSq", moduleVec3LengthSq); - moduleBaseDefineMethod(s_vec3Proto, "normalize", moduleVec3Normalize); - moduleBaseDefineMethod(s_vec3Proto, "negate", moduleVec3Negate); - moduleBaseDefineMethod(s_vec3Proto, "add", moduleVec3Add); - moduleBaseDefineMethod(s_vec3Proto, "sub", moduleVec3Sub); - moduleBaseDefineMethod(s_vec3Proto, "scale", moduleVec3Scale); - moduleBaseDefineMethod(s_vec3Proto, "lerp", moduleVec3Lerp); - moduleBaseDefineMethod(s_vec3Proto, "distance", moduleVec3Distance); - - moduleBaseFunctionRegister("vec3", moduleVec3Create); + scriptProtoDefineFunc(&MODULE_VEC3_PROTO, "dot", moduleVec3Dot); + scriptProtoDefineFunc(&MODULE_VEC3_PROTO, "cross", moduleVec3Cross); + scriptProtoDefineFunc(&MODULE_VEC3_PROTO, "length", moduleVec3Length); + scriptProtoDefineFunc(&MODULE_VEC3_PROTO, "lengthSq", moduleVec3LengthSq); + scriptProtoDefineFunc(&MODULE_VEC3_PROTO, "normalize", moduleVec3Normalize); + scriptProtoDefineFunc(&MODULE_VEC3_PROTO, "negate", moduleVec3Negate); + scriptProtoDefineFunc(&MODULE_VEC3_PROTO, "add", moduleVec3Add); + scriptProtoDefineFunc(&MODULE_VEC3_PROTO, "sub", moduleVec3Sub); + scriptProtoDefineFunc(&MODULE_VEC3_PROTO, "scale", moduleVec3Scale); + scriptProtoDefineFunc(&MODULE_VEC3_PROTO, "lerp", moduleVec3Lerp); + scriptProtoDefineFunc(&MODULE_VEC3_PROTO, "distance", moduleVec3Distance); } diff --git a/src/dusk/script/module/math/modulevec4.h b/src/dusk/script/module/math/modulevec4.h index 7a808eb6..37c104dc 100644 --- a/src/dusk/script/module/math/modulevec4.h +++ b/src/dusk/script/module/math/modulevec4.h @@ -7,134 +7,106 @@ #pragma once #include "script/module/modulebase.h" -#include "assert/assert.h" +#include "script/scriptproto.h" #include "cglm/cglm.h" -// Native info for heap-allocated vec4 (float[4]) -static void freeVec4Native(void *ptr, jerry_object_native_info_t *info) { - (void)info; - free(ptr); -} -static const jerry_object_native_info_t VEC4_NATIVE_INFO = { - .free_cb = freeVec4Native, - .number_of_references = 0, - .offset_of_references = 0 -}; -static jerry_value_t s_vec4Proto = 0; +static scriptproto_t MODULE_VEC4_PROTO; // --------------------------------------------------------------------------- -// Property getters / setters (x/u0, y/v0, z/u1, w/v1) +// Constructor +// --------------------------------------------------------------------------- + +moduleBaseFunction(moduleVec4Constructor) { + float_t *ptr = (float_t *)memoryAllocate(sizeof(vec4)); + ptr[0] = (argc >= 1 && jerry_value_is_number(args[0])) ? (float_t)jerry_value_as_number(args[0]) : 0.0f; + ptr[1] = (argc >= 2 && jerry_value_is_number(args[1])) ? (float_t)jerry_value_as_number(args[1]) : 0.0f; + ptr[2] = (argc >= 3 && jerry_value_is_number(args[2])) ? (float_t)jerry_value_as_number(args[2]) : 0.0f; + ptr[3] = (argc >= 4 && jerry_value_is_number(args[3])) ? (float_t)jerry_value_as_number(args[3]) : 0.0f; + jerry_object_set_native_ptr(callInfo->this_value, &MODULE_VEC4_PROTO.info, ptr); + return jerry_undefined(); +} + +// --------------------------------------------------------------------------- +// Property getters / setters (x/y/z/w and u0/v0/u1/v1 aliases) // --------------------------------------------------------------------------- moduleBaseFunction(moduleVec4GetX) { - float_t *v = (float_t *)jerry_object_get_native_ptr( - callInfo->this_value, &VEC4_NATIVE_INFO - ); + float_t *v = (float_t *)scriptProtoGetValue(&MODULE_VEC4_PROTO, callInfo->this_value); return v ? jerry_number(v[0]) : jerry_undefined(); } moduleBaseFunction(moduleVec4SetX) { - float_t *v = (float_t *)jerry_object_get_native_ptr( - callInfo->this_value, &VEC4_NATIVE_INFO - ); + float_t *v = (float_t *)scriptProtoGetValue(&MODULE_VEC4_PROTO, callInfo->this_value); if(v && argc > 0) v[0] = (float_t)jerry_value_as_number(args[0]); return jerry_undefined(); } moduleBaseFunction(moduleVec4GetY) { - float_t *v = (float_t *)jerry_object_get_native_ptr( - callInfo->this_value, &VEC4_NATIVE_INFO - ); + float_t *v = (float_t *)scriptProtoGetValue(&MODULE_VEC4_PROTO, callInfo->this_value); return v ? jerry_number(v[1]) : jerry_undefined(); } moduleBaseFunction(moduleVec4SetY) { - float_t *v = (float_t *)jerry_object_get_native_ptr( - callInfo->this_value, &VEC4_NATIVE_INFO - ); + float_t *v = (float_t *)scriptProtoGetValue(&MODULE_VEC4_PROTO, callInfo->this_value); if(v && argc > 0) v[1] = (float_t)jerry_value_as_number(args[0]); return jerry_undefined(); } moduleBaseFunction(moduleVec4GetZ) { - float_t *v = (float_t *)jerry_object_get_native_ptr( - callInfo->this_value, &VEC4_NATIVE_INFO - ); + float_t *v = (float_t *)scriptProtoGetValue(&MODULE_VEC4_PROTO, callInfo->this_value); return v ? jerry_number(v[2]) : jerry_undefined(); } moduleBaseFunction(moduleVec4SetZ) { - float_t *v = (float_t *)jerry_object_get_native_ptr( - callInfo->this_value, &VEC4_NATIVE_INFO - ); + float_t *v = (float_t *)scriptProtoGetValue(&MODULE_VEC4_PROTO, callInfo->this_value); if(v && argc > 0) v[2] = (float_t)jerry_value_as_number(args[0]); return jerry_undefined(); } moduleBaseFunction(moduleVec4GetW) { - float_t *v = (float_t *)jerry_object_get_native_ptr( - callInfo->this_value, &VEC4_NATIVE_INFO - ); + float_t *v = (float_t *)scriptProtoGetValue(&MODULE_VEC4_PROTO, callInfo->this_value); return v ? jerry_number(v[3]) : jerry_undefined(); } moduleBaseFunction(moduleVec4SetW) { - float_t *v = (float_t *)jerry_object_get_native_ptr( - callInfo->this_value, &VEC4_NATIVE_INFO - ); + float_t *v = (float_t *)scriptProtoGetValue(&MODULE_VEC4_PROTO, callInfo->this_value); if(v && argc > 0) v[3] = (float_t)jerry_value_as_number(args[0]); return jerry_undefined(); } -// u0/v0/u1/v1 aliases share the same backing floats +// u0/v0/u1/v1 aliases share the same backing floats as x/y/z/w moduleBaseFunction(moduleVec4GetU0) { - float_t *v = (float_t *)jerry_object_get_native_ptr( - callInfo->this_value, &VEC4_NATIVE_INFO - ); + float_t *v = (float_t *)scriptProtoGetValue(&MODULE_VEC4_PROTO, callInfo->this_value); return v ? jerry_number(v[0]) : jerry_undefined(); } moduleBaseFunction(moduleVec4SetU0) { - float_t *v = (float_t *)jerry_object_get_native_ptr( - callInfo->this_value, &VEC4_NATIVE_INFO - ); + float_t *v = (float_t *)scriptProtoGetValue(&MODULE_VEC4_PROTO, callInfo->this_value); if(v && argc > 0) v[0] = (float_t)jerry_value_as_number(args[0]); return jerry_undefined(); } moduleBaseFunction(moduleVec4GetV0) { - float_t *v = (float_t *)jerry_object_get_native_ptr( - callInfo->this_value, &VEC4_NATIVE_INFO - ); + float_t *v = (float_t *)scriptProtoGetValue(&MODULE_VEC4_PROTO, callInfo->this_value); return v ? jerry_number(v[1]) : jerry_undefined(); } moduleBaseFunction(moduleVec4SetV0) { - float_t *v = (float_t *)jerry_object_get_native_ptr( - callInfo->this_value, &VEC4_NATIVE_INFO - ); + float_t *v = (float_t *)scriptProtoGetValue(&MODULE_VEC4_PROTO, callInfo->this_value); if(v && argc > 0) v[1] = (float_t)jerry_value_as_number(args[0]); return jerry_undefined(); } moduleBaseFunction(moduleVec4GetU1) { - float_t *v = (float_t *)jerry_object_get_native_ptr( - callInfo->this_value, &VEC4_NATIVE_INFO - ); + float_t *v = (float_t *)scriptProtoGetValue(&MODULE_VEC4_PROTO, callInfo->this_value); return v ? jerry_number(v[2]) : jerry_undefined(); } moduleBaseFunction(moduleVec4SetU1) { - float_t *v = (float_t *)jerry_object_get_native_ptr( - callInfo->this_value, &VEC4_NATIVE_INFO - ); + float_t *v = (float_t *)scriptProtoGetValue(&MODULE_VEC4_PROTO, callInfo->this_value); if(v && argc > 0) v[2] = (float_t)jerry_value_as_number(args[0]); return jerry_undefined(); } moduleBaseFunction(moduleVec4GetV1) { - float_t *v = (float_t *)jerry_object_get_native_ptr( - callInfo->this_value, &VEC4_NATIVE_INFO - ); + float_t *v = (float_t *)scriptProtoGetValue(&MODULE_VEC4_PROTO, callInfo->this_value); return v ? jerry_number(v[3]) : jerry_undefined(); } moduleBaseFunction(moduleVec4SetV1) { - float_t *v = (float_t *)jerry_object_get_native_ptr( - callInfo->this_value, &VEC4_NATIVE_INFO - ); + float_t *v = (float_t *)scriptProtoGetValue(&MODULE_VEC4_PROTO, callInfo->this_value); if(v && argc > 0) v[3] = (float_t)jerry_value_as_number(args[0]); return jerry_undefined(); } @@ -145,179 +117,93 @@ moduleBaseFunction(moduleVec4SetV1) { moduleBaseFunction(moduleVec4Dot) { moduleBaseRequireArgs(1); - float_t *a = (float_t *)jerry_object_get_native_ptr( - callInfo->this_value, &VEC4_NATIVE_INFO - ); - if(!a) return moduleBaseThrow("vec4.dot: invalid this"); - float_t *b = (float_t *)jerry_object_get_native_ptr(args[0], &VEC4_NATIVE_INFO); - if(!b) return moduleBaseThrow("vec4.dot: argument must be a vec4"); + float_t *a = (float_t *)scriptProtoGetValue(&MODULE_VEC4_PROTO, callInfo->this_value); + if(!a) return moduleBaseThrow("Vec4.dot: invalid this"); + float_t *b = (float_t *)scriptProtoGetValue(&MODULE_VEC4_PROTO, args[0]); + if(!b) return moduleBaseThrow("Vec4.dot: argument must be a Vec4"); return jerry_number(glm_vec4_dot(a, b)); } moduleBaseFunction(moduleVec4Length) { - float_t *v = (float_t *)jerry_object_get_native_ptr( - callInfo->this_value, &VEC4_NATIVE_INFO - ); - if(!v) return moduleBaseThrow("vec4.length: invalid this"); + float_t *v = (float_t *)scriptProtoGetValue(&MODULE_VEC4_PROTO, callInfo->this_value); + if(!v) return moduleBaseThrow("Vec4.length: invalid this"); return jerry_number(glm_vec4_norm(v)); } moduleBaseFunction(moduleVec4LengthSq) { - float_t *v = (float_t *)jerry_object_get_native_ptr( - callInfo->this_value, &VEC4_NATIVE_INFO - ); - if(!v) return moduleBaseThrow("vec4.lengthSq: invalid this"); + float_t *v = (float_t *)scriptProtoGetValue(&MODULE_VEC4_PROTO, callInfo->this_value); + if(!v) return moduleBaseThrow("Vec4.lengthSq: invalid this"); return jerry_number(glm_vec4_norm2(v)); } moduleBaseFunction(moduleVec4Normalize) { - float_t *v = (float_t *)jerry_object_get_native_ptr( - callInfo->this_value, &VEC4_NATIVE_INFO - ); - if(!v) return moduleBaseThrow("vec4.normalize: invalid this"); - float_t *r = (float_t *)malloc(sizeof(vec4)); + float_t *v = (float_t *)scriptProtoGetValue(&MODULE_VEC4_PROTO, callInfo->this_value); + if(!v) return moduleBaseThrow("Vec4.normalize: invalid this"); + vec4 r; glm_vec4_normalize_to(v, r); - jerry_value_t obj = jerry_object(); - jerry_object_set_native_ptr(obj, &VEC4_NATIVE_INFO, r); - jerry_object_set_proto(obj, s_vec4Proto); - return obj; + return scriptProtoCreateValue(&MODULE_VEC4_PROTO, r); } moduleBaseFunction(moduleVec4Negate) { - float_t *v = (float_t *)jerry_object_get_native_ptr( - callInfo->this_value, &VEC4_NATIVE_INFO - ); - if(!v) return moduleBaseThrow("vec4.negate: invalid this"); - float_t *r = (float_t *)malloc(sizeof(vec4)); + float_t *v = (float_t *)scriptProtoGetValue(&MODULE_VEC4_PROTO, callInfo->this_value); + if(!v) return moduleBaseThrow("Vec4.negate: invalid this"); + vec4 r; glm_vec4_negate_to(v, r); - jerry_value_t obj = jerry_object(); - jerry_object_set_native_ptr(obj, &VEC4_NATIVE_INFO, r); - jerry_object_set_proto(obj, s_vec4Proto); - return obj; + return scriptProtoCreateValue(&MODULE_VEC4_PROTO, r); } moduleBaseFunction(moduleVec4Add) { moduleBaseRequireArgs(1); - float_t *a = (float_t *)jerry_object_get_native_ptr( - callInfo->this_value, &VEC4_NATIVE_INFO - ); - if(!a) return moduleBaseThrow("vec4.add: invalid this"); - float_t *b = (float_t *)jerry_object_get_native_ptr(args[0], &VEC4_NATIVE_INFO); - if(!b) return moduleBaseThrow("vec4.add: argument must be a vec4"); - float_t *r = (float_t *)malloc(sizeof(vec4)); + float_t *a = (float_t *)scriptProtoGetValue(&MODULE_VEC4_PROTO, callInfo->this_value); + if(!a) return moduleBaseThrow("Vec4.add: invalid this"); + float_t *b = (float_t *)scriptProtoGetValue(&MODULE_VEC4_PROTO, args[0]); + if(!b) return moduleBaseThrow("Vec4.add: argument must be a Vec4"); + vec4 r; glm_vec4_add(a, b, r); - jerry_value_t obj = jerry_object(); - jerry_object_set_native_ptr(obj, &VEC4_NATIVE_INFO, r); - jerry_object_set_proto(obj, s_vec4Proto); - return obj; + return scriptProtoCreateValue(&MODULE_VEC4_PROTO, r); } moduleBaseFunction(moduleVec4Sub) { moduleBaseRequireArgs(1); - float_t *a = (float_t *)jerry_object_get_native_ptr( - callInfo->this_value, &VEC4_NATIVE_INFO - ); - if(!a) return moduleBaseThrow("vec4.sub: invalid this"); - float_t *b = (float_t *)jerry_object_get_native_ptr(args[0], &VEC4_NATIVE_INFO); - if(!b) return moduleBaseThrow("vec4.sub: argument must be a vec4"); - float_t *r = (float_t *)malloc(sizeof(vec4)); + float_t *a = (float_t *)scriptProtoGetValue(&MODULE_VEC4_PROTO, callInfo->this_value); + if(!a) return moduleBaseThrow("Vec4.sub: invalid this"); + float_t *b = (float_t *)scriptProtoGetValue(&MODULE_VEC4_PROTO, args[0]); + if(!b) return moduleBaseThrow("Vec4.sub: argument must be a Vec4"); + vec4 r; glm_vec4_sub(a, b, r); - jerry_value_t obj = jerry_object(); - jerry_object_set_native_ptr(obj, &VEC4_NATIVE_INFO, r); - jerry_object_set_proto(obj, s_vec4Proto); - return obj; + return scriptProtoCreateValue(&MODULE_VEC4_PROTO, r); } moduleBaseFunction(moduleVec4Scale) { - moduleBaseRequireArgs(1); - moduleBaseRequireNumber(0); - float_t *v = (float_t *)jerry_object_get_native_ptr( - callInfo->this_value, &VEC4_NATIVE_INFO - ); - if(!v) return moduleBaseThrow("vec4.scale: invalid this"); - float_t s = (float_t)jerry_value_as_number(args[0]); - float_t *r = (float_t *)malloc(sizeof(vec4)); - glm_vec4_scale(v, s, r); - jerry_value_t obj = jerry_object(); - jerry_object_set_native_ptr(obj, &VEC4_NATIVE_INFO, r); - jerry_object_set_proto(obj, s_vec4Proto); - return obj; + moduleBaseRequireArgs(1); moduleBaseRequireNumber(0); + float_t *v = (float_t *)scriptProtoGetValue(&MODULE_VEC4_PROTO, callInfo->this_value); + if(!v) return moduleBaseThrow("Vec4.scale: invalid this"); + vec4 r; + glm_vec4_scale(v, (float_t)jerry_value_as_number(args[0]), r); + return scriptProtoCreateValue(&MODULE_VEC4_PROTO, r); } moduleBaseFunction(moduleVec4Lerp) { - moduleBaseRequireArgs(2); - moduleBaseRequireNumber(1); - float_t *a = (float_t *)jerry_object_get_native_ptr( - callInfo->this_value, &VEC4_NATIVE_INFO - ); - if(!a) return moduleBaseThrow("vec4.lerp: invalid this"); - float_t *b = (float_t *)jerry_object_get_native_ptr(args[0], &VEC4_NATIVE_INFO); - if(!b) return moduleBaseThrow("vec4.lerp: first argument must be a vec4"); - float_t t = (float_t)jerry_value_as_number(args[1]); - float_t *r = (float_t *)malloc(sizeof(vec4)); - glm_vec4_lerp(a, b, t, r); - jerry_value_t obj = jerry_object(); - jerry_object_set_native_ptr(obj, &VEC4_NATIVE_INFO, r); - jerry_object_set_proto(obj, s_vec4Proto); - return obj; + moduleBaseRequireArgs(2); moduleBaseRequireNumber(1); + float_t *a = (float_t *)scriptProtoGetValue(&MODULE_VEC4_PROTO, callInfo->this_value); + if(!a) return moduleBaseThrow("Vec4.lerp: invalid this"); + float_t *b = (float_t *)scriptProtoGetValue(&MODULE_VEC4_PROTO, args[0]); + if(!b) return moduleBaseThrow("Vec4.lerp: first argument must be a Vec4"); + vec4 r; + glm_vec4_lerp(a, b, (float_t)jerry_value_as_number(args[1]), r); + return scriptProtoCreateValue(&MODULE_VEC4_PROTO, r); } // --------------------------------------------------------------------------- -// Constructor +// Helpers for use by other modules // --------------------------------------------------------------------------- -moduleBaseFunction(moduleVec4Create) { - moduleBaseRequireArgs(4); - moduleBaseRequireNumber(0); - moduleBaseRequireNumber(1); - moduleBaseRequireNumber(2); - moduleBaseRequireNumber(3); - float_t *v = (float_t *)malloc(sizeof(vec4)); - v[0] = (float_t)jerry_value_as_number(args[0]); - v[1] = (float_t)jerry_value_as_number(args[1]); - v[2] = (float_t)jerry_value_as_number(args[2]); - v[3] = (float_t)jerry_value_as_number(args[3]); - jerry_value_t obj = jerry_object(); - jerry_object_set_native_ptr(obj, &VEC4_NATIVE_INFO, v); - jerry_object_set_proto(obj, s_vec4Proto); - return obj; -} - -// --------------------------------------------------------------------------- -// Helper: push a cglm vec4 as a new JS object -// --------------------------------------------------------------------------- - -/** - * Wraps a copy of a cglm vec4 as a new JerryScript object. - * - * @param v Source float[4] to copy. - * @return Owned jerry_value_t with native ptr set. - */ static inline jerry_value_t moduleVec4Push(const float_t *v) { - float_t *copy = (float_t *)malloc(sizeof(vec4)); - copy[0] = v[0]; - copy[1] = v[1]; - copy[2] = v[2]; - copy[3] = v[3]; - jerry_value_t obj = jerry_object(); - jerry_object_set_native_ptr(obj, &VEC4_NATIVE_INFO, copy); - jerry_object_set_proto(obj, s_vec4Proto); - return obj; + return scriptProtoCreateValue(&MODULE_VEC4_PROTO, v); } -// --------------------------------------------------------------------------- -// Helper: extract vec4 from a JS object -// --------------------------------------------------------------------------- - -/** - * Reads a JerryScript vec4 object into an existing float[4]. - * - * @param val JS value to read from. - * @param out Destination float[4]. - * @return true if val carries a valid vec4 native ptr. - */ static inline bool_t moduleVec4Check(jerry_value_t val, float_t *out) { - float_t *v = (float_t *)jerry_object_get_native_ptr(val, &VEC4_NATIVE_INFO); + float_t *v = (float_t *)scriptProtoGetValue(&MODULE_VEC4_PROTO, val); if(!v) return false; out[0] = v[0]; out[1] = v[1]; @@ -330,35 +216,25 @@ static inline bool_t moduleVec4Check(jerry_value_t val, float_t *out) { // Module init // --------------------------------------------------------------------------- -/** - * Creates the vec4 prototype with x/y/z/w (and u0/v0/u1/v1 alias) - * getter-setter properties and all methods, then registers the global - * vec4() constructor. - */ static void moduleVec4(void) { - s_vec4Proto = jerry_object(); + scriptProtoInit(&MODULE_VEC4_PROTO, "Vec4", sizeof(vec4), moduleVec4Constructor); - // Primary component names - moduleBaseDefineProperty(s_vec4Proto, "x", moduleVec4GetX, moduleVec4SetX); - moduleBaseDefineProperty(s_vec4Proto, "y", moduleVec4GetY, moduleVec4SetY); - moduleBaseDefineProperty(s_vec4Proto, "z", moduleVec4GetZ, moduleVec4SetZ); - moduleBaseDefineProperty(s_vec4Proto, "w", moduleVec4GetW, moduleVec4SetW); + scriptProtoDefineProp(&MODULE_VEC4_PROTO, "x", moduleVec4GetX, moduleVec4SetX); + scriptProtoDefineProp(&MODULE_VEC4_PROTO, "y", moduleVec4GetY, moduleVec4SetY); + scriptProtoDefineProp(&MODULE_VEC4_PROTO, "z", moduleVec4GetZ, moduleVec4SetZ); + scriptProtoDefineProp(&MODULE_VEC4_PROTO, "w", moduleVec4GetW, moduleVec4SetW); + scriptProtoDefineProp(&MODULE_VEC4_PROTO, "u0", moduleVec4GetU0, moduleVec4SetU0); + scriptProtoDefineProp(&MODULE_VEC4_PROTO, "v0", moduleVec4GetV0, moduleVec4SetV0); + scriptProtoDefineProp(&MODULE_VEC4_PROTO, "u1", moduleVec4GetU1, moduleVec4SetU1); + scriptProtoDefineProp(&MODULE_VEC4_PROTO, "v1", moduleVec4GetV1, moduleVec4SetV1); - // UV alias names (same backing components) - moduleBaseDefineProperty(s_vec4Proto, "u0", moduleVec4GetU0, moduleVec4SetU0); - moduleBaseDefineProperty(s_vec4Proto, "v0", moduleVec4GetV0, moduleVec4SetV0); - moduleBaseDefineProperty(s_vec4Proto, "u1", moduleVec4GetU1, moduleVec4SetU1); - moduleBaseDefineProperty(s_vec4Proto, "v1", moduleVec4GetV1, moduleVec4SetV1); - - moduleBaseDefineMethod(s_vec4Proto, "dot", moduleVec4Dot); - moduleBaseDefineMethod(s_vec4Proto, "length", moduleVec4Length); - moduleBaseDefineMethod(s_vec4Proto, "lengthSq", moduleVec4LengthSq); - moduleBaseDefineMethod(s_vec4Proto, "normalize", moduleVec4Normalize); - moduleBaseDefineMethod(s_vec4Proto, "negate", moduleVec4Negate); - moduleBaseDefineMethod(s_vec4Proto, "add", moduleVec4Add); - moduleBaseDefineMethod(s_vec4Proto, "sub", moduleVec4Sub); - moduleBaseDefineMethod(s_vec4Proto, "scale", moduleVec4Scale); - moduleBaseDefineMethod(s_vec4Proto, "lerp", moduleVec4Lerp); - - moduleBaseFunctionRegister("vec4", moduleVec4Create); + scriptProtoDefineFunc(&MODULE_VEC4_PROTO, "dot", moduleVec4Dot); + scriptProtoDefineFunc(&MODULE_VEC4_PROTO, "length", moduleVec4Length); + scriptProtoDefineFunc(&MODULE_VEC4_PROTO, "lengthSq", moduleVec4LengthSq); + scriptProtoDefineFunc(&MODULE_VEC4_PROTO, "normalize", moduleVec4Normalize); + scriptProtoDefineFunc(&MODULE_VEC4_PROTO, "negate", moduleVec4Negate); + scriptProtoDefineFunc(&MODULE_VEC4_PROTO, "add", moduleVec4Add); + scriptProtoDefineFunc(&MODULE_VEC4_PROTO, "sub", moduleVec4Sub); + scriptProtoDefineFunc(&MODULE_VEC4_PROTO, "scale", moduleVec4Scale); + scriptProtoDefineFunc(&MODULE_VEC4_PROTO, "lerp", moduleVec4Lerp); }