diff --git a/assets/testentity.js b/assets/testentity.js new file mode 100644 index 00000000..273cd11e --- /dev/null +++ b/assets/testentity.js @@ -0,0 +1,4 @@ +const e = Entity.create(); +const pos = e.add(Component.POSITION); +pos.localPosition = new Vec3(-1, 0, 1); +Console.print('Entity ID: ' + e.toString()); diff --git a/src/dusk/engine/engine.c b/src/dusk/engine/engine.c index ecf91c8f..8f4560e6 100644 --- a/src/dusk/engine/engine.c +++ b/src/dusk/engine/engine.c @@ -47,18 +47,18 @@ errorret_t engineInit(const int32_t argc, const char_t **argv) { errorChain(displayInit()); errorChain(uiInit()); errorChain(uiTextboxInit()); - errorChain(cutsceneInit()); errorChain(sceneInit()); entityManagerInit(); backpackInit(); physicsManagerInit(); errorChain(networkInit()); - errorChain(scriptInit()); - errorChain(scriptExecFile("init.js")); consolePrint("Engine initialized"); + + errorChain(scriptExecFile("init.js")); + sceneSet(SCENE_TYPE_INITIAL); errorOk(); } diff --git a/src/dusk/scene/initial/initialscene.c b/src/dusk/scene/initial/initialscene.c index 67c0aa5f..ce7575d5 100644 --- a/src/dusk/scene/initial/initialscene.c +++ b/src/dusk/scene/initial/initialscene.c @@ -8,25 +8,27 @@ #include "initialscene.h" #include "console/console.h" #include "scene/scene.h" +#include "script/script.h" #include "time/time.h" #include "ui/uiloading.h" void initialSceneInit(void) { consolePrint("Initial scene initialized"); - SCENE.data.initial.timer = 0.0f; - SCENE.data.initial.hiding = false; - uiLoadingShow(NULL, NULL); + errorCatch(errorPrint(scriptExecFile("testentity.js"))); + // SCENE.data.initial.timer = 0.0f; + // SCENE.data.initial.hiding = false; + // uiLoadingShow(NULL, NULL); } errorret_t initialSceneUpdate(void) { - initialscene_t *scene = &SCENE.data.initial; - if(scene->hiding) errorOk(); + // initialscene_t *scene = &SCENE.data.initial; + // if(scene->hiding) errorOk(); - scene->timer += TIME.delta; - if(scene->timer >= INITIAL_SCENE_WAIT) { - scene->hiding = true; - uiLoadingHide(NULL, NULL); - } + // scene->timer += TIME.delta; + // if(scene->timer >= INITIAL_SCENE_WAIT) { + // scene->hiding = true; + // uiLoadingHide(NULL, NULL); + // } errorOk(); } diff --git a/src/dusk/script/module/entity/component/modulecomponentlist.h b/src/dusk/script/module/entity/component/modulecomponentlist.h index f50c4def..02182b7e 100644 --- a/src/dusk/script/module/entity/component/modulecomponentlist.h +++ b/src/dusk/script/module/entity/component/modulecomponentlist.h @@ -6,11 +6,29 @@ */ #pragma once +#include "script/module/entity/modulecomponent.h" +#include "position/moduleposition.h" -/* Include component modules here as they are added. */ +/** + * Returns a typed JS instance for a newly-added component. Falls back to the + * generic Component proto for types that have no specific module yet. + */ +static jerry_value_t moduleComponentListCreateInstance( + const componenttype_t type, + const jscomponent_t *comp +) { + switch(type) { + case COMPONENT_TYPE_POSITION: + return scriptProtoCreateValue(&MODULE_POSITION_PROTO, comp); + default: + return scriptProtoCreateValue(&MODULE_COMPONENT_PROTO, comp); + } +} static void moduleComponentListInit(void) { + modulePositionInit(); } static void moduleComponentListDispose(void) { + modulePositionDispose(); } diff --git a/src/dusk/script/module/entity/component/position/moduleposition.h b/src/dusk/script/module/entity/component/position/moduleposition.h new file mode 100644 index 00000000..85723dc9 --- /dev/null +++ b/src/dusk/script/module/entity/component/position/moduleposition.h @@ -0,0 +1,225 @@ +/** + * Copyright (c) 2026 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#pragma once +#include "script/module/modulebase.h" +#include "script/scriptproto.h" +#include "script/module/math/modulevec3.h" +#include "script/module/entity/modulecomponent.h" +#include "entity/component/display/entityposition.h" + +static scriptproto_t MODULE_POSITION_PROTO; + +moduleBaseFunction(modulePositionCtor) { + (void)callInfo; (void)args; (void)argc; + return moduleBaseThrow("Position cannot be instantiated with new"); +} + +static inline jscomponent_t *modulePositionSelf( + const jerry_call_info_t *callInfo +) { + return (jscomponent_t *)scriptProtoGetValue( + &MODULE_POSITION_PROTO, callInfo->this_value + ); +} + +moduleBaseFunction(modulePositionGetEntity) { + jscomponent_t *c = modulePositionSelf(callInfo); + if(!c) return jerry_undefined(); + return jerry_number((double)c->entityId); +} + +moduleBaseFunction(modulePositionGetId) { + jscomponent_t *c = modulePositionSelf(callInfo); + if(!c) return jerry_undefined(); + return jerry_number((double)c->componentId); +} + +moduleBaseFunction(modulePositionGetLocalPos) { + jscomponent_t *c = modulePositionSelf(callInfo); + if(!c) return jerry_undefined(); + vec3 v; + entityPositionGetLocalPosition(c->entityId, c->componentId, v); + return moduleVec3Push(v); +} + +moduleBaseFunction(modulePositionSetLocalPos) { + moduleBaseRequireArgs(1); + jscomponent_t *c = modulePositionSelf(callInfo); + if(!c) return jerry_undefined(); + float_t *v = moduleVec3From(args[0]); + if(!v) return moduleBaseThrow("Position.localPosition: expected Vec3"); + entityPositionSetLocalPosition(c->entityId, c->componentId, v); + return jerry_undefined(); +} + +moduleBaseFunction(modulePositionGetWorldPos) { + jscomponent_t *c = modulePositionSelf(callInfo); + if(!c) return jerry_undefined(); + vec3 v; + entityPositionGetWorldPosition(c->entityId, c->componentId, v); + return moduleVec3Push(v); +} + +moduleBaseFunction(modulePositionSetWorldPos) { + moduleBaseRequireArgs(1); + jscomponent_t *c = modulePositionSelf(callInfo); + if(!c) return jerry_undefined(); + float_t *v = moduleVec3From(args[0]); + if(!v) return moduleBaseThrow("Position.worldPosition: expected Vec3"); + entityPositionSetWorldPosition(c->entityId, c->componentId, v); + return jerry_undefined(); +} + +moduleBaseFunction(modulePositionGetLocalRot) { + jscomponent_t *c = modulePositionSelf(callInfo); + if(!c) return jerry_undefined(); + vec3 v; + entityPositionGetLocalRotation(c->entityId, c->componentId, v); + return moduleVec3Push(v); +} + +moduleBaseFunction(modulePositionSetLocalRot) { + moduleBaseRequireArgs(1); + jscomponent_t *c = modulePositionSelf(callInfo); + if(!c) return jerry_undefined(); + float_t *v = moduleVec3From(args[0]); + if(!v) return moduleBaseThrow("Position.localRotation: expected Vec3"); + entityPositionSetLocalRotation(c->entityId, c->componentId, v); + return jerry_undefined(); +} + +moduleBaseFunction(modulePositionGetWorldRot) { + jscomponent_t *c = modulePositionSelf(callInfo); + if(!c) return jerry_undefined(); + vec3 v; + entityPositionGetWorldRotation(c->entityId, c->componentId, v); + return moduleVec3Push(v); +} + +moduleBaseFunction(modulePositionSetWorldRot) { + moduleBaseRequireArgs(1); + jscomponent_t *c = modulePositionSelf(callInfo); + if(!c) return jerry_undefined(); + float_t *v = moduleVec3From(args[0]); + if(!v) return moduleBaseThrow("Position.worldRotation: expected Vec3"); + entityPositionSetWorldRotation(c->entityId, c->componentId, v); + return jerry_undefined(); +} + +moduleBaseFunction(modulePositionGetLocalScale) { + jscomponent_t *c = modulePositionSelf(callInfo); + if(!c) return jerry_undefined(); + vec3 v; + entityPositionGetLocalScale(c->entityId, c->componentId, v); + return moduleVec3Push(v); +} + +moduleBaseFunction(modulePositionSetLocalScale) { + moduleBaseRequireArgs(1); + jscomponent_t *c = modulePositionSelf(callInfo); + if(!c) return jerry_undefined(); + float_t *v = moduleVec3From(args[0]); + if(!v) return moduleBaseThrow("Position.localScale: expected Vec3"); + entityPositionSetLocalScale(c->entityId, c->componentId, v); + return jerry_undefined(); +} + +moduleBaseFunction(modulePositionGetWorldScale) { + jscomponent_t *c = modulePositionSelf(callInfo); + if(!c) return jerry_undefined(); + vec3 v; + entityPositionGetWorldScale(c->entityId, c->componentId, v); + return moduleVec3Push(v); +} + +moduleBaseFunction(modulePositionSetWorldScale) { + moduleBaseRequireArgs(1); + jscomponent_t *c = modulePositionSelf(callInfo); + if(!c) return jerry_undefined(); + float_t *v = moduleVec3From(args[0]); + if(!v) return moduleBaseThrow("Position.worldScale: expected Vec3"); + entityPositionSetWorldScale(c->entityId, c->componentId, v); + return jerry_undefined(); +} + +moduleBaseFunction(modulePositionSetParent) { + jscomponent_t *c = modulePositionSelf(callInfo); + if(!c) return jerry_undefined(); + if(argc == 0 || + jerry_value_is_null(args[0]) || + jerry_value_is_undefined(args[0])) { + entityPositionSetParent( + c->entityId, c->componentId, + ENTITY_ID_INVALID, COMPONENT_ID_INVALID + ); + return jerry_undefined(); + } + jscomponent_t *parent = (jscomponent_t *)scriptProtoGetValue( + &MODULE_POSITION_PROTO, args[0] + ); + if(!parent) return moduleBaseThrow("Position.setParent: expected Position or null"); + entityPositionSetParent( + c->entityId, c->componentId, + parent->entityId, parent->componentId + ); + return jerry_undefined(); +} + +moduleBaseFunction(modulePositionToString) { + jscomponent_t *c = modulePositionSelf(callInfo); + if(!c) return jerry_string_sz("Position:invalid"); + char_t buf[32]; + snprintf(buf, sizeof(buf), "Position(%u)", (unsigned)c->componentId); + return jerry_string_sz(buf); +} + +static void modulePositionInit(void) { + scriptProtoInit( + &MODULE_POSITION_PROTO, "Position", + sizeof(jscomponent_t), modulePositionCtor + ); + + scriptProtoDefineProp( + &MODULE_POSITION_PROTO, "entity", modulePositionGetEntity, NULL + ); + scriptProtoDefineProp( + &MODULE_POSITION_PROTO, "id", modulePositionGetId, NULL + ); + scriptProtoDefineProp( + &MODULE_POSITION_PROTO, "localPosition", + modulePositionGetLocalPos, modulePositionSetLocalPos + ); + scriptProtoDefineProp( + &MODULE_POSITION_PROTO, "worldPosition", + modulePositionGetWorldPos, modulePositionSetWorldPos + ); + scriptProtoDefineProp( + &MODULE_POSITION_PROTO, "localRotation", + modulePositionGetLocalRot, modulePositionSetLocalRot + ); + scriptProtoDefineProp( + &MODULE_POSITION_PROTO, "worldRotation", + modulePositionGetWorldRot, modulePositionSetWorldRot + ); + scriptProtoDefineProp( + &MODULE_POSITION_PROTO, "localScale", + modulePositionGetLocalScale, modulePositionSetLocalScale + ); + scriptProtoDefineProp( + &MODULE_POSITION_PROTO, "worldScale", + modulePositionGetWorldScale, modulePositionSetWorldScale + ); + scriptProtoDefineFunc( + &MODULE_POSITION_PROTO, "setParent", modulePositionSetParent + ); + scriptProtoDefineToString(&MODULE_POSITION_PROTO, modulePositionToString); +} + +static void modulePositionDispose(void) { + scriptProtoDispose(&MODULE_POSITION_PROTO); +} diff --git a/src/dusk/script/module/entity/moduleentity.h b/src/dusk/script/module/entity/moduleentity.h index 460bdbed..990c9146 100644 --- a/src/dusk/script/module/entity/moduleentity.h +++ b/src/dusk/script/module/entity/moduleentity.h @@ -9,6 +9,7 @@ #include "script/module/modulebase.h" #include "script/scriptproto.h" #include "script/module/entity/modulecomponent.h" +#include "script/module/entity/component/modulecomponentlist.h" #include "entity/entitymanager.h" /** C struct wrapped by every Entity JS instance. */ @@ -59,7 +60,7 @@ moduleBaseFunction(moduleEntityAdd) { } jscomponent_t comp = { .entityId = ent->id, .componentId = cid }; - return scriptProtoCreateValue(&MODULE_COMPONENT_PROTO, &comp); + return moduleComponentListCreateInstance(type, &comp); } moduleBaseFunction(moduleEntityToString) {