Refactor script logic

This commit is contained in:
2026-04-26 10:10:42 -05:00
parent c9d949f759
commit 07943ec5f8
5 changed files with 101 additions and 31 deletions
+16 -12
View File
@@ -1,21 +1,25 @@
local Cube = {} local Cube = setmetatable({}, { __index = Entity })
Cube.__index = Cube Cube.__index = Cube
function Cube.new() function Cube.new()
local self = setmetatable({}, Cube) local self = Entity.new()
self.id = entityAdd() setmetatable(self, Cube)
local pos = entityPositionAdd(self.id) self:add(Entity.POSITION)
pos.x = 0 self.position.x = 0
pos.y = 0 self.position.y = 0
pos.z = 0 self.position.z = 0
entityMeshAdd(self.id) self:add(Entity.MESH)
local mat = entityMaterialAdd(self.id) self:add(Entity.MATERIAL)
mat.color = colorWhite() self.material.color = colorRed()
return self return self
end end
function Cube:dispose() function Cube:update()
entityRemove(self.id) local speed = 3.0
local dx = inputAxis(INPUT_ACTION_LEFT, INPUT_ACTION_RIGHT)
local dz = inputAxis(INPUT_ACTION_UP, INPUT_ACTION_DOWN)
self.position.x = self.position.x + dx * speed * TIME.delta
self.position.z = self.position.z + dz * speed * TIME.delta
end end
return Cube return Cube
+17 -13
View File
@@ -1,26 +1,30 @@
local Cube = include('entities/cube.lua') local Cube = include('entities/cube.lua')
local SceneCube = {}
SceneCube.__index = SceneCube
local cam local cam
local cube local cube
function Scene:init() function SceneCube:init()
print("Scene init") cam = Entity.new()
local camId = entityAdd() cam:add(Entity.POSITION)
local pos = entityPositionAdd(camId) cam.position.x = 3
pos.x = 3 cam.position.y = 3
pos.y = 3 cam.position.z = 3
pos.z = 3 cam.position:lookAt(0, 0, 0)
pos:lookAt(0, 0, 0) cam:add(Entity.CAMERA)
entityCameraAdd(camId)
cam = camId
cube = Cube.new() cube = Cube.new()
end end
function Scene:update() function SceneCube:update()
cube:update()
end end
function Scene:dispose() function SceneCube:dispose()
cam:dispose()
cube:dispose() cube:dispose()
entityRemove(cam)
end end
return SceneCube
+16 -6
View File
@@ -21,19 +21,23 @@
scene_t SCENE; scene_t SCENE;
// Rebuilds the Scene global to a clean table with only Scene.set bound. // Releases the current scene class ref and rebuilds Scene.set global.
static void sceneReset(void) { static void sceneReset(void) {
lua_State *L = SCRIPT_MANAGER.mainContext.luaState; lua_State *L = SCRIPT_MANAGER.mainContext.luaState;
if(SCENE.scriptRef != LUA_NOREF) {
luaL_unref(L, LUA_REGISTRYINDEX, SCENE.scriptRef);
SCENE.scriptRef = LUA_NOREF;
}
lua_newtable(L); lua_newtable(L);
lua_pushcfunction(L, sceneSetLua); lua_pushcfunction(L, sceneSetLua);
lua_setfield(L, -2, "set"); lua_setfield(L, -2, "set");
lua_setglobal(L, "Scene"); lua_setglobal(L, "Scene");
} }
// Calls Scene:method() if it exists. Returns an error if the call fails. // Calls sceneClass:method() if it exists. Returns an error if the call fails.
static errorret_t sceneCall(const char_t *method) { static errorret_t sceneCall(const char_t *method) {
lua_State *L = SCRIPT_MANAGER.mainContext.luaState; lua_State *L = SCRIPT_MANAGER.mainContext.luaState;
lua_getglobal(L, "Scene"); lua_rawgeti(L, LUA_REGISTRYINDEX, SCENE.scriptRef);
lua_getfield(L, -1, method); lua_getfield(L, -1, method);
if(!lua_isfunction(L, -1)) { if(!lua_isfunction(L, -1)) {
lua_pop(L, 2); lua_pop(L, 2);
@@ -45,12 +49,13 @@ static errorret_t sceneCall(const char_t *method) {
lua_pop(L, 2); lua_pop(L, 2);
errorThrow("Scene:%s failed: %s", method, err); errorThrow("Scene:%s failed: %s", method, err);
} }
lua_pop(L, 1); // pop Scene lua_pop(L, 1); // pop scene class
errorOk(); errorOk();
} }
errorret_t sceneInit(void) { errorret_t sceneInit(void) {
memoryZero(&SCENE, sizeof(scene_t)); memoryZero(&SCENE, sizeof(scene_t));
SCENE.scriptRef = LUA_NOREF;
sceneReset(); sceneReset();
errorOk(); errorOk();
} }
@@ -210,8 +215,13 @@ errorret_t sceneSetImmediate(const char_t *scene) {
errorChain(scriptContextExecFile(&SCRIPT_MANAGER.mainContext, scene)); errorChain(scriptContextExecFile(&SCRIPT_MANAGER.mainContext, scene));
// Discard any return values — we access Scene via the global. int32_t nReturns = lua_gettop(L) - stackBase;
lua_settop(L, stackBase); if(nReturns < 1 || !lua_istable(L, stackBase + 1)) {
lua_settop(L, stackBase);
errorThrow("Scene '%s' must return a table", scene);
}
lua_settop(L, stackBase + 1);
SCENE.scriptRef = luaL_ref(L, LUA_REGISTRYINDEX);
errorChain(sceneCall("init")); errorChain(sceneCall("init"));
SCENE.scriptActive = true; SCENE.scriptActive = true;
+1
View File
@@ -14,6 +14,7 @@
typedef struct { typedef struct {
bool_t scriptActive; bool_t scriptActive;
int scriptRef;
char_t sceneCurrent[ASSET_FILE_PATH_MAX]; char_t sceneCurrent[ASSET_FILE_PATH_MAX];
char_t sceneNext[ASSET_FILE_PATH_MAX]; char_t sceneNext[ASSET_FILE_PATH_MAX];
} scene_t; } scene_t;
@@ -239,6 +239,54 @@ static int _entityMaterialAdd(lua_State *L) {
return 1; return 1;
} }
// ============================================================================
// Component type Lua constants (auto-generated from componentlist.h)
// ============================================================================
#define X(enumName, type, field, init, dispose) \
"COMPONENT_TYPE_" #enumName " = \"" #field "\"\n"
static const char_t *COMPONENT_TYPE_SCRIPT =
#include "entity/componentlist.h"
;
#undef X
// ============================================================================
// Entity base class Lua script
// ============================================================================
static const char_t *ENTITY_SCRIPT =
"Entity = {}\n"
"Entity.__index = Entity\n"
"\n"
"Entity.POSITION = COMPONENT_TYPE_POSITION\n"
"Entity.CAMERA = COMPONENT_TYPE_CAMERA\n"
"Entity.MESH = COMPONENT_TYPE_MESH\n"
"Entity.MATERIAL = COMPONENT_TYPE_MATERIAL\n"
"Entity.PHYSICS = COMPONENT_TYPE_PHYSICS\n"
"\n"
"local _addFns = {\n"
" [COMPONENT_TYPE_POSITION] = entityPositionAdd,\n"
" [COMPONENT_TYPE_CAMERA] = entityCameraAdd,\n"
" [COMPONENT_TYPE_MESH] = entityMeshAdd,\n"
" [COMPONENT_TYPE_MATERIAL] = entityMaterialAdd,\n"
"}\n"
"\n"
"function Entity.new()\n"
" return setmetatable({ id = entityAdd() }, Entity)\n"
"end\n"
"\n"
"function Entity:add(componentType)\n"
" local fn = _addFns[componentType]\n"
" if not fn then error('unknown component type: ' .. tostring(componentType)) end\n"
" self[componentType] = fn(self.id)\n"
" return self[componentType]\n"
"end\n"
"\n"
"function Entity:dispose()\n"
" entityRemove(self.id)\n"
"end\n"
;
// ============================================================================ // ============================================================================
// entityAdd / entityRemove // entityAdd / entityRemove
// ============================================================================ // ============================================================================
@@ -288,4 +336,7 @@ static void moduleEntity(lua_State *L) {
lua_register(L, "entityCameraAdd", _entityCameraAdd); lua_register(L, "entityCameraAdd", _entityCameraAdd);
lua_register(L, "entityMeshAdd", _entityMeshAdd); lua_register(L, "entityMeshAdd", _entityMeshAdd);
lua_register(L, "entityMaterialAdd", _entityMaterialAdd); lua_register(L, "entityMaterialAdd", _entityMaterialAdd);
luaL_dostring(L, COMPONENT_TYPE_SCRIPT);
luaL_dostring(L, ENTITY_SCRIPT);
} }