From c9448f9b74832be83db0d0f7a478c793a7a4e004 Mon Sep 17 00:00:00 2001 From: ecker Date: Sun, 17 Aug 2025 20:48:20 -0500 Subject: [PATCH] lua optimizations to remove as much overhead as possible (to almost nothing), adjusted how metadata is accessed in lua (it requires explicit pasting of macros) --- .../entities/gui/mainmenu/scripts/menu.lua | 50 +++++------ bin/data/entities/gui/pause/scripts/menu.lua | 90 +++++++++---------- bin/data/entities/scripts/craeture.lua | 49 ---------- bin/data/entities/scripts/player.lua | 37 ++++---- engine/inc/uf/engine/entity/entity.h | 5 +- engine/inc/uf/ext/lua/component.h | 23 +++++ engine/inc/uf/ext/lua/lua.h | 16 +++- engine/inc/uf/ext/lua/lua.inl | 27 +++++- engine/inc/uf/macros.h | 3 +- engine/inc/uf/utils/serialize/serializer.h | 1 + engine/inc/uf/utils/string/ext.h | 5 +- engine/src/engine/ext/gui/behavior.cpp | 87 +++++++++++------- engine/src/engine/ext/gui/behavior.h | 18 ++-- engine/src/engine/ext/light/behavior.cpp | 13 ++- engine/src/ext/lua/lua.cpp | 62 ++++++++----- engine/src/ext/lua/usertypes/asset.cpp | 3 +- engine/src/ext/lua/usertypes/audio.cpp | 5 +- engine/src/ext/lua/usertypes/camera.cpp | 3 +- engine/src/ext/lua/usertypes/matrix.cpp | 3 +- engine/src/ext/lua/usertypes/object.cpp | 49 ++++++++-- engine/src/ext/lua/usertypes/physics.cpp | 3 +- engine/src/ext/lua/usertypes/quaternion.cpp | 3 +- engine/src/ext/lua/usertypes/timer.cpp | 3 +- engine/src/ext/lua/usertypes/transform.cpp | 3 +- engine/src/ext/lua/usertypes/vector.cpp | 7 +- engine/src/utils/serialize/serializer.cpp | 1 + engine/src/utils/string/ext.cpp | 19 ++-- 27 files changed, 341 insertions(+), 247 deletions(-) create mode 100644 engine/inc/uf/ext/lua/component.h diff --git a/bin/data/entities/gui/mainmenu/scripts/menu.lua b/bin/data/entities/gui/mainmenu/scripts/menu.lua index 440e1764..58c0ef68 100644 --- a/bin/data/entities/gui/mainmenu/scripts/menu.lua +++ b/bin/data/entities/gui/mainmenu/scripts/menu.lua @@ -12,7 +12,8 @@ local ent = ent local scene = entities.currentScene() local controller = entities.controller() local camera = controller:getComponent("Camera") -local metadata = ent:getComponent("Metadata") +local metadataJson = ent:getComponent("Metadata") +local metadata = ent:getComponent("GuiBehavior::Metadata") local masterdata = scene:getComponent("Metadata") local soundEmitter = ent:loadChild("./sound.json",true) @@ -76,7 +77,7 @@ local selectableElements = { } local selectableElementColors = {} local selectedElement = 0 -local selectionColor = { 1, 0, 1, 1 } +local selectionColor = Vector4f( 1, 0, 1, 1 ) local INPUT_DELAY = 0.2 local function array_index_of( haystack, needle ) @@ -87,6 +88,8 @@ local function array_index_of( haystack, needle ) end return 0 end + + local function onHover( payload ) playSound( "buttonrollover" ) selectedElement = 0 @@ -142,18 +145,20 @@ ent:bind( "tick", function(self) static.alpha = 0 end - metadata["initialized"] = true; - if static.alpha >= 1.0 then static.alpha = 1.0 else static.alpha = static.alpha + time.delta() * 1.5 end + metadata.initialized = true + -- make background glow local glow = 1 + math.sin(1.25 * time.current()) * 0.125 - metadata["color"] = { glow, glow, glow, static.alpha } - self:setComponent("Metadata", metadata) + metadata.color.x = glow + metadata.color.y = glow + metadata.color.z = glow + metadata.color.w = static.alpha camera:update(true); @@ -161,37 +166,35 @@ ent:bind( "tick", function(self) for k, v in pairs(children) do if v:uid() <= 0 then goto continue end - -- set alpha - local metadata = v:getComponent("Metadata") + local metadata = v:getComponent("GuiBehavior::Metadata") local index = array_index_of( selectableElements, v ) -- mark element as hovered if selected if 0 < selectedElement and selectedElement <= #selectableElements then if 0 < index and index <= #selectableElements then - metadata["hovered"] = index == selectedElement + metadata.hovered = index == selectedElement end end - if metadata["clickable"] then + if metadata.clickable then -- backup color if selectableElementColors[index] == nil then - selectableElementColors[index] = metadata["color"] + selectableElementColors[index] = Vector4f(metadata.color) end -- color for selection - if metadata["hovered"] then - metadata["color"] = selectionColor + if metadata.hovered then + metadata.color = selectionColor -- simulate click on input press if (inputs.key("A") or inputs.key("START") or inputs.key("Enter")) and timer:elapsed() >= INPUT_DELAY then timer:reset() v:callHook("gui:Clicked.%UID%", {}) end else - metadata["color"] = selectableElementColors[index] + metadata.color = selectableElementColors[index] end end - - metadata["color"][4] = static.alpha - v:setComponent("Metadata", metadata) + -- set alpha + metadata.color.w = static.alpha local transform = v:getComponent("Transform") local static = Static.get(v) @@ -207,7 +210,6 @@ ent:bind( "tick", function(self) transform.position = Vector3f.lerp( static.from, static.to, static.delta ) end - ::continue:: end @@ -217,10 +219,8 @@ ent:bind( "tick", function(self) local static = Static.get( child ) local transform = child:getComponent("Transform") - local metadata = child:getComponent("Metadata") - - -- rotation - local speed = metadata["hovered"] and 0.25 or 0.0125 + local metadata = child:getComponent("GuiBehavior::Metadata") + local speed = metadata.hovered and 0.25 or 0.0125 static.time = (static.time or 0) + time.delta() * -speed transform.orientation = Quaternion.axisAngle( Vector3f(0, 0, 1), static.time ) end @@ -230,10 +230,8 @@ ent:bind( "tick", function(self) local static = Static.get( child ) local transform = child:getComponent("Transform") - local metadata = child:getComponent("Metadata") - - -- rotation - local speed = metadata["hovered"] and 0.25 or 0.0125 + local metadata = child:getComponent("GuiBehavior::Metadata") + local speed = metadata.hovered and 0.25 or 0.0125 static.time = (static.time or 0) + time.delta() * speed transform.orientation = Quaternion.axisAngle( Vector3f(0, 0, 1), static.time ) end diff --git a/bin/data/entities/gui/pause/scripts/menu.lua b/bin/data/entities/gui/pause/scripts/menu.lua index 65d801dd..d9e340e8 100644 --- a/bin/data/entities/gui/pause/scripts/menu.lua +++ b/bin/data/entities/gui/pause/scripts/menu.lua @@ -1,7 +1,8 @@ local ent = ent local scene = entities.currentScene() local controller = entities.controller() -local metadata = ent:getComponent("Metadata") +local metadataJson = ent:getComponent("Metadata") +local metadata = ent:getComponent("GuiBehavior::Metadata") local masterdata = scene:getComponent("Metadata") local children = { @@ -51,12 +52,13 @@ local playSound = function( key ) -- assetLoader:cache(soundEmitter:formatHookName("asset:Load.%UID%"), string.resolveURI(url), "") end +local closing = false +local closed = false +local onClose = nil ent:addHook("menu:Close.%UID%", function( json ) --playSound("menu close") - if metadata["system"]["hooks"] == nil then metadata["system"]["hooks"] = {} end - metadata["system"]["hooks"]["onClose"] = json["callback"]; - metadata["system"]["closing"] = true; - ent:setComponent("Metadata", metadata) + closing = true + onClose = json["callback"]; end ) --playSound("menu open") @@ -67,7 +69,7 @@ local selectableElements = { } local selectableElementColors = {} local selectedElement = 0 -local selectionColor = { 1, 0, 1, 1 } +local selectionColor = Vector4f( 1, 0, 1, 1 ) local INPUT_DELAY = 0.2 local function array_index_of( haystack, needle ) @@ -140,30 +142,29 @@ ent:bind( "tick", function(self) end -- handle closing - if metadata["system"]["closing"] then + if closing then if static.alpha <= 0 then static.alpha = 0 - metadata["system"]["closing"] = false - metadata["system"]["closed"] = true + closing = false + closed = true else static.alpha = static.alpha - time.delta() end - elseif metadata["system"]["closed"] then + elseif closed then timer:stop() - local callback = metadata["system"]["hooks"]["onClose"] - if callback then - local payload = callback["payload"] + if onClose then + local payload = onClose["payload"] local target = self - if callback["scope"] == "parent" then + if onClose["scope"] == "parent" then target = ent:getParent() - elseif callback["scope"] == "scene" then + elseif onClose["scope"] == "scene" then target = scene end - if type(callback["delay"]) == "number" and target:uid() ~= self:uid() then - target:queueHook( callback["name"], payload, callback["delay"] ); + if type(onClose["delay"]) == "number" and target:uid() ~= self:uid() then + target:queueHook( onClose["name"], payload, onClose["delay"] ); else - target:callHook( callback["name"], payload ); + target:callHook( onClose["name"], payload ); end end @@ -171,10 +172,10 @@ ent:bind( "tick", function(self) -- scene:queueHook("system:Destroy", { uid = self:uid() }, 0) return else - if not metadata["initialized"] then + if not metadata.initialized then static.alpha = 0 end - metadata["initialized"] = true; + metadata.initialized = true; if static.alpha >= 1.0 then static.alpha = 1.0 else @@ -182,42 +183,41 @@ ent:bind( "tick", function(self) end end - metadata["color"][4] = static.alpha; + metadata.color.w = static.alpha -- set alphas for k, v in pairs(children) do if v:uid() <= 0 then goto continue end - -- set alpha - local metadata = v:getComponent("Metadata") + local metadata = v:getComponent("GuiBehavior::Metadata") local index = array_index_of( selectableElements, v ) -- mark element as hovered if selected if 0 < selectedElement and selectedElement <= #selectableElements then if 0 < index and index <= #selectableElements then - metadata["hovered"] = index == selectedElement + metadata.hovered = index == selectedElement end end - if metadata["clickable"] then + if metadata.clickable then -- backup color if selectableElementColors[index] == nil then - selectableElementColors[index] = metadata["color"] + selectableElementColors[index] = Vector4f(metadata.color) end -- color for selection - if metadata["hovered"] then - metadata["color"] = selectionColor + if metadata.hovered then + metadata.color = selectionColor -- simulate click on input press - if (inputs.key("A") or inputs.key("Enter")) and timer:elapsed() >= INPUT_DELAY then + if (inputs.key("A") or inputs.key("START") or inputs.key("Enter")) and timer:elapsed() >= INPUT_DELAY then timer:reset() v:callHook("gui:Clicked.%UID%", {}) end else - metadata["color"] = selectableElementColors[index] + metadata.color = selectableElementColors[index] end end - metadata["color"][4] = static.alpha - v:setComponent("Metadata", metadata) + -- set alpha + metadata.color.w = static.alpha local transform = v:getComponent("Transform") local static = Static.get(v) @@ -237,26 +237,24 @@ ent:bind( "tick", function(self) end -- circle in - if children.circleIn:uid() > 0 then - local static = Static.get( children.circleIn ) + child = children.circleIn + if child:uid() > 0 then + local static = Static.get( child ) - local transform = children.circleIn:getComponent("Transform") - local metadata = children.circleIn:getComponent("Metadata") - - -- rotation - local speed = metadata["hovered"] and 0.25 or 0.0125 + local transform = child:getComponent("Transform") + local metadata = child:getComponent("GuiBehavior::Metadata") + local speed = metadata.hovered and 0.25 or 0.0125 static.time = (static.time or 0) + time.delta() * -speed transform.orientation = Quaternion.axisAngle( Vector3f(0, 0, 1), static.time ) end -- circle out - if children.circleOut:uid() > 0 then - local static = Static.get( children.circleOut ) + child = children.circleOut + if child:uid() > 0 then + local static = Static.get( child ) - local transform = children.circleOut:getComponent("Transform") - local metadata = children.circleOut:getComponent("Metadata") - - -- rotation - local speed = metadata["hovered"] and 0.25 or 0.0125 + local transform = child:getComponent("Transform") + local metadata = child:getComponent("GuiBehavior::Metadata") + local speed = metadata.hovered and 0.25 or 0.0125 static.time = (static.time or 0) + time.delta() * speed transform.orientation = Quaternion.axisAngle( Vector3f(0, 0, 1), static.time ) end diff --git a/bin/data/entities/scripts/craeture.lua b/bin/data/entities/scripts/craeture.lua index ed1ab488..e60feba8 100644 --- a/bin/data/entities/scripts/craeture.lua +++ b/bin/data/entities/scripts/craeture.lua @@ -12,55 +12,6 @@ local timers = { } if not timers.lookat:running() then timers.lookat:start(); end ---[[ --- setup held object locals -local heldObject = { - uid = 0, - distance = 0, - smoothSpeed = 4, - scrollSpeed = 16, - momentum = Vector3f(0,0,0), - rotate = false, -} --- setup light locals -local light = { - entity = nil -} -for k, v in pairs(ent:getChildren()) do - if v:name() == "Light" then - light.entity = v - end -end - -if light.entity == nil then - light.entity = ent:loadChild("./playerLight.json",true) -end -light.metadata = light.entity:getComponent("Metadata") -light.transform = light.entity:getComponent("Transform") -light.power = light.metadata["light"]["power"] -light.origin = Vector3f(light.transform.position) -light.entity:setComponent("Metadata", { light = { power = 0 } }) - --- sound emitter -local playSound = function( key, loop ) - if not loop then loop = false end - local url = "/ui/" .. key .. ".ogg" - ent:callHook("sound:Emit.%UID%", { - filename = string.resolveURI(url, metadata["system"]["root"]), - spatial = true, - streamed = true, - volume = "sfx", - loop = loop - }, 0) -end -local stopSound = function( key ) - local url = "/ui/" .. key .. ".ogg" - ent:callHook("sound:Stop.%UID%", { - filename = string.resolveURI(url, metadata["system"]["root"]) - }, 0) -end -]] - local collider = ent:getComponent("PhysicsState") local target_transform = nil local soundEmitter = ent diff --git a/bin/data/entities/scripts/player.lua b/bin/data/entities/scripts/player.lua index 42e6ca77..59473a67 100644 --- a/bin/data/entities/scripts/player.lua +++ b/bin/data/entities/scripts/player.lua @@ -1,11 +1,13 @@ local ent = ent local scene = entities.currentScene() -local metadata = ent:getComponent("Metadata") +local metadataJson = ent:getComponent("Metadata") local transform = ent:getComponent("Transform") -local physicsState = ent:getComponent("PhysicsState") +local physicsState = ent:getComponent("Physics") local camera = ent:getComponent("Camera") local cameraTransform = camera:getTransform() +local fixedCamera = metadataJson["camera"]["settings"]["fixed"] + -- setup all timers local timers = { use = Timer.new(), @@ -29,7 +31,7 @@ local heldObject = { } -- setup light locals local light = { - entity = nil + entity = nil, } for k, v in pairs(ent:getChildren()) do if type(v) == "number" then @@ -44,18 +46,19 @@ end if light.entity == nil then light.entity = ent:loadChild("./playerLight.json",true) end -light.metadata = light.entity:getComponent("Metadata") +light.metadata = light.entity:getComponent("LightBehavior::Metadata") light.transform = light.entity:getComponent("Transform") -light.power = light.metadata["light"]["power"] +light.power = light.metadata.power light.origin = Vector3f(light.transform.position) -light.entity:setComponent("Metadata", { light = { power = 0 } }) +light.metadata.power = 0 +--light.entity:setComponent("Metadata", { light = { power = 0 } }) -- sound emitter local playSound = function( key, loop ) if not loop then loop = false end local url = "/ui/" .. key .. ".ogg" ent:callHook("sound:Emit.%UID%", { - filename = string.resolveURI(url, metadata["system"]["root"]), + filename = string.resolveURI(url, metadataJson["system"]["root"]), spatial = true, streamed = true, volume = "sfx", @@ -65,7 +68,7 @@ end local stopSound = function( key ) local url = "/ui/" .. key .. ".ogg" ent:callHook("sound:Stop.%UID%", { - filename = string.resolveURI(url, metadata["system"]["root"]) + filename = string.resolveURI(url, metadataJson["system"]["root"]) }, 0) end @@ -95,7 +98,7 @@ ent:bind( "tick", function(self) -- eye transform local flattenedTransform = nil - if metadata["camera"]["settings"]["fixed"] then + if fixedCamera then flattenedTransform = transform:flatten() -- flattenedTransform.position.y = flattenedTransform.position.y else @@ -121,15 +124,13 @@ ent:bind( "tick", function(self) if timers.flashlight:elapsed() > 0.5 and keyF then timers.flashlight:reset() - local metadata = { light = { power = light.power } } - if light.entity:getComponent("Metadata")["light"]["power"] ~= light.power then - metadata["light"]["power"] = light.power + if light.metadata.power ~= light.power then + light.metadata.power = light.power light.enabled = true else - metadata["light"]["power"] = 0 + light.metadata.power = 0 light.enabled = false end - light.entity:setComponent("Metadata", metadata) playSound("flashlight") end @@ -166,7 +167,7 @@ ent:bind( "tick", function(self) local prop, depth = physicsState:rayCast( center, direction ) if depth >= 0 and prop and not string.matched( prop:name(), "/^worldspawn/" ) then local heldObjectTransform = prop:getComponent("Transform") - local heldObjectPhysicsState = prop:getComponent("PhysicsState") + local heldObjectPhysicsState = prop:getComponent("Physics") local strength = 500 local distanceSquared = (heldObjectTransform.position - flattenedTransform.position):magnitude() @@ -190,7 +191,7 @@ ent:bind( "tick", function(self) local prop = entities.get( heldObject.uid ) local heldObjectTransform = prop:getComponent("Transform") - local heldObjectPhysicsState = prop:getComponent("PhysicsState") + local heldObjectPhysicsState = prop:getComponent("Physics") if mouse1 and timers.physcannon:elapsed() > 0.5 then timers.physcannon:reset() @@ -242,14 +243,14 @@ ent:addHook( "entity:Use.%UID%", function( payload ) heldObject.uid = payload.uid heldObject.distance = offset:norm() - prop:getComponent("PhysicsState"):enableGravity(false) + prop:getComponent("Physics"):enableGravity(false) else validUse = not string.matched( prop:name(), "/^worldspawn/" ) end elseif heldObject.uid ~= 0 then validUse = true local prop = entities.get( heldObject.uid ) - local heldObjectPhysicsState = prop:getComponent("PhysicsState") + local heldObjectPhysicsState = prop:getComponent("Physics") heldObjectPhysicsState:enableGravity(true) heldObjectPhysicsState:applyImpulse( heldObject.momentum ) diff --git a/engine/inc/uf/engine/entity/entity.h b/engine/inc/uf/engine/entity/entity.h index 1b8ee178..20d1470e 100644 --- a/engine/inc/uf/engine/entity/entity.h +++ b/engine/inc/uf/engine/entity/entity.h @@ -2,7 +2,7 @@ #include #include -#include +//#include #include #include #include @@ -15,7 +15,10 @@ #define UF_ENTITY_OBJECT_UNIFIED 1 + namespace uf { + class Serializer; + class UF_API Entity : public uf::Behaviors { public: typedef uf::stl::vector container_t; diff --git a/engine/inc/uf/ext/lua/component.h b/engine/inc/uf/ext/lua/component.h new file mode 100644 index 00000000..845a12c8 --- /dev/null +++ b/engine/inc/uf/ext/lua/component.h @@ -0,0 +1,23 @@ +#pragma once + +#include +#if UF_USE_LUA + +// agony to try and get this included within "lua.h" + +#include +namespace ext { + namespace lua { + // component shenanigans + using GetComponent = sol::object(*)(uf::Object&); + + extern UF_API uf::stl::unordered_map componentGetters; + + template + sol::object getComponent( uf::Object& self ) { + return sol::make_object(ext::lua::state, std::ref(self.getComponent())); + } + } +} + +#endif \ No newline at end of file diff --git a/engine/inc/uf/ext/lua/lua.h b/engine/inc/uf/ext/lua/lua.h index 04a2d3d0..18ea190e 100644 --- a/engine/inc/uf/ext/lua/lua.h +++ b/engine/inc/uf/ext/lua/lua.h @@ -6,13 +6,24 @@ #if UF_USE_LUAJIT #define SOL_LUAJIT 1 #endif + #define SOL_NO_EXCEPTIONS 1 + #if UF_ENV_DREAMCAST #define SOL_NO_THREAD_LOCAL 1 + #define UF_LUA_PCALLS 0 #else #define SOL_ALL_SAFETIES_ON 1 + #define UF_LUA_PCALLS 1 #endif +#if UF_LUA_PCALLS + #define LUA_FUN sol::protected_function +#else + #define LUA_FUN sol::function +#endif + + #include #include #include @@ -37,12 +48,12 @@ namespace ext { void UF_API terminate(); void UF_API onInitialization( const std::function& ); - bool UF_API run( const uf::stl::string&, bool = true ); + bool UF_API run( const uf::stl::string&, bool = UF_LUA_PCALLS ); pod::LuaScript UF_API script( const uf::stl::string& ); void UF_API script( const uf::stl::string&, pod::LuaScript& ); - bool UF_API run( const pod::LuaScript&, bool = true ); + bool UF_API run( const pod::LuaScript&, bool = UF_LUA_PCALLS ); sol::table createTable(); uf::stl::string sanitize( const uf::stl::string& dirty, int index = -1 ); @@ -52,4 +63,5 @@ namespace ext { } #include "lua.inl" + #endif \ No newline at end of file diff --git a/engine/inc/uf/ext/lua/lua.inl b/engine/inc/uf/ext/lua/lua.inl index 3d4a4b8c..d9faf04f 100644 --- a/engine/inc/uf/ext/lua/lua.inl +++ b/engine/inc/uf/ext/lua/lua.inl @@ -1,4 +1,5 @@ -#define UF_NS_GET_LAST(name) uf::string::replace( uf::string::split( #name, "::" ).back(), "<>", "" ) +#define UF_NS_GET_LAST(name) uf::string::namespaceGetLast(#name) +#define UF_NS_REMOVE_FIRST(name) uf::string::namespaceRemoveFirst(#name) #define TOKEN__PASTE(x, y) x ## y #define TOKEN_PASTE(x, y) TOKEN__PASTE(x, y) @@ -32,14 +33,32 @@ namespace {\ static uf::StaticInitialization TOKEN_PASTE(STATIC_INITIALIZATION_, __LINE__)( []{\ ext::lua::onInitialization( []{\ ext::lua::state.new_usertype(UF_NS_GET_LAST(type), __VA_ARGS__);\ + ext::lua::componentGetters[UF_NS_REMOVE_FIRST(type)] = &ext::lua::getComponent;\ + });\ + });\ +} +#define UF_LUA_REGISTER_COMPONENT(type, ...) \ +namespace {\ + static uf::StaticInitialization TOKEN_PASTE(STATIC_INITIALIZATION_, __LINE__)( []{\ + ext::lua::onInitialization( []{\ + ext::lua::componentGetters[UF_NS_REMOVE_FIRST(type)] = &ext::lua::getComponent;\ + });\ + });\ +} +#define UF_LUA_REGISTER_USERTYPE_AND_COMPONENT(type, ...) \ +namespace {\ + static uf::StaticInitialization TOKEN_PASTE(STATIC_INITIALIZATION_, __LINE__)( []{\ + ext::lua::onInitialization( []{\ + ext::lua::state.new_usertype(UF_NS_GET_LAST(type), __VA_ARGS__);\ + ext::lua::componentGetters[UF_NS_REMOVE_FIRST(type)] = &ext::lua::getComponent;\ });\ });\ } + #define UF_LUA_REGISTER_USERTYPE_DEFINE(k, v) #k, v #define UF_LUA_REGISTER_USERTYPE_MEMBER(member) UF_NS_GET_LAST(member), &member -//#define UF_LUA_REGISTER_USERTYPE_MEMBER(member) UF_NS_GET_LAST(member), sol::as_function(&member) #define UF_LUA_REGISTER_USERTYPE_MEMBER_FUN(member) UF_NS_GET_LAST(member), UF_LUA_C_FUN(member) -#define UF_LUA_C_FUN(x) sol::c_call -#define UF_LUA_WRAP_FUN(x) sol::c_call> \ No newline at end of file +#define UF_LUA_C_FUN(x) &x +#define UF_LUA_WRAP_FUN(x) UF_LUA_C_FUN(x) \ No newline at end of file diff --git a/engine/inc/uf/macros.h b/engine/inc/uf/macros.h index 2cec9f5d..702ca55a 100644 --- a/engine/inc/uf/macros.h +++ b/engine/inc/uf/macros.h @@ -1,7 +1,8 @@ #define TOKEN__PASTE(x, y) x ## y #define TOKEN_PASTE(x, y) TOKEN__PASTE(x, y) -#define UF_NS_GET_LAST(name) uf::string::replace( uf::string::split( #name, "::" ).back(), "<>", "" ) +#define UF_NS_GET_LAST(name) uf::string::namespaceGetLast(#name) +#define UF_NS_REMOVE_FIRST(name) uf::string::namespaceRemoveFirst(#name) #define TIMER(x, ...)\ static bool first = true;\ diff --git a/engine/inc/uf/utils/serialize/serializer.h b/engine/inc/uf/utils/serialize/serializer.h index 4a3bc7bd..a06c25aa 100644 --- a/engine/inc/uf/utils/serialize/serializer.h +++ b/engine/inc/uf/utils/serialize/serializer.h @@ -3,6 +3,7 @@ #include #include +#define UF_LUA_SKIP_COMPONENTS #include #include diff --git a/engine/inc/uf/utils/string/ext.h b/engine/inc/uf/utils/string/ext.h index 214a071c..685a8b80 100644 --- a/engine/inc/uf/utils/string/ext.h +++ b/engine/inc/uf/utils/string/ext.h @@ -22,7 +22,10 @@ namespace uf { uf::stl::vector UF_API split( const uf::stl::string&, const uf::stl::string& ); uf::stl::string UF_API si( double value, const uf::stl::string& unit, size_t precision = 3 ); bool UF_API contains( const uf::stl::string&, const uf::stl::string& ); - uf::stl::vector cStrings( const uf::stl::vector& ); + uf::stl::vector UF_API cStrings( const uf::stl::vector& ); + + uf::stl::string UF_API namespaceGetLast( const uf::stl::string& name ); + uf::stl::string UF_API namespaceRemoveFirst( const uf::stl::string& name ); template uf::stl::string /*UF_API*/ join( const T&, const uf::stl::string& = "\n", bool = false ); diff --git a/engine/src/engine/ext/gui/behavior.cpp b/engine/src/engine/ext/gui/behavior.cpp index 2c8f3dae..d5f41ac8 100644 --- a/engine/src/engine/ext/gui/behavior.cpp +++ b/engine/src/engine/ext/gui/behavior.cpp @@ -285,15 +285,15 @@ void ext::GuiBehavior::initialize( uf::Object& self ) { }); - if ( metadata.ui.click.able ) { + if ( metadata.clickable ) { uf::Timer clickTimer(false); clickTimer.start( uf::Time<>(-1000000) ); if ( !clickTimer.running() ) clickTimer.start(); this->addHook( "window:Mouse.Click", [&](pod::payloads::windowMouseClick& payload){ if ( metadata.world ) return; - //if ( !metadata.box.min && !metadata.box.max ) return; - if ((metadata.box.min.x > metadata.box.max.x)||(metadata.box.min.y > metadata.box.max.y)) return; + //if ( !metadata.boxMin && !metadata.boxMax ) return; + if ((metadata.boxMin.x > metadata.boxMax.x)||(metadata.boxMin.y > metadata.boxMax.y)) return; // uf::Object* manager = (uf::Object*) this->globalFindByName("Gui Manager"); // pod::Vector2ui guiSize = manager ? manager->getComponent().size : pod::Vector2ui{ uf::renderer::settings::width, uf::renderer::settings::height }; @@ -316,25 +316,25 @@ void ext::GuiBehavior::initialize( uf::Object& self ) { x = payload.mouse.position.x; y = payload.mouse.position.y; } - clicked = ( metadata.box.min.x <= x && metadata.box.min.y <= y && metadata.box.max.x >= x && metadata.box.max.y >= y ); + clicked = ( metadata.boxMin.x <= x && metadata.boxMin.y <= y && metadata.boxMax.x >= x && metadata.boxMax.y >= y ); - int minX = (metadata.box.min.x * 0.5f + 0.5f) * guiSize.x; - int minY = (metadata.box.min.y * 0.5f + 0.5f) * guiSize.y; + int minX = (metadata.boxMin.x * 0.5f + 0.5f) * guiSize.x; + int minY = (metadata.boxMin.y * 0.5f + 0.5f) * guiSize.y; - int maxX = (metadata.box.max.x * 0.5f + 0.5f) * guiSize.x; - int maxY = (metadata.box.max.y * 0.5f + 0.5f) * guiSize.y; + int maxX = (metadata.boxMax.x * 0.5f + 0.5f) * guiSize.x; + int maxY = (metadata.boxMax.y * 0.5f + 0.5f) * guiSize.y; int mouseX = payload.mouse.position.x; int mouseY = payload.mouse.position.y; } - if ( !metadata.ui.click.ed && clicked ) { + if ( !metadata.clicked && clicked ) { this->callHook("gui:ClickStart.%UID%", payload); - } else if ( metadata.ui.click.ed && !clicked ) { + } else if ( metadata.clicked && !clicked ) { this->callHook("gui:ClickEnd.%UID%", payload); } - metadata.ui.click.ed = clicked; + metadata.clicked = clicked; if ( clicked ) { this->callHook("gui:Clicked.%UID%", payload); @@ -381,14 +381,14 @@ void ext::GuiBehavior::initialize( uf::Object& self ) { } }); } - if ( metadata.ui.hover.able ) { + if ( metadata.hoverable ) { uf::Timer hoverTimer(false); hoverTimer.start( uf::Time<>(-1000000) ); this->addHook( "window:Mouse.Moved", [&](pod::payloads::windowMouseMoved& payload){ if ( metadata.world ) return; - //if ( !metadata.box.min && !metadata.box.max ) return; - if ((metadata.box.min.x > metadata.box.max.x)||(metadata.box.min.y > metadata.box.max.y)) return; + //if ( !metadata.boxMin && !metadata.boxMax ) return; + if ((metadata.boxMin.x > metadata.boxMax.x)||(metadata.boxMin.y > metadata.boxMax.y)) return; // uf::Object* manager = (uf::Object*) this->globalFindByName("Gui Manager"); // pod::Vector2ui guiSize = manager ? manager->getComponent().size : pod::Vector2ui{ uf::renderer::settings::width, uf::renderer::settings::height }; @@ -405,14 +405,14 @@ void ext::GuiBehavior::initialize( uf::Object& self ) { float x = click.x; float y = click.y; - hovered = ( metadata.box.min.x <= x && metadata.box.min.y <= y && metadata.box.max.x >= x && metadata.box.max.y >= y ); + hovered = ( metadata.boxMin.x <= x && metadata.boxMin.y <= y && metadata.boxMax.x >= x && metadata.boxMax.y >= y ); if ( hovered ) { - int minX = (metadata.box.min.x * 0.5f + 0.5f) * guiSize.x; - int minY = (metadata.box.min.y * 0.5f + 0.5f) * guiSize.y; + int minX = (metadata.boxMin.x * 0.5f + 0.5f) * guiSize.x; + int minY = (metadata.boxMin.y * 0.5f + 0.5f) * guiSize.y; - int maxX = (metadata.box.max.x * 0.5f + 0.5f) * guiSize.x; - int maxY = (metadata.box.max.y * 0.5f + 0.5f) * guiSize.y; + int maxX = (metadata.boxMax.x * 0.5f + 0.5f) * guiSize.x; + int maxY = (metadata.boxMax.y * 0.5f + 0.5f) * guiSize.y; int mouseX = payload.mouse.position.x; int mouseY = payload.mouse.position.y; @@ -421,16 +421,16 @@ void ext::GuiBehavior::initialize( uf::Object& self ) { uf::Serializer jsonPayload = ext::json::null(); // to-do: do something about trying to trigger json-bound hooks - if ( !metadata.ui.hover.ed && hovered ) { + if ( !metadata.hovered && hovered ) { this->callHook("gui:HoverStart.%UID%", payload); - } else if ( metadata.ui.hover.ed && !hovered ) { + } else if ( metadata.hovered && !hovered ) { this->callHook("gui:HoverEnd.%UID%", payload); } else if ( hovered ) { /*&& hoverTimer.elapsed().asDouble() >= 1 ) { hoverTimer.reset();*/ this->callHook("gui:Hovered.%UID%", payload); } - metadata.ui.hover.ed = hovered; + metadata.hovered = hovered; this->callHook("gui:Mouse.Moved.%UID%", payload); }); @@ -610,10 +610,10 @@ void ext::GuiBehavior::tick( uf::Object& self ) { max.y = std::max( max.y, translated.y ); } - metadata.box.min.x = min.x; - metadata.box.min.y = min.y; - metadata.box.max.x = max.x; - metadata.box.max.y = max.y; + metadata.boxMin.x = min.x; + metadata.boxMin.y = min.y; + metadata.boxMax.x = max.x; + metadata.boxMax.y = max.y; } } void ext::GuiBehavior::render( uf::Object& self ){} @@ -628,11 +628,11 @@ void ext::GuiBehavior::Metadata::serialize( uf::Object& self, uf::Serializer& se serializer["renderMode"] = /*this->*/renderMode; serializer["scaling"] = /*this->*/scaleMode; - serializer["clickable"] = /*this->*/ui.click.able; - serializer["clicked"] = /*this->*/ui.click.ed; + serializer["clickable"] = /*this->*/clickable; + serializer["clicked"] = /*this->*/clicked; - serializer["hoverable"] = /*this->*/ui.hover.able; - serializer["hovered"] = /*this->*/ui.hover.ed; + serializer["hoverable"] = /*this->*/hoverable; + serializer["hovered"] = /*this->*/hovered; } void ext::GuiBehavior::Metadata::deserialize( uf::Object& self, uf::Serializer& serializer ){ /*this->*/color = uf::vector::decode( serializer["color"], /*this->*/color ); @@ -644,7 +644,28 @@ void ext::GuiBehavior::Metadata::deserialize( uf::Object& self, uf::Serializer& /*this->*/renderMode = serializer["renderMode"].as( /*this->*/renderMode ); /*this->*/scaleMode = serializer["scaling"].as( /*this->*/scaleMode ); - /*this->*/ui.click.able = serializer["clickable"].as( /*this->*/ui.click.able ); - /*this->*/ui.hover.able = serializer["hoverable"].as( /*this->*/ui.hover.able ); + /*this->*/clickable = serializer["clickable"].as( /*this->*/clickable ); + /*this->*/hoverable = serializer["hoverable"].as( /*this->*/hoverable ); } -#undef this \ No newline at end of file +#undef this + +// yikes +#include +UF_LUA_REGISTER_USERTYPE_AND_COMPONENT(ext::GuiBehavior::Metadata, + UF_LUA_REGISTER_USERTYPE_MEMBER(ext::GuiBehavior::Metadata::initialized), + UF_LUA_REGISTER_USERTYPE_MEMBER(ext::GuiBehavior::Metadata::world), + UF_LUA_REGISTER_USERTYPE_MEMBER(ext::GuiBehavior::Metadata::depth), + UF_LUA_REGISTER_USERTYPE_MEMBER(ext::GuiBehavior::Metadata::mode), + UF_LUA_REGISTER_USERTYPE_MEMBER(ext::GuiBehavior::Metadata::clickable), + UF_LUA_REGISTER_USERTYPE_MEMBER(ext::GuiBehavior::Metadata::clicked), + UF_LUA_REGISTER_USERTYPE_MEMBER(ext::GuiBehavior::Metadata::hoverable), + UF_LUA_REGISTER_USERTYPE_MEMBER(ext::GuiBehavior::Metadata::hovered), + UF_LUA_REGISTER_USERTYPE_MEMBER(ext::GuiBehavior::Metadata::size), + UF_LUA_REGISTER_USERTYPE_MEMBER(ext::GuiBehavior::Metadata::scale), + UF_LUA_REGISTER_USERTYPE_MEMBER(ext::GuiBehavior::Metadata::uv), + UF_LUA_REGISTER_USERTYPE_MEMBER(ext::GuiBehavior::Metadata::color), + UF_LUA_REGISTER_USERTYPE_MEMBER(ext::GuiBehavior::Metadata::renderMode), + UF_LUA_REGISTER_USERTYPE_MEMBER(ext::GuiBehavior::Metadata::scaleMode), + UF_LUA_REGISTER_USERTYPE_MEMBER(ext::GuiBehavior::Metadata::boxMin), + UF_LUA_REGISTER_USERTYPE_MEMBER(ext::GuiBehavior::Metadata::boxMax) +) \ No newline at end of file diff --git a/engine/src/engine/ext/gui/behavior.h b/engine/src/engine/ext/gui/behavior.h index 287fe7be..0b0045b6 100644 --- a/engine/src/engine/ext/gui/behavior.h +++ b/engine/src/engine/ext/gui/behavior.h @@ -25,6 +25,11 @@ namespace ext { float depth = 0; size_t mode = 0; + bool clickable = false; + bool clicked = false; + bool hoverable = false; + bool hovered = false; + pod::Vector2ui size = {}; pod::Vector2f scale = { 1, 1 }; pod::Vector4f uv = { 0, 0, 1, 1 }; @@ -33,17 +38,8 @@ namespace ext { uf::stl::string renderMode = "Gui"; uf::stl::string scaleMode = "fixed"; - struct { - struct { - bool able = false; - bool ed = false; - } click, hover; - } ui; - - struct { - pod::Vector2f min = { 1, 1 }; - pod::Vector2f max = { -1, -1 }; - } box; + pod::Vector2f boxMin = { 1, 1 }; + pod::Vector2f boxMax = { 1, 1 }; ); } } \ No newline at end of file diff --git a/engine/src/engine/ext/light/behavior.cpp b/engine/src/engine/ext/light/behavior.cpp index 83526447..dbb745b9 100644 --- a/engine/src/engine/ext/light/behavior.cpp +++ b/engine/src/engine/ext/light/behavior.cpp @@ -285,4 +285,15 @@ void ext::LightBehavior::Metadata::deserialize( uf::Object& self, uf::Serializer } if ( serializer["light"]["dynamic"].as() ) /*this->*/type = -/*this->*/type; } -#undef this \ No newline at end of file +#undef this + +// yikes +#include +UF_LUA_REGISTER_USERTYPE_AND_COMPONENT(ext::LightBehavior::Metadata, + UF_LUA_REGISTER_USERTYPE_MEMBER(ext::LightBehavior::Metadata::color), + UF_LUA_REGISTER_USERTYPE_MEMBER(ext::LightBehavior::Metadata::power), + UF_LUA_REGISTER_USERTYPE_MEMBER(ext::LightBehavior::Metadata::bias), + UF_LUA_REGISTER_USERTYPE_MEMBER(ext::LightBehavior::Metadata::shadows), + UF_LUA_REGISTER_USERTYPE_MEMBER(ext::LightBehavior::Metadata::type), + UF_LUA_REGISTER_USERTYPE_MEMBER(ext::LightBehavior::Metadata::global) +) \ No newline at end of file diff --git a/engine/src/ext/lua/lua.cpp b/engine/src/ext/lua/lua.cpp index 6ea93bfa..87df5396 100644 --- a/engine/src/ext/lua/lua.cpp +++ b/engine/src/ext/lua/lua.cpp @@ -1,5 +1,7 @@ #include + #if UF_USE_LUA + bool ext::lua::enabled = true; sol::state ext::lua::state; uf::stl::string ext::lua::main = uf::io::root + "/scripts/main.lua"; @@ -29,23 +31,27 @@ uf::stl::string ext::lua::sanitize( const uf::stl::string& dirty, int index ) { return part; } std::optional ext::lua::encode( sol::table table ) { - sol::protected_function fun = ext::lua::state["json"]["encode"]; + LUA_FUN fun = ext::lua::state["json"]["encode"]; auto result = fun( table ); +#if UF_LUA_PCALLS if ( !result.valid() ) { sol::error err = result; UF_MSG_ERROR("{}", err.what()) return "{}"; } +#endif return result; } std::optional ext::lua::decode( const uf::stl::string& string ) { - sol::protected_function fun = ext::lua::state["json"]["decode"]; + LUA_FUN fun = ext::lua::state["json"]["decode"]; auto result = fun( string ); +#if UF_LUA_PCALLS if ( !result.valid() ) { sol::error err = result; UF_MSG_ERROR("{}", err.what()) return createTable(); } +#endif return result; } @@ -61,14 +67,17 @@ void ext::lua::onInitialization( const std::function& function ) { namespace binds { namespace hook { - void add( const uf::stl::string& name, sol::function function ) { + void add( const uf::stl::string& name, LUA_FUN function ) { uf::hooks.addHook( name, [function](ext::json::Value& json){ sol::table table = ext::lua::state["json"]["decode"]( json.dump() ); auto result = function( table ); + // ??? + #if UF_LUA_PCALLS if ( !result.valid() ) { sol::error err = result; UF_MSG_ERROR("{}", err.what()) } + #endif }); }; void call( const uf::stl::string& name, sol::table table = ext::lua::createTable() ) { @@ -180,7 +189,11 @@ namespace binds { void ext::lua::initialize() { if ( !ext::lua::enabled ) return; +#if UF_USE_LUAJIT state.open_libraries(sol::lib::base, sol::lib::package, sol::lib::table, sol::lib::math, sol::lib::string, sol::lib::ffi, sol::lib::jit); +#else + state.open_libraries(sol::lib::base, sol::lib::package, sol::lib::table, sol::lib::math, sol::lib::string); +#endif // load modules for ( auto pair : modules ) { @@ -203,36 +216,36 @@ void ext::lua::initialize() { { auto hooks = state["hooks"].get_or_create(); - hooks["add"] = UF_LUA_C_FUN(::binds::hook::add); - hooks["call"] = UF_LUA_C_FUN(::binds::hook::call); + hooks.set("add", UF_LUA_C_FUN(::binds::hook::add)); + hooks.set("call", UF_LUA_C_FUN(::binds::hook::call)); } // `entities` table { auto entities = state["entities"].get_or_create(); - entities["get"] = UF_LUA_C_FUN(::binds::entities::get); - entities["currentScene"] = UF_LUA_C_FUN(::binds::entities::currentScene); - entities["controller"] = UF_LUA_C_FUN(::binds::entities::controller); - entities["destroy"] = UF_LUA_C_FUN(::binds::entities::destroy); + entities.set("get", UF_LUA_C_FUN(::binds::entities::get)); + entities.set("currentScene", UF_LUA_C_FUN(::binds::entities::currentScene)); + entities.set("controller", UF_LUA_C_FUN(::binds::entities::controller)); + entities.set("destroy", UF_LUA_C_FUN(::binds::entities::destroy)); } // `string` table { auto string = state["string"].get_or_create(); - string["extension"] = UF_LUA_C_FUN(::binds::string::extension); - string["resolveURI"] = UF_LUA_C_FUN(::binds::string::resolveURI); - string["si"] = UF_LUA_C_FUN(::binds::string::si); + string.set("extension", UF_LUA_C_FUN(::binds::string::extension)); + string.set("resolveURI", UF_LUA_C_FUN(::binds::string::resolveURI)); + string.set("si", UF_LUA_C_FUN(::binds::string::si)); - string["match"] = UF_LUA_C_FUN(uf::string::match); - string["matched"] = UF_LUA_C_FUN(uf::string::matched); + string.set("match", UF_LUA_C_FUN(uf::string::match)); + string.set("matched", UF_LUA_C_FUN(uf::string::matched)); } // `io` table { auto io = state["io"].get_or_create(); - io["print"] = UF_LUA_C_FUN(::binds::io::print); + io.set("print", UF_LUA_C_FUN(::binds::io::print)); } // `math` table { auto math = state["math"].get_or_create(); - math["clamp"] = UF_LUA_C_FUN(::binds::math::clamp); + math.set("clamp", UF_LUA_C_FUN(::binds::math::clamp)); } // `time` table { @@ -243,26 +256,27 @@ void ext::lua::initialize() { } // `json` table { - state["json"]["pretty"] = UF_LUA_C_FUN(::binds::json::pretty); - state["json"]["readFromFile"] = UF_LUA_C_FUN(::binds::json::readFromFile); - state["json"]["writeToFile"] = UF_LUA_C_FUN(::binds::json::writeToFile); + auto json = state["json"].get_or_create(); + json.set("pretty", UF_LUA_C_FUN(::binds::json::pretty)); + json.set("readFromFile", UF_LUA_C_FUN(::binds::json::readFromFile)); + json.set("writeToFile", UF_LUA_C_FUN(::binds::json::writeToFile)); } // `window` table { auto window = state["window"].get_or_create(); - window["keyPressed"] = UF_LUA_C_FUN(uf::Window::isKeyPressed); + window.set("keyPressed", UF_LUA_C_FUN(uf::Window::isKeyPressed)); } // `os` table { auto os = state["os"].get_or_create(); - os["arch"] = UF_LUA_C_FUN(::binds::os::arch); + os.set("arch", UF_LUA_C_FUN(::binds::os::arch)); } // `inputs` table { auto inputs = state["inputs"].get_or_create(); - inputs["key"] = UF_LUA_C_FUN(uf::inputs::key); - inputs["analog"] = UF_LUA_C_FUN(uf::inputs::analog); - inputs["analog2"] = UF_LUA_C_FUN(uf::inputs::analog2); + inputs.set("key", UF_LUA_C_FUN(uf::inputs::key)); + inputs.set("analog", UF_LUA_C_FUN(uf::inputs::analog)); + inputs.set("analog2", UF_LUA_C_FUN(uf::inputs::analog2)); } run(main); } diff --git a/engine/src/ext/lua/usertypes/asset.cpp b/engine/src/ext/lua/usertypes/asset.cpp index 01c5db0d..88e0e2ce 100644 --- a/engine/src/ext/lua/usertypes/asset.cpp +++ b/engine/src/ext/lua/usertypes/asset.cpp @@ -45,7 +45,8 @@ namespace binds { } } -UF_LUA_REGISTER_USERTYPE(uf::asset, +#include +UF_LUA_REGISTER_USERTYPE_AND_COMPONENT(uf::asset, UF_LUA_REGISTER_USERTYPE_DEFINE( load, UF_LUA_C_FUN(::binds::load) ), UF_LUA_REGISTER_USERTYPE_DEFINE( cache, UF_LUA_C_FUN(::binds::cache) ), UF_LUA_REGISTER_USERTYPE_DEFINE( getOriginal, UF_LUA_C_FUN(::binds::getOriginal) ) diff --git a/engine/src/ext/lua/usertypes/audio.cpp b/engine/src/ext/lua/usertypes/audio.cpp index bac592c6..ef67cd7e 100644 --- a/engine/src/ext/lua/usertypes/audio.cpp +++ b/engine/src/ext/lua/usertypes/audio.cpp @@ -1,8 +1,9 @@ -#include #if 0 +#include #if UF_USE_LUA #include -UF_LUA_REGISTER_USERTYPE(uf::Audio, +#include +UF_LUA_REGISTER_USERTYPE_AND_COMPONENT(uf::Audio, sol::call_constructor, sol::initializers( []( uf::Audio& self ){}, []( uf::Audio& self, const uf::stl::string& filename = "", double volume = 1 ){ if ( filename != "" ) self.load(filename); diff --git a/engine/src/ext/lua/usertypes/camera.cpp b/engine/src/ext/lua/usertypes/camera.cpp index e7bbe678..5e3652e8 100644 --- a/engine/src/ext/lua/usertypes/camera.cpp +++ b/engine/src/ext/lua/usertypes/camera.cpp @@ -45,7 +45,8 @@ namespace binds { } } -UF_LUA_REGISTER_USERTYPE(uf::Camera, +#include +UF_LUA_REGISTER_USERTYPE_AND_COMPONENT(uf::Camera, UF_LUA_REGISTER_USERTYPE_DEFINE( getTransform, UF_LUA_C_FUN(::binds::getTransform) ), UF_LUA_REGISTER_USERTYPE_DEFINE( getView, UF_LUA_C_FUN(::binds::getView) ), UF_LUA_REGISTER_USERTYPE_DEFINE( setView, UF_LUA_C_FUN(::binds::setView) ), diff --git a/engine/src/ext/lua/usertypes/matrix.cpp b/engine/src/ext/lua/usertypes/matrix.cpp index eea621e2..8166f169 100644 --- a/engine/src/ext/lua/usertypes/matrix.cpp +++ b/engine/src/ext/lua/usertypes/matrix.cpp @@ -23,7 +23,8 @@ namespace binds { } } -UF_LUA_REGISTER_USERTYPE(pod::Matrix4f, +#include +UF_LUA_REGISTER_USERTYPE_AND_COMPONENT(pod::Matrix4f, sol::call_constructor, sol::initializers( []( pod::Matrix4f& self ) { return self = uf::matrix::identity(); diff --git a/engine/src/ext/lua/usertypes/object.cpp b/engine/src/ext/lua/usertypes/object.cpp index ca11ba8f..b327e3aa 100644 --- a/engine/src/ext/lua/usertypes/object.cpp +++ b/engine/src/ext/lua/usertypes/object.cpp @@ -1,4 +1,5 @@ #include +#include #if UF_USE_LUA #include #include @@ -8,7 +9,10 @@ #include #include +uf::stl::unordered_map ext::lua::componentGetters; + namespace binds { + /* namespace enums { enum Components { Metadata, @@ -35,10 +39,12 @@ namespace binds { }); }); } + */ uf::stl::string formatHookName(uf::Object& self, const uf::stl::string n ){ return self.formatHookName(n); } + /* sol::object getComponentFromEnum( uf::Object& self, binds::enums::Components type ) { #define UF_LUA_RETRIEVE_COMPONENT_FROM_ENUM( E, T )\ case enums::Components::E: return sol::make_object( ext::lua::state, std::ref(self.getComponent()) ); @@ -107,9 +113,28 @@ namespace binds { UF_LUA_UPDATE_COMPONENT(uf::Camera) UF_LUA_UPDATE_COMPONENT(pod::Physics) UF_LUA_UPDATE_COMPONENT(pod::PhysicsState) + + } - bool bind(uf::Object& self, const uf::stl::string& type, sol::protected_function fun ) { - // if ( !self.hasBehavior({.type = uf::LuaBehavior::type}) ) uf::instantiator::bind( "LuaBehavior", self ); + */ + sol::object getComponent( uf::Object& self, const uf::stl::string& type ) { + if ( type == "Metadata" ) { + self.callHook( "object:Serialize.%UID%" ); + auto& metadata = self.getComponent(); + auto decoded = ext::lua::decode( metadata ); + if ( decoded ) { + sol::table table = decoded.value(); + return sol::make_object( ext::lua::state, table ); + } + UF_MSG_ERROR("Failed to deserialize metadata for {}: {}", self.getName(), self.getUid()); + } + + auto it = ext::lua::componentGetters.find(type); + if ( it != ext::lua::componentGetters.end() ) return it->second(self); + UF_MSG_ERROR("Invalid component of {} requested for {}", type, uf::string::toString(self)); + return sol::make_object(ext::lua::state, sol::lua_nil); + } + bool bind(uf::Object& self, const uf::stl::string& type, LUA_FUN fun ) { if ( !self.hasBehavior({.type = TYPE(uf::LuaBehavior::Metadata)}) ) uf::instantiator::bind( "LuaBehavior", self ); pod::Behavior* behaviorPointer = NULL; auto& behaviors = self.getBehaviors(); @@ -131,13 +156,17 @@ namespace binds { if ( !functionPointer ) return false; pod::Behavior::function_t& function = *functionPointer; + #if !UF_LUA_PCALLS + function = fun; + #else function = [fun]( uf::Object& s ) { auto result = fun(s); if ( !result.valid() ) { sol::error err = result; - uf::iostream << err.what() << "\n"; + UF_MSG_ERROR("{}", err.what()); } }; + #endif self.generateGraph(); return true; } @@ -189,16 +218,18 @@ namespace binds { uf::Object& getParent( uf::Object& self ){ return self.getParent().as(); } - void addHook( uf::Object& self, const uf::stl::string& name, sol::protected_function fun ) { + void addHook( uf::Object& self, const uf::stl::string& name, LUA_FUN fun ) { self.addHook( name, [fun](ext::json::Value& json){ // cringe if ( ext::json::isNull( json ) ) { auto result = fun(); + #if UF_LUA_PCALLS if ( !result.valid() ) { sol::error err = result; uf::iostream << err.what() << "\n"; return; } + #endif return; } @@ -207,11 +238,13 @@ namespace binds { if ( !decoded ) return; sol::table table = decoded.value(); auto result = fun( table ); + #if UF_LUA_PCALLS if ( !result.valid() ) { sol::error err = result; uf::iostream << err.what() << "\n"; return; } + #endif }); } void callHook( uf::Object& self, const uf::stl::string& name, sol::table table = ext::lua::createTable() ) { @@ -253,9 +286,10 @@ UF_LUA_REGISTER_USERTYPE(uf::Object, UF_LUA_REGISTER_USERTYPE_DEFINE( uid, UF_LUA_C_FUN(::binds::getUid) ), UF_LUA_REGISTER_USERTYPE_DEFINE( name, UF_LUA_C_FUN(::binds::getName) ), UF_LUA_REGISTER_USERTYPE_DEFINE( formatHookName, UF_LUA_C_FUN(::binds::formatHookName) ), - UF_LUA_REGISTER_USERTYPE_DEFINE( getComponent, UF_LUA_C_FUN(::binds::getComponentFromEnum) ), - UF_LUA_REGISTER_USERTYPE_DEFINE( getComponent, UF_LUA_C_FUN(::binds::getComponentFromString) ), - UF_LUA_REGISTER_USERTYPE_DEFINE( setComponent, UF_LUA_C_FUN(::binds::setComponent) ), + //UF_LUA_REGISTER_USERTYPE_DEFINE( getComponent, UF_LUA_C_FUN(::binds::getComponentFromEnum) ), + //UF_LUA_REGISTER_USERTYPE_DEFINE( getComponent, UF_LUA_C_FUN(::binds::getComponentFromString) ), + //UF_LUA_REGISTER_USERTYPE_DEFINE( setComponent, UF_LUA_C_FUN(::binds::setComponent) ), + UF_LUA_REGISTER_USERTYPE_DEFINE( getComponent, UF_LUA_C_FUN(::binds::getComponent) ), UF_LUA_REGISTER_USERTYPE_DEFINE( bind, UF_LUA_C_FUN(::binds::bind) ), UF_LUA_REGISTER_USERTYPE_DEFINE( findByUid, UF_LUA_C_FUN(::binds::findByUid) ), UF_LUA_REGISTER_USERTYPE_DEFINE( findByName, UF_LUA_C_FUN(::binds::findByName) ), @@ -272,4 +306,5 @@ UF_LUA_REGISTER_USERTYPE(uf::Object, UF_LUA_REGISTER_USERTYPE_DEFINE( queueHook, UF_LUA_C_FUN(::binds::queueHook) ), UF_LUA_REGISTER_USERTYPE_DEFINE( __tostring, UF_LUA_C_FUN(::binds::toString) ) ) + #endif \ No newline at end of file diff --git a/engine/src/ext/lua/usertypes/physics.cpp b/engine/src/ext/lua/usertypes/physics.cpp index 0e843663..8328e0f4 100644 --- a/engine/src/ext/lua/usertypes/physics.cpp +++ b/engine/src/ext/lua/usertypes/physics.cpp @@ -27,7 +27,8 @@ namespace binds { } } -UF_LUA_REGISTER_USERTYPE(pod::Physics, +#include +UF_LUA_REGISTER_USERTYPE_AND_COMPONENT(pod::Physics, UF_LUA_REGISTER_USERTYPE_DEFINE( hasBody, UF_LUA_C_FUN(::binds::hasBody) ), UF_LUA_REGISTER_USERTYPE_DEFINE( linearVelocity, UF_LUA_C_FUN(::binds::linearVelocity) ), UF_LUA_REGISTER_USERTYPE_DEFINE( rotationalVelocity, UF_LUA_C_FUN(::binds::rotationalVelocity) ), diff --git a/engine/src/ext/lua/usertypes/quaternion.cpp b/engine/src/ext/lua/usertypes/quaternion.cpp index 77b45903..74f710e5 100644 --- a/engine/src/ext/lua/usertypes/quaternion.cpp +++ b/engine/src/ext/lua/usertypes/quaternion.cpp @@ -60,7 +60,8 @@ namespace binds { } } -UF_LUA_REGISTER_USERTYPE(::Quaternion, +#include +UF_LUA_REGISTER_USERTYPE_AND_COMPONENT(::Quaternion, sol::call_constructor, sol::initializers( []( ::Quaternion& self ) { return self = {0,0,0,1}; diff --git a/engine/src/ext/lua/usertypes/timer.cpp b/engine/src/ext/lua/usertypes/timer.cpp index 94283e26..c0f64f6a 100644 --- a/engine/src/ext/lua/usertypes/timer.cpp +++ b/engine/src/ext/lua/usertypes/timer.cpp @@ -11,7 +11,8 @@ namespace binds { bool running( uf::Timer<>& self ) { return self.running(); } } -UF_LUA_REGISTER_USERTYPE(uf::Timer<>, +#include +UF_LUA_REGISTER_USERTYPE_AND_COMPONENT(uf::Timer<>, UF_LUA_REGISTER_USERTYPE_DEFINE( elapsed, UF_LUA_C_FUN(::binds::elapsed) ), UF_LUA_REGISTER_USERTYPE_MEMBER_FUN( uf::Timer<>::start ), UF_LUA_REGISTER_USERTYPE_MEMBER_FUN( uf::Timer<>::stop ), diff --git a/engine/src/ext/lua/usertypes/transform.cpp b/engine/src/ext/lua/usertypes/transform.cpp index bbb7830e..f6a6f727 100644 --- a/engine/src/ext/lua/usertypes/transform.cpp +++ b/engine/src/ext/lua/usertypes/transform.cpp @@ -49,7 +49,8 @@ namespace binds { } } -UF_LUA_REGISTER_USERTYPE(pod::Transform<>, +#include +UF_LUA_REGISTER_USERTYPE_AND_COMPONENT(pod::Transform<>, UF_LUA_REGISTER_USERTYPE_MEMBER(pod::Transform<>::position), UF_LUA_REGISTER_USERTYPE_MEMBER(pod::Transform<>::scale), UF_LUA_REGISTER_USERTYPE_MEMBER(pod::Transform<>::up), diff --git a/engine/src/ext/lua/usertypes/vector.cpp b/engine/src/ext/lua/usertypes/vector.cpp index d240edc3..e5b67a5d 100644 --- a/engine/src/ext/lua/usertypes/vector.cpp +++ b/engine/src/ext/lua/usertypes/vector.cpp @@ -99,7 +99,8 @@ namespace binds { } } -UF_LUA_REGISTER_USERTYPE(pod::Vector3f, +#include +UF_LUA_REGISTER_USERTYPE_AND_COMPONENT(pod::Vector3f, sol::call_constructor, sol::initializers( []( pod::Vector3f& self ) { return self = pod::Vector3f{}; @@ -132,8 +133,7 @@ UF_LUA_REGISTER_USERTYPE(pod::Vector3f, UF_LUA_REGISTER_USERTYPE_DEFINE( dot, UF_LUA_C_FUN(::binds::v3f::dot) ), UF_LUA_REGISTER_USERTYPE_DEFINE( __tostring, UF_LUA_C_FUN(::binds::v3f::toString) ) ) -/* -UF_LUA_REGISTER_USERTYPE(pod::Vector4f, +UF_LUA_REGISTER_USERTYPE_AND_COMPONENT(pod::Vector4f, sol::call_constructor, sol::initializers( []( pod::Vector4f& self ) { return self = pod::Vector4f{}; @@ -165,5 +165,4 @@ UF_LUA_REGISTER_USERTYPE(pod::Vector4f, UF_LUA_REGISTER_USERTYPE_DEFINE( dot, UF_LUA_C_FUN(::binds::v4f::dot) ), UF_LUA_REGISTER_USERTYPE_DEFINE( __tostring, UF_LUA_C_FUN(::binds::v4f::toString) ) ) -*/ #endif \ No newline at end of file diff --git a/engine/src/utils/serialize/serializer.cpp b/engine/src/utils/serialize/serializer.cpp index c1fef46a..001fb4c2 100644 --- a/engine/src/utils/serialize/serializer.cpp +++ b/engine/src/utils/serialize/serializer.cpp @@ -4,6 +4,7 @@ #include #include +#include #include #include diff --git a/engine/src/utils/string/ext.cpp b/engine/src/utils/string/ext.cpp index 341e835e..094ac58b 100644 --- a/engine/src/utils/string/ext.cpp +++ b/engine/src/utils/string/ext.cpp @@ -58,16 +58,6 @@ uf::stl::vector uf::string::split( const uf::stl::string& str, } while (pos < str.length() && prev < str.length()); if ( tokens.empty() ) tokens.emplace_back(str); return tokens; -/* - uf::stl::vector cont; - size_t last = 0, next = 0; - while ((next = str.find(needle, last)) != uf::stl::string::npos) { - cont.push_back(str.substr(last, next-last)); - last = next + 1; - } - cont.push_back( str.substr(last) ); - return cont; -*/ } /* uf::stl::string uf::string::join( const uf::stl::vector& strings, const uf::stl::string& delim, bool trailing ) { @@ -142,4 +132,13 @@ uf::stl::string uf::string::si( double value, const uf::stl::string& unit, size_ uf::stl::stringstream ss; ss << std::fixed << std::setprecision(precision) << scaled << prefix << unit; return ss.str(); +} + +uf::stl::string uf::string::namespaceGetLast( const uf::stl::string& name ) { + return uf::string::replace( uf::string::split( name, "::" ).back(), "<>", "" ); +} +uf::stl::string uf::string::namespaceRemoveFirst( const uf::stl::string& name ) { + auto split = uf::string::split( name, "::" ); + split.erase(split.begin()); + return uf::string::replace( uf::string::join( split, "::" ), "<>", "" ); } \ No newline at end of file