Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/reverse/BasicTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,14 +132,14 @@ struct TweakDBID

TweakDBID(const std::string_view aName)
{
name_hash = RED4ext::CRC32(aName.data(), 0);
name_hash = RED4ext::CRC32(reinterpret_cast<const uint8_t*>(aName.data()), aName.size(), 0);
name_length = static_cast<uint8_t>(aName.size());
unk5 = unk7 = 0;
}

TweakDBID(const TweakDBID& aBase, const std::string_view aName)
{
name_hash = RED4ext::CRC32(aName.data(), aBase.name_hash);
name_hash = RED4ext::CRC32(reinterpret_cast<const uint8_t*>(aName.data()), aName.size(), aBase.name_hash);
name_length = static_cast<uint8_t>(aName.size() + aBase.name_length);
unk5 = unk7 = 0;
}
Expand Down
23 changes: 2 additions & 21 deletions src/reverse/Converter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ auto s_metaVisitor =
}(LuaRED<int8_t, "Int8">(), LuaRED<int16_t, "Int16">(), LuaRED<int32_t, "Int32">(), LuaRED<int64_t, "Int64">(), LuaRED<uint8_t, "Uint8">(), LuaRED<uint16_t, "Uint16">(),
LuaRED<uint32_t, "Uint32">(), LuaRED<uint64_t, "Uint64">(), LuaRED<float, "Float">(), LuaRED<double, "Double">(), LuaRED<bool, "Bool">(), LuaRED<Quaternion, "Quaternion">(),
LuaRED<Vector3, "Vector3">(), LuaRED<Vector4, "Vector4">(), LuaRED<EulerAngles, "EulerAngles">(), LuaRED<ItemID, "gameItemID">(), LuaRED<Variant, "Variant">(),
LuaRED<CRUID, "CRUID">(), LuaRED<gamedataLocKeyWrapper, "gamedataLocKeyWrapper">(), CNameConverter(), TweakDBIDConverter(), EnumConverter(), ClassConverter(),
LuaRED<CRUID, "CRUID">(), LuaRED<gamedataLocKeyWrapper, "gamedataLocKeyWrapper">(), CNameConverter(), TweakDBIDConverter(), EnumConverter(), BitFieldConverter(),
ClassConverter(),
RawConverter() // Should always be last resort
);

Expand Down Expand Up @@ -85,23 +86,3 @@ RED4ext::CStackType Converter::ToRED(sol::object aObject, RED4ext::CBaseRTTIType

return r;
}

void Converter::ToRED(sol::object aObject, RED4ext::CStackType* apType)
{
auto initStackType = [&](auto& x)
{
if (x.Is(apType->type))
{
x.ToRED(aObject, apType);
return true;
}
return false;
};

auto f = [initStackType](auto&&... xs)
{
(... && !initStackType(xs));
};

s_metaVisitor(f);
}
131 changes: 56 additions & 75 deletions src/reverse/Converter.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ namespace Converter
size_t Size(RED4ext::CBaseRTTIType* apRtti);
sol::object ToLua(RED4ext::CStackType& aResult, TiltedPhoques::Locked<sol::state, std::recursive_mutex>& aLua);
RED4ext::CStackType ToRED(sol::object aObject, RED4ext::CBaseRTTIType* apRtti, TiltedPhoques::Allocator* apAllocator);
void ToRED(sol::object aObject, RED4ext::CStackType* apType);
} // namespace Converter

// Specialization manages special case implicit casting
Expand All @@ -38,20 +37,6 @@ struct CNameConverter : LuaRED<CName, "CName">

return result;
}

void ToRED(sol::object aObject, RED4ext::CStackType* apType)
{
if (aObject != sol::nil && aObject.get_type() == sol::type::string) // CName from String implicit cast
{
sol::state_view v(aObject.lua_state());
std::string str = v["tostring"](aObject);
*static_cast<CName*>(apType->value) = CName(str);
}
else
{
return LuaRED<CName, "CName">::ToRED(aObject, apType);
}
}
};

// Specialization manages special case implicit casting for TweakDBID
Expand All @@ -72,18 +57,6 @@ struct TweakDBIDConverter : LuaRED<TweakDBID, "TweakDBID">

return result;
}

void ToRED(sol::object aObject, RED4ext::CStackType* apType)
{
if (aObject != sol::nil && aObject.get_type() == sol::type::string)
{
*static_cast<TweakDBID*>(apType->value) = TweakDBID(aObject.as<std::string>());
}
else
{
LuaRED<TweakDBID, "TweakDBID">::ToRED(aObject, apType);
}
}
};

// Specialization manages wrapping and converting RT_Enum
Expand Down Expand Up @@ -137,43 +110,75 @@ struct EnumConverter : LuaRED<Enum, "Enum">
return result;
}

void ToRED(sol::object aObject, RED4ext::CStackType* apType)
size_t Size() const noexcept { return m_pRtti ? m_pRtti->GetSize() : 0; }

bool Is(RED4ext::CBaseRTTIType* apRtti) const
{
if (aObject.is<Enum>())
if (apRtti->GetType() == RED4ext::ERTTIType::Enum)
{
auto* pEnum = aObject.as<Enum*>();
if (pEnum->GetType() == apType->type)
{
pEnum->Set(*apType);
}
m_pRtti = apRtti;
return true;
}
else if (aObject == sol::nil)

return false;
}
};

// Specialization manages wrapping and converting RT_BitField
struct BitFieldConverter : LuaRED<uint64_t, "BitField">
{
sol::object ToLua(RED4ext::CStackType& aResult, TiltedPhoques::Locked<sol::state, std::recursive_mutex>& aLua)
{
uint64_t value;

switch (m_pRtti->GetSize())
{
auto* enumType = static_cast<RED4ext::CEnum*>(apType->type);
const Enum en(enumType, 0);
en.Set(*apType);
case sizeof(uint8_t): value = *static_cast<uint8_t*>(aResult.value); break;
case sizeof(uint16_t): value = *static_cast<uint16_t*>(aResult.value); break;
case sizeof(uint32_t): value = *static_cast<uint32_t*>(aResult.value); break;
case sizeof(uint64_t): value = *static_cast<uint64_t*>(aResult.value); break;
}
else if (aObject.get_type() == sol::type::number) // Enum from number cast

auto res{aLua.Get().script(fmt::format("return {}ull", value))};
assert(res.valid());
return res.get<sol::object>();
}

RED4ext::CStackType ToRED(sol::object aObject, RED4ext::CBaseRTTIType* apRtti, TiltedPhoques::Allocator* apAllocator)
{
RED4ext::CStackType result;
result.type = apRtti;
result.value = apAllocator->Allocate(apRtti->GetSize());

uint64_t value = 0;

if (aObject.get_type() == sol::type::number)
{
auto* enumType = static_cast<RED4ext::CEnum*>(apType->type);
const Enum en(enumType, aObject.as<uint32_t>());
en.Set(*apType);
value = aObject.as<uint32_t>();
}
else if (aObject.get_type() == sol::type::string) // Enum from string cast
else if (IsLuaCData(aObject))
{
auto* enumType = static_cast<RED4ext::CEnum*>(apType->type);
sol::state_view v(aObject.lua_state());
std::string str = v["tostring"](aObject);
const Enum en(enumType, str);
en.Set(*apType);
value = std::stoull(str);
}

switch (m_pRtti->GetSize())
{
case sizeof(uint8_t): *static_cast<uint8_t*>(result.value) = static_cast<uint8_t>(value); break;
case sizeof(uint16_t): *static_cast<uint16_t*>(result.value) = static_cast<uint16_t>(value); break;
case sizeof(uint32_t): *static_cast<uint32_t*>(result.value) = static_cast<uint32_t>(value); break;
case sizeof(uint64_t): *static_cast<uint64_t*>(result.value) = value; break;
}

return result;
}

size_t Size() const noexcept { return m_pRtti ? m_pRtti->GetSize() : 0; }

bool Is(RED4ext::CBaseRTTIType* apRtti) const
{
if (apRtti->GetType() == RED4ext::ERTTIType::Enum)
if (apRtti->GetType() == RED4ext::ERTTIType::BitField)
{
m_pRtti = apRtti;
return true;
Expand All @@ -199,12 +204,12 @@ struct ClassConverter : LuaRED<ClassReference, "ClassReference">
{
result.value = aObject.as<ClassReference*>()->GetHandle();
}
else if (aObject == sol::nil)
{
result.value = RTTIHelper::Get().NewInstance(apRtti, sol::nullopt, apAllocator);
}
// Disabled until new allocator is implemented
// Current implementation can leak
// else if (aObject == sol::nil)
// {
// result.value = RTTIHelper::Get().NewInstance(apRtti, sol::nullopt, apAllocator);
// }
// else if (aObject.get_type() == sol::type::table)
//{
// // The implicit table to instance conversion `Game.FindEntityByID({ hash = 1 })` has potential issue:
Expand All @@ -228,18 +233,6 @@ struct ClassConverter : LuaRED<ClassReference, "ClassReference">
return result;
}

void ToRED(sol::object aObject, RED4ext::CStackType* apType)
{
if (aObject.is<ClassReference>())
{
apType->value = aObject.as<ClassReference*>()->GetHandle();
}
else
{
apType->value = nullptr;
}
}

size_t Size() const noexcept { return m_pRtti ? m_pRtti->GetSize() : 0; }

bool Is(RED4ext::CBaseRTTIType* apRtti) const
Expand Down Expand Up @@ -278,18 +271,6 @@ struct RawConverter : LuaRED<UnknownType, "UnknownType">
return result;
}

void ToRED(sol::object aObject, RED4ext::CStackType* apType)
{
if (aObject.is<UnknownType>())
{
apType->value = aObject.as<UnknownType*>()->GetHandle();
}
else
{
apType->value = nullptr;
}
}

size_t Size() const noexcept { return m_pRtti ? m_pRtti->GetSize() : 0; }

bool Is(RED4ext::CBaseRTTIType* apRtti) const
Expand Down
48 changes: 0 additions & 48 deletions src/reverse/LuaRED.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,54 +77,6 @@ template <class T, FixedString REDName> struct LuaRED
return result;
}

void ToRED(sol::object aObject, RED4ext::CStackType* apType)
{
if (aObject == sol::nil)
{
*reinterpret_cast<T*>(apType->value) = T{};
}
else if constexpr (std::is_integral_v<T> && sizeof(T) == sizeof(uint64_t))
{
if (aObject.get_type() == sol::type::number)
{
sol::state_view v(aObject.lua_state());
double value = v["tonumber"](aObject);
*reinterpret_cast<T*>(apType->value) = static_cast<T>(value);
}
else if (IsLuaCData(aObject))
{
sol::state_view v(aObject.lua_state());
std::string str = v["tostring"](aObject);
if constexpr (std::is_signed_v<T>)
*reinterpret_cast<T*>(apType->value) = std::stoll(str);
else
*reinterpret_cast<T*>(apType->value) = std::stoull(str);
}
}
else if constexpr (std::is_same_v<T, bool>)
{
if (aObject.get_type() == sol::type::boolean)
*reinterpret_cast<T*>(apType->value) = aObject.as<T>();
}
else if constexpr (std::is_arithmetic_v<T>)
{
if (aObject.get_type() == sol::type::number)
{
*reinterpret_cast<T*>(apType->value) = aObject.as<T>();
}
else if (IsLuaCData(aObject))
{
sol::state_view v(aObject.lua_state());
double value = v["tonumber"](aObject);
*reinterpret_cast<T*>(apType->value) = static_cast<T>(value);
}
}
else if (aObject.is<T>())
{
*reinterpret_cast<T*>(apType->value) = aObject.as<T>();
}
}

size_t Size() const noexcept { return sizeof(T); }

bool Is(RED4ext::CBaseRTTIType* apRtti) const
Expand Down
9 changes: 3 additions & 6 deletions src/reverse/NativeProxy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,15 +158,12 @@ void NativeProxy::Callback(RED4ext::IScriptable* apSelf, RED4ext::CStackFrame* a
if (functionIt == self->m_functions.end())
return;

TiltedPhoques::StackAllocator<1 << 13> allocator;
const auto pAllocator = TiltedPhoques::Allocator::Get();
TiltedPhoques::Allocator::Set(&allocator);
TiltedPhoques::Vector<sol::object> args(0);
TiltedPhoques::Allocator::Set(pAllocator);

auto lockedState = self->m_lua.Lock();
auto& luaState = lockedState.Get();

TiltedPhoques::Vector<sol::object> args(0);
args.reserve(apFrame->func->params.size);

for (const auto& param : apFrame->func->params)
{
RED4ext::CStackType arg;
Expand Down
Loading
Loading