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)

This commit is contained in:
ecker 2025-08-17 20:48:20 -05:00
parent 0a299a3fd2
commit c9448f9b74
27 changed files with 341 additions and 247 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 )

View File

@ -2,7 +2,7 @@
#include <uf/config.h>
#include <uf/engine/behavior/behavior.h>
#include <uf/utils/serialize/serializer.h>
//#include <uf/utils/serialize/serializer.h>
#include <uf/utils/memory/vector.h>
#include <uf/utils/resolvable/resolvable.h>
#include <uf/engine/asset/payload.h>
@ -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<uf::Entity*> container_t;

View File

@ -0,0 +1,23 @@
#pragma once
#include <uf/config.h>
#if UF_USE_LUA
// agony to try and get this included within "lua.h"
#include <uf/engine/object/object.h>
namespace ext {
namespace lua {
// component shenanigans
using GetComponent = sol::object(*)(uf::Object&);
extern UF_API uf::stl::unordered_map<uf::stl::string, GetComponent> componentGetters;
template<typename T>
sol::object getComponent( uf::Object& self ) {
return sol::make_object(ext::lua::state, std::ref(self.getComponent<T>()));
}
}
}
#endif

View File

@ -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 <sol/sol.hpp>
#include <uf/utils/memory/unordered_map.h>
#include <uf/utils/singletons/pre_main.h>
@ -37,12 +48,12 @@ namespace ext {
void UF_API terminate();
void UF_API onInitialization( const std::function<void()>& );
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

View File

@ -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<type>(UF_NS_GET_LAST(type), __VA_ARGS__);\
ext::lua::componentGetters[UF_NS_REMOVE_FIRST(type)] = &ext::lua::getComponent<type>;\
});\
});\
}
#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<type>;\
});\
});\
}
#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<type>(UF_NS_GET_LAST(type), __VA_ARGS__);\
ext::lua::componentGetters[UF_NS_REMOVE_FIRST(type)] = &ext::lua::getComponent<type>;\
});\
});\
}
#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<decltype(&x), &x>
#define UF_LUA_WRAP_FUN(x) sol::c_call<sol::wrap<decltype(&x), &x>>
#define UF_LUA_C_FUN(x) &x
#define UF_LUA_WRAP_FUN(x) UF_LUA_C_FUN(x)

View File

@ -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;\

View File

@ -3,6 +3,7 @@
#include <uf/config.h>
#include <uf/utils/userdata/userdata.h>
#define UF_LUA_SKIP_COMPONENTS
#include <uf/ext/lua/lua.h>
#include <uf/ext/json/json.h>

View File

@ -22,7 +22,10 @@ namespace uf {
uf::stl::vector<uf::stl::string> 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<const char*> cStrings( const uf::stl::vector<uf::stl::string>& );
uf::stl::vector<const char*> UF_API cStrings( const uf::stl::vector<uf::stl::string>& );
uf::stl::string UF_API namespaceGetLast( const uf::stl::string& name );
uf::stl::string UF_API namespaceRemoveFirst( const uf::stl::string& name );
template<typename T>
uf::stl::string /*UF_API*/ join( const T&, const uf::stl::string& = "\n", bool = false );

View File

@ -285,15 +285,15 @@ void ext::GuiBehavior::initialize( uf::Object& self ) {
});
if ( metadata.ui.click.able ) {
if ( metadata.clickable ) {
uf::Timer<long long> 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<ext::GuiManagerBehavior::Metadata>().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<long long> 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<ext::GuiManagerBehavior::Metadata>().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
#undef this
// yikes
#include <uf/ext/lua/component.h>
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)
)

View File

@ -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 };
);
}
}

View File

@ -285,4 +285,15 @@ void ext::LightBehavior::Metadata::deserialize( uf::Object& self, uf::Serializer
}
if ( serializer["light"]["dynamic"].as<bool>() ) /*this->*/type = -/*this->*/type;
}
#undef this
#undef this
// yikes
#include <uf/ext/lua/component.h>
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)
)

View File

@ -1,5 +1,7 @@
#include <uf/ext/lua/lua.h>
#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<uf::stl::string> 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<sol::table> 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<void()>& 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<sol::table>();
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<sol::table>();
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<sol::table>();
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<sol::table>();
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<sol::table>();
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<sol::table>();
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<sol::table>();
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<sol::table>();
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<sol::table>();
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);
}

View File

@ -45,7 +45,8 @@ namespace binds {
}
}
UF_LUA_REGISTER_USERTYPE(uf::asset,
#include <uf/ext/lua/component.h>
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) )

View File

@ -1,8 +1,9 @@
#include <uf/ext/lua/lua.h>
#if 0
#include <uf/ext/lua/lua.h>
#if UF_USE_LUA
#include <uf/utils/audio/audio.h>
UF_LUA_REGISTER_USERTYPE(uf::Audio,
#include <uf/ext/lua/component.h>
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);

View File

@ -45,7 +45,8 @@ namespace binds {
}
}
UF_LUA_REGISTER_USERTYPE(uf::Camera,
#include <uf/ext/lua/component.h>
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) ),

View File

@ -23,7 +23,8 @@ namespace binds {
}
}
UF_LUA_REGISTER_USERTYPE(pod::Matrix4f,
#include <uf/ext/lua/component.h>
UF_LUA_REGISTER_USERTYPE_AND_COMPONENT(pod::Matrix4f,
sol::call_constructor, sol::initializers(
[]( pod::Matrix4f& self ) {
return self = uf::matrix::identity();

View File

@ -1,4 +1,5 @@
#include <uf/ext/lua/lua.h>
#include <uf/ext/lua/component.h>
#if UF_USE_LUA
#include <uf/utils/math/transform.h>
#include <uf/utils/audio/audio.h>
@ -8,7 +9,10 @@
#include <uf/utils/math/physics.h>
#include <uf/engine/object/behaviors/lua.h>
uf::stl::unordered_map<uf::stl::string, ext::lua::GetComponent> 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<T>()) );
@ -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<uf::Serializer>();
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<uf::Object>();
}
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

View File

@ -27,7 +27,8 @@ namespace binds {
}
}
UF_LUA_REGISTER_USERTYPE(pod::Physics,
#include <uf/ext/lua/component.h>
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) ),

View File

@ -60,7 +60,8 @@ namespace binds {
}
}
UF_LUA_REGISTER_USERTYPE(::Quaternion,
#include <uf/ext/lua/component.h>
UF_LUA_REGISTER_USERTYPE_AND_COMPONENT(::Quaternion,
sol::call_constructor, sol::initializers(
[]( ::Quaternion& self ) {
return self = {0,0,0,1};

View File

@ -11,7 +11,8 @@ namespace binds {
bool running( uf::Timer<>& self ) { return self.running(); }
}
UF_LUA_REGISTER_USERTYPE(uf::Timer<>,
#include <uf/ext/lua/component.h>
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 ),

View File

@ -49,7 +49,8 @@ namespace binds {
}
}
UF_LUA_REGISTER_USERTYPE(pod::Transform<>,
#include <uf/ext/lua/component.h>
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),

View File

@ -99,7 +99,8 @@ namespace binds {
}
}
UF_LUA_REGISTER_USERTYPE(pod::Vector3f,
#include <uf/ext/lua/component.h>
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

View File

@ -4,6 +4,7 @@
#include <uf/utils/io/iostream.h>
#include <uf/ext/zlib/zlib.h>
#include <uf/ext/lua/lua.h>
#include <sstream>
#include <fstream>

View File

@ -58,16 +58,6 @@ uf::stl::vector<uf::stl::string> 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<uf::stl::string> 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<uf::stl::string>& 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, "::" ), "<>", "" );
}