Skip to content

Commit

Permalink
Lua: Cache MotionControllerState
Browse files Browse the repository at this point in the history
  • Loading branch information
praydog committed Oct 18, 2024
1 parent e032b90 commit e1a0057
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 8 deletions.
4 changes: 4 additions & 0 deletions include/uevr/API.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1565,6 +1565,10 @@ class API {
}

struct MotionControllerState {
static consteval std::string_view internal_name() {
return "MotionControllerState";
}

inline UEVR_UObjectHookMotionControllerStateHandle to_handle() { return (UEVR_UObjectHookMotionControllerStateHandle)this; }
inline UEVR_UObjectHookMotionControllerStateHandle to_handle() const { return (UEVR_UObjectHookMotionControllerStateHandle)this; }

Expand Down
4 changes: 2 additions & 2 deletions lua-api/lib/include/ScriptPrerequisites.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@

namespace detail {
template<typename T>
concept UObjectBased = std::is_base_of_v<uevr::API::UObject, T>;
concept CacheablePointer = std::is_base_of_v<uevr::API::UObject, T> || std::is_base_of_v<uevr::API::UObjectHook::MotionControllerState, T>;

constexpr uintptr_t FAKE_OBJECT_ADDR = 12345;
}

// Object pooling for UObject based pointers using a specialization for sol_lua_push
template<detail::UObjectBased T>
template<detail::CacheablePointer T>
int sol_lua_push(sol::types<T*>, lua_State* l, T* obj) {
static const std::string TABLE_NAME = std::string{"_sol_lua_push_objects"} + "_" + T::internal_name().data();

Expand Down
36 changes: 30 additions & 6 deletions lua-api/lib/src/ScriptContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -198,20 +198,24 @@ int ScriptContext::setup_bindings() {
_sol_lua_push_objects_Property = setmetatable({}, { __mode = "v" })
_sol_lua_push_objects_Field = setmetatable({}, { __mode = "v" })
_sol_lua_push_objects_Enum = setmetatable({}, { __mode = "v" })
-- Not a real UObject but is cacheable
_sol_lua_push_objects_MotionControllerState = setmetatable({}, { __mode = "v" })
_sol_lua_push_usertypes = {}
_sol_lua_push_ref_counts = {}
_sol_lua_push_ephemeral_counts = {}
)");


// templated lambda
auto create_uobject_ptr_gc = [&]<detail::UObjectBased T>(T* obj) {
m_lua["__UEVRUObjectPtrInternalCreate"] = [this]() -> sol::object {
auto create_uobject_ptr_gc = [&]<detail::CacheablePointer T>(T* obj) {
m_lua["__UEVRCachePtrInternalCreate"] = [this]() -> sol::object {
return sol::make_object(m_lua, (T*)detail::FAKE_OBJECT_ADDR);
};

m_lua.do_string(R"(
local fake_obj = __UEVRUObjectPtrInternalCreate()
local fake_obj = __UEVRCachePtrInternalCreate()
local mt = getmetatable(fake_obj)
fake_obj = nil
Expand All @@ -222,7 +226,7 @@ int ScriptContext::setup_bindings() {
end
)");

m_lua["__UEVRUObjectPtrInternalCreate"] = sol::make_object(m_lua, sol::nil);
m_lua["__UEVRCachePtrInternalCreate"] = sol::make_object(m_lua, sol::nil);
};

lua::datatypes::bind_xinput(m_lua);
Expand Down Expand Up @@ -860,6 +864,8 @@ int ScriptContext::setup_bindings() {
"set_permanent", &uevr::API::UObjectHook::MotionControllerState::set_permanent
);

create_uobject_ptr_gc((API::UObjectHook::MotionControllerState*)nullptr);

m_lua.new_usertype<uevr::API::UObjectHook>("UEVR_UObjectHook",
"activate", &uevr::API::UObjectHook::activate,
"exists", &uevr::API::UObjectHook::exists,
Expand Down Expand Up @@ -897,8 +903,26 @@ int ScriptContext::setup_bindings() {

return sol::make_object(s, tbl);
},
"get_or_add_motion_controller_state", &uevr::API::UObjectHook::get_or_add_motion_controller_state,
"get_motion_controller_state", &uevr::API::UObjectHook::get_motion_controller_state,
//"get_or_add_motion_controller_state", &uevr::API::UObjectHook::get_or_add_motion_controller_state,
"get_or_add_motion_controller_state", [](sol::this_state s, API::UObject* obj) -> sol::object {
auto state = API::UObjectHook::get_or_add_motion_controller_state(obj);

if (state == nullptr) {
return sol::make_object(s, sol::lua_nil);
}

return sol::make_object(s, state);
},
//"get_motion_controller_state", &uevr::API::UObjectHook::get_motion_controller_state,
"get_motion_controller_state", [](sol::this_state s, uevr::API::UObjectHook* self, API::UObject* obj) -> sol::object {
auto state = API::UObjectHook::get_motion_controller_state(obj);

if (state == nullptr) {
return sol::make_object(s, sol::lua_nil);
}

return sol::make_object(s, state);
},
"remove_motion_controller_state", &uevr::API::UObjectHook::remove_motion_controller_state
);

Expand Down

0 comments on commit e1a0057

Please sign in to comment.