From 21aaf9a3fe1d52633ae251a7d5006bcbb6ee6991 Mon Sep 17 00:00:00 2001 From: praydog Date: Fri, 28 Jun 2024 08:33:30 -0700 Subject: [PATCH] Lua: Add support for enum properties and some other primitives --- lua-api/lib/src/ScriptContext.cpp | 4 +- lua-api/lib/src/ScriptUtility.cpp | 129 +++++++++++++++++++++++++++++- 2 files changed, 130 insertions(+), 3 deletions(-) diff --git a/lua-api/lib/src/ScriptContext.cpp b/lua-api/lib/src/ScriptContext.cpp index 2b8e6be..cf6ca8a 100644 --- a/lua-api/lib/src/ScriptContext.cpp +++ b/lua-api/lib/src/ScriptContext.cpp @@ -428,7 +428,9 @@ int ScriptContext::setup_bindings() { "static_class", &uevr::API::UStruct::static_class, "get_super_struct", &uevr::API::UStruct::get_super_struct, "get_super", &uevr::API::UStruct::get_super, - "find_function", &uevr::API::UStruct::find_function, + "find_function", [](uevr::API::UStruct& self, const std::wstring& name) { + return self.find_function(name); + }, "get_child_properties", &uevr::API::UStruct::get_child_properties, "get_properties_size", &uevr::API::UStruct::get_properties_size ); diff --git a/lua-api/lib/src/ScriptUtility.cpp b/lua-api/lib/src/ScriptUtility.cpp index fcdc144..5a02981 100644 --- a/lua-api/lib/src/ScriptUtility.cpp +++ b/lua-api/lib/src/ScriptUtility.cpp @@ -56,11 +56,66 @@ sol::object prop_to_object(sol::this_state s, void* self, uevr::API::FProperty* return sol::make_object(s, *(float*)((uintptr_t)self + offset)); case L"DoubleProperty"_fnv: return sol::make_object(s, *(double*)((uintptr_t)self + offset)); + case L"ByteProperty"_fnv: + return sol::make_object(s, *(uint8_t*)((uintptr_t)self + offset)); + case L"Int8Property"_fnv: + return sol::make_object(s, *(int8_t*)((uintptr_t)self + offset)); + case L"Int16Property"_fnv: + return sol::make_object(s, *(int16_t*)((uintptr_t)self + offset)); + case L"UInt16Property"_fnv: + return sol::make_object(s, *(uint16_t*)((uintptr_t)self + offset)); case L"IntProperty"_fnv: return sol::make_object(s, *(int32_t*)((uintptr_t)self + offset)); case L"UIntProperty"_fnv: case L"UInt32Property"_fnv: return sol::make_object(s, *(uint32_t*)((uintptr_t)self + offset)); + case L"UInt64Property"_fnv: + return sol::make_object(s, *(uint64_t*)((uintptr_t)self + offset)); + case L"Int64Property"_fnv: + return sol::make_object(s, *(int64_t*)((uintptr_t)self + offset)); + case L"EnumProperty"_fnv: + { + const auto ep = (uevr::API::FEnumProperty*)desc; + const auto np = ep->get_underlying_prop(); + + if (np == nullptr) { + return sol::make_object(s, sol::lua_nil); + } + + const auto np_c = np->get_class(); + + if (np_c == nullptr) { + return sol::make_object(s, sol::lua_nil); + } + + const auto np_name_hash = ::utility::hash(np_c->get_fname()->to_string()); + + switch (np_name_hash) { + case L"FloatProperty"_fnv: + return sol::make_object(s, *(float*)((uintptr_t)self + offset)); + case L"DoubleProperty"_fnv: + return sol::make_object(s, *(double*)((uintptr_t)self + offset)); + case L"ByteProperty"_fnv: + return sol::make_object(s, *(uint8_t*)((uintptr_t)self + offset)); + case L"Int8Property"_fnv: + return sol::make_object(s, *(int8_t*)((uintptr_t)self + offset)); + case L"Int16Property"_fnv: + return sol::make_object(s, *(int16_t*)((uintptr_t)self + offset)); + case L"UInt16Property"_fnv: + return sol::make_object(s, *(uint16_t*)((uintptr_t)self + offset)); + case L"IntProperty"_fnv: + return sol::make_object(s, *(int32_t*)((uintptr_t)self + offset)); + case L"UIntProperty"_fnv: + case L"UInt32Property"_fnv: + return sol::make_object(s, *(uint32_t*)((uintptr_t)self + offset)); + case L"UInt64Property"_fnv: + return sol::make_object(s, *(uint64_t*)((uintptr_t)self + offset)); + case L"Int64Property"_fnv: + return sol::make_object(s, *(int64_t*)((uintptr_t)self + offset)); + }; + + return sol::make_object(s, sol::lua_nil); + } case L"NameProperty"_fnv: return sol::make_object(s, *(uevr::API::FName*)((uintptr_t)self + offset)); case L"ObjectProperty"_fnv: @@ -209,19 +264,89 @@ void set_property(sol::this_state s, void* self, uevr::API::UStruct* c, const st return; } case L"FloatProperty"_fnv: - //self.get_property(name) = value.as(); *(float*)((uintptr_t)self + offset) = value.as(); return; case L"DoubleProperty"_fnv: *(double*)((uintptr_t)self + offset) = value.as(); return; + case L"ByteProperty"_fnv: + *(uint8_t*)((uintptr_t)self + offset) = value.as(); + return; + case L"Int8Property"_fnv: + *(int8_t*)((uintptr_t)self + offset) = value.as(); + return; + case L"Int16Property"_fnv: + *(int16_t*)((uintptr_t)self + offset) = value.as(); + return; + case L"UInt16Property"_fnv: + *(uint16_t*)((uintptr_t)self + offset) = value.as(); + return; case L"IntProperty"_fnv: *(int32_t*)((uintptr_t)self + offset) = value.as(); - return; + return; case L"UIntProperty"_fnv: case L"UInt32Property"_fnv: *(uint32_t*)((uintptr_t)self + offset) = value.as(); return; + case L"UInt64Property"_fnv: + *(uint64_t*)((uintptr_t)self + offset) = value.as(); + return; + case L"Int64Property"_fnv: + *(int64_t*)((uintptr_t)self + offset) = value.as(); + return; + case L"EnumProperty"_fnv: + { + const auto ep = (uevr::API::FEnumProperty*)desc; + const auto np = ep->get_underlying_prop(); + + if (np == nullptr) { + throw sol::error("Enum property has no underlying property"); + } + + const auto np_c = np->get_class(); + + if (np_c == nullptr) { + throw sol::error("Enum property's underlying property has no class"); + } + + const auto np_name_hash = ::utility::hash(np_c->get_fname()->to_string()); + + switch (np_name_hash) { + case L"FloatProperty"_fnv: + *(float*)((uintptr_t)self + offset) = value.as(); + return; + case L"DoubleProperty"_fnv: + *(double*)((uintptr_t)self + offset) = value.as(); + return; + case L"ByteProperty"_fnv: + *(uint8_t*)((uintptr_t)self + offset) = value.as(); + return; + case L"Int8Property"_fnv: + *(int8_t*)((uintptr_t)self + offset) = value.as(); + return; + case L"Int16Property"_fnv: + *(int16_t*)((uintptr_t)self + offset) = value.as(); + return; + case L"UInt16Property"_fnv: + *(uint16_t*)((uintptr_t)self + offset) = value.as(); + return; + case L"IntProperty"_fnv: + *(int32_t*)((uintptr_t)self + offset) = value.as(); + return; + case L"UIntProperty"_fnv: + case L"UInt32Property"_fnv: + *(uint32_t*)((uintptr_t)self + offset) = value.as(); + return; + case L"UInt64Property"_fnv: + *(uint64_t*)((uintptr_t)self + offset) = value.as(); + return; + case L"Int64Property"_fnv: + *(int64_t*)((uintptr_t)self + offset) = value.as(); + return; + }; + + throw sol::error("Could not set enum property"); + } case L"NameProperty"_fnv: //return sol::make_object(s, self.get_property(name)); throw sol::error("Setting FName properties is not supported (yet)");