diff --git a/assets/init.lua b/assets/init.lua index 2b437dc5..2a71c265 100644 --- a/assets/init.lua +++ b/assets/init.lua @@ -72,4 +72,6 @@ else print("Unknown platform, no default input bindings set.") end -print('Inited') \ No newline at end of file + +local test = 'test' +Scene.set('test/scene.lua') \ No newline at end of file diff --git a/src/dusk/scene/scene.c b/src/dusk/scene/scene.c index 339ad32e..21b756e6 100644 --- a/src/dusk/scene/scene.c +++ b/src/dusk/scene/scene.c @@ -17,12 +17,33 @@ #include "display/screen/screen.h" #include "console/console.h" #include "util/string.h" +#include "script/scriptmanager.h" scene_t SCENE; errorret_t sceneInit(void) { memoryZero(&SCENE, sizeof(scene_t)); - eventInit(&SCENE.eventUpdate, SCENE.updateListeners, SCENE_EVENT_UPDATE_MAX); + + errorChain(scriptContextExec( + &SCRIPT_MANAGER.mainContext, + "SceneBase = {}\n" + "function SceneBase:callTest()\n" + " print('SceneBase:callTest called with: ' .. tostring(self.test))\n" + "end\n" + "Scene = {}\n" + "Scene.__index = Scene\n" + "setmetatable(Scene, { __index = SceneBase })\n" + "Scene.current = nil\n" + )); + + lua_State *L = SCRIPT_MANAGER.mainContext.luaState; + lua_getglobal(L, "Scene"); + + assertTrue(lua_istable(L, -1), "Scene must be a table"); + lua_pushcfunction(L, sceneSetLua); + lua_setfield(L, -2, "set"); + + lua_pop(L, 1); errorOk(); } @@ -33,6 +54,16 @@ errorret_t sceneUpdate(void) { } #endif + // Call scene update on active scene + if(SCENE.scriptActive) { + errorChain(scriptContextExec( + &SCRIPT_MANAGER.mainContext, + "if Scene.current ~= nil and Scene.current.update ~= nil then\n" + " Scene.current:update()\n" + "end\n" + )); + } + // Is the scene changing? if(stringCompare(SCENE.sceneNext, SCENE.sceneCurrent) != 0) { errorChain(sceneSetImmediate(SCENE.sceneNext)); @@ -42,19 +73,6 @@ errorret_t sceneUpdate(void) { if(!SCENE.scriptActive) { errorOk(); } - - eventInvoke(&SCENE.eventUpdate, NULL, NULL); - - assertNotNull(SCENE.script.luaState, "Script context null?"); - lua_getglobal(SCENE.script.luaState, "sceneUpdate"); - if(lua_isfunction(SCENE.script.luaState, -1)) { - if(lua_pcall(SCENE.script.luaState, 0, 0, 0) != LUA_OK) { - errorThrow( - "Failed to call sceneUpdate function in script: %s\n", - lua_tostring(SCENE.script.luaState, -1) - ); - } - } errorOk(); } @@ -178,31 +196,15 @@ errorret_t sceneSetImmediate(const char_t *script) { // If there's currently a scene active, dispose of it first. if(SCENE.scriptActive) { - assertNotNull(SCENE.script.luaState, "Script context null?"); - - // Call sceneDispose function - lua_getglobal(SCENE.script.luaState, "sceneDispose"); - if(lua_isfunction(SCENE.script.luaState, -1)) { - if(lua_pcall(SCENE.script.luaState, 0, 0, 0) != LUA_OK) { - errorThrow( - "Failed to call sceneDispose function in script: %s\n", - lua_tostring(SCENE.script.luaState, -1) - ); - } - } - - // Scenes should ideally clean themselves up, this is just a warning because - // you can technically move entities between scenes, but it's messy. - for(entityid_t i = 0; i < ENTITY_COUNT_MAX; i++) { - if(ENTITY_MANAGER.entities[i].state & ENTITY_STATE_ACTIVE) { - consolePrint( - "Entity %d is active after scene dispose\n", i - ); - } - } - - // Unload script context. - scriptContextDispose(&SCENE.script); + // Unload script context. I do this with Lua code but I can probably make + // it optimized in future and call from C. + errorChain(scriptContextExec( + &SCRIPT_MANAGER.mainContext, + "if Scene.current ~= nil and Scene.current.dispose ~= nil then\n" + " Scene.current:dispose()\n" + "end\n" + "Scene.current = nil\n" + )); SCENE.scriptActive = false; } @@ -215,20 +217,14 @@ errorret_t sceneSetImmediate(const char_t *script) { // If we have a new scene, execute it. if(script != NULL) { - errorChain(scriptContextInit(&SCENE.script)); SCENE.scriptActive = true; - errorChain(scriptContextExecFile(&SCENE.script, script)); + errorChain(scriptContextExecFile(&SCRIPT_MANAGER.mainContext, script)); // Call the init function. - lua_getglobal(SCENE.script.luaState, "sceneInit"); - if(lua_isfunction(SCENE.script.luaState, -1)) { - if(lua_pcall(SCENE.script.luaState, 0, 0, 0) != LUA_OK) { - errorThrow( - "Failed to call sceneInit function in script: %s\n", - lua_tostring(SCENE.script.luaState, -1) - ); - } - } + errorChain(scriptContextExec( + &SCRIPT_MANAGER.mainContext, + "Scene.current = Scene.new()\n" + )); } errorOk(); @@ -247,4 +243,16 @@ void sceneSet(const char_t *script) { errorret_t sceneDispose(void) { errorChain(sceneSetImmediate(NULL)); errorOk(); +} + +int sceneSetLua(lua_State *L) { + assertNotNull(L, "Lua state cannot be NULL"); + + if(!lua_isstring(L, 1)) { + luaL_error(L, "Scene.set requires a string argument"); + return 0; + } + + sceneSet(lua_tostring(L, 1)); + return 0; } \ No newline at end of file diff --git a/src/dusk/scene/scene.h b/src/dusk/scene/scene.h index 0dc382fa..d1b77935 100644 --- a/src/dusk/scene/scene.h +++ b/src/dusk/scene/scene.h @@ -13,13 +13,9 @@ #define SCENE_EVENT_UPDATE_MAX 16 typedef struct { - scriptcontext_t script; bool_t scriptActive; char_t sceneCurrent[ASSET_FILE_PATH_MAX]; char_t sceneNext[ASSET_FILE_PATH_MAX]; - - eventlistener_t updateListeners[SCENE_EVENT_UPDATE_MAX]; - event_t eventUpdate; } scene_t; extern scene_t SCENE; @@ -64,4 +60,11 @@ void sceneSet(const char_t *script); * * @return The error return value. */ -errorret_t sceneDispose(void); \ No newline at end of file +errorret_t sceneDispose(void); + +/** + * Lua method for setting the scene. + * @param L The Lua state. + * @return The number of return values on the Lua stack. + */ +int sceneSetLua(lua_State *L); \ No newline at end of file diff --git a/src/dusk/script/module/module.h b/src/dusk/script/module/module.h index 30ea7cc2..d4b91a39 100644 --- a/src/dusk/script/module/module.h +++ b/src/dusk/script/module/module.h @@ -10,7 +10,6 @@ #include "script/module/entity/moduleentity.h" #include "script/module/input/moduleinput.h" #include "script/module/moduleplatform.h" -#include "script/module/scene/modulescene.h" #include "script/module/locale/modulelocale.h" #include "script/module/time/moduletime.h" #include "script/module/event/moduleevent.h" @@ -31,7 +30,6 @@ void moduleRegister(lua_State *L) { moduleEntity(L); moduleInput(L); modulePlatform(L); - moduleScene(L); moduleLocale(L); moduleTime(L); moduleEvent(L); diff --git a/src/dusk/script/module/scene/modulescene.h b/src/dusk/script/module/scene/modulescene.h deleted file mode 100644 index 03b80620..00000000 --- a/src/dusk/script/module/scene/modulescene.h +++ /dev/null @@ -1,31 +0,0 @@ -/** - * Copyright (c) 2025 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -#pragma once -#include "script/module/modulebase.h" -#include "scene/scene.h" - -static int moduleSceneSet(lua_State *L) { - assertNotNull(L, "Lua state cannot be NULL"); - - if(!lua_isstring(L, 1)) { - luaL_error(L, "sceneSet requires a string argument"); - return 0; - } - - sceneSet(lua_tostring(L, 1)); - return 0; -} - -static void moduleScene(lua_State *L) { - assertNotNull(L, "Lua state cannot be NULL"); - - lua_register(L, "sceneSet", moduleSceneSet); - - lua_pushlightuserdata(L, &SCENE.eventUpdate); - lua_setglobal(L, "SCENE_EVENT_UPDATE"); -} diff --git a/src/dusk/script/scriptmanager.c b/src/dusk/script/scriptmanager.c index 097c28f0..9606f411 100644 --- a/src/dusk/script/scriptmanager.c +++ b/src/dusk/script/scriptmanager.c @@ -16,10 +16,6 @@ errorret_t scriptManagerInit() { memoryZero(&SCRIPT_MANAGER, sizeof(scriptmanager_t)); errorChain(scriptContextInit(&SCRIPT_MANAGER.mainContext)); - errorChain(scriptContextExec( - &SCRIPT_MANAGER.mainContext, - "print('Main Script Context Ready!')" - )); errorOk(); } diff --git a/src/duskdolphin/script/module/moduleplatformdolphin.h b/src/duskdolphin/script/module/moduleplatformdolphin.h index 759f0f4d..2a18b7e9 100644 --- a/src/duskdolphin/script/module/moduleplatformdolphin.h +++ b/src/duskdolphin/script/module/moduleplatformdolphin.h @@ -8,6 +8,6 @@ #pragma once #include "script/scriptcontext.h" -void modulePlatformDolphin(scriptcontext_t *ctx) { - scriptContextExec(ctx, "DOLPHIN = true\n"); +static void modulePlatformDolphin(lua_State *L) { + luaL_dostring(L, "DOLPHIN = true\n"); } \ No newline at end of file diff --git a/src/duskpsp/script/module/moduleplatformpsp.h b/src/duskpsp/script/module/moduleplatformpsp.h index 4030e5c5..bd12bb56 100644 --- a/src/duskpsp/script/module/moduleplatformpsp.h +++ b/src/duskpsp/script/module/moduleplatformpsp.h @@ -8,6 +8,6 @@ #pragma once #include "script/scriptcontext.h" -void modulePlatformPSP(scriptcontext_t *ctx) { - scriptContextExec(ctx, "PSP = true\n"); +void modulePlatformPSP(lua_State *L) { + luaL_dostring(L, "PSP = true\n"); } \ No newline at end of file