Better again.

This commit is contained in:
2026-04-29 23:26:21 -05:00
parent ffed626447
commit 010900fe21
12 changed files with 622 additions and 1155 deletions
+10
View File
@@ -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,
+16
View File
@@ -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.
*
@@ -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
);
}
@@ -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
);
}
@@ -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);
}
@@ -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);
@@ -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);
}
+30 -28
View File
@@ -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); \
+76 -174
View File
@@ -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);
}
+79 -173
View File
@@ -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);
}
+90 -195
View File
@@ -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);
}
+97 -221
View File
@@ -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);
}