Skip to content

Commit

Permalink
Fix: scriptable system parser was not reading values from proper offsets
Browse files Browse the repository at this point in the history
- How this worked is beyond me
- Refactored to use the older implementation (without default value insertion)
- As class instantiation takes care of that anyway
  • Loading branch information
not_alphanine committed May 8, 2024
1 parent 2b7f84d commit 379cf6b
Show file tree
Hide file tree
Showing 11 changed files with 331 additions and 299 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,10 @@ class NativeReader
throw std::runtime_error(std::format("NativeReader::ReadValue, unknown value type {}", typeName.ToString()));
}
public:
virtual ~NativeReader()
{

}
virtual void ReadClass(FileCursor& aCursor, Red::ScriptInstance aOut, Red::CBaseRTTIType* aClass) = 0;
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ struct OptimizedFieldHeader
class ScriptableReader : redRTTI::native::NativeReader
{
std::vector<Red::CName>* m_names;
static constexpr auto m_reportNonCriticalErrors = false;

Red::CName ReadCNameInternal(FileCursor& aCursor)
{
Expand Down Expand Up @@ -155,6 +156,11 @@ class ScriptableReader : redRTTI::native::NativeReader

}

virtual ~ScriptableReader()
{

}

inline std::vector<Red::CName>* GetNames()
{
return m_names;
Expand All @@ -167,53 +173,42 @@ class ScriptableReader : redRTTI::native::NativeReader
const auto baseOffset = aCursor.offset;
const auto fieldCount = aCursor.readUShort();

auto fieldDescriptors = aCursor.ReadMultipleClasses<RedPackageFieldHeader>(fieldCount);
std::unordered_map<Red::CName, OptimizedFieldHeader> fieldDescMap{};

// I'm not sure if this is necessary, given the class will have some default initialization?

std::transform(fieldDescriptors.begin(), fieldDescriptors.end(),
std::inserter(fieldDescMap, fieldDescMap.end()),
[this](RedPackageFieldHeader aHeader)
{
const auto names = this->GetNames();
auto optimized = OptimizedFieldHeader::Make(aHeader, names);
return std::make_pair(optimized.m_name, optimized);
});

Red::DynArray<Red::CProperty*> classProps{};

classType->GetProperties(classProps);

for (auto propData : classProps)
for (auto desc : aCursor.ReadMultipleClasses<RedPackageFieldHeader>(fieldCount))
{
// Only bother with loading savable properties
if (propData->flags.isPersistent == 0 && propData->flags.isSavable == 0)
{
continue;
}

auto saveProp = fieldDescMap.find(propData->name);
const auto propName = m_names->at(desc.m_nameId);
const auto propData = classType->GetProperty(propName);

if (saveProp == fieldDescMap.end())
// No prop...
if (!propData)
{
if constexpr (m_reportNonCriticalErrors)
{
PluginContext::Error(std::format("NativeScriptableReader::ReadClass, couldn't find {}.{}",
classType->GetName().ToString(), propName.ToString()));
}

continue;
}

auto storedType = PluginContext::m_rtti->GetType(saveProp->second.m_type);

if (!storedType || propData->type != storedType)
if (propData->type->GetName() != m_names->at(desc.m_typeId))
{
PluginContext::Error(std::format("NativeScriptableReader::ReadClass, class {}, property type mismatch - {} != {}",
classType->GetName().ToString(), saveProp->second.m_type.ToString(),
propData->type->GetName().ToString()));
if constexpr (m_reportNonCriticalErrors)
{
PluginContext::Error(
std::format("NativeScriptableReader::ReadClass, class {}, property type mismatch - {} != {}",
classType->GetName().ToString(), propData->type->GetName().ToString(),
m_names->at(desc.m_typeId).ToString()));
}
continue;
}

aCursor.seekTo(FileCursor::SeekTo::Start, baseOffset + desc.m_offset);

auto propPtr = propData->GetValuePtr<std::remove_pointer_t<Red::ScriptInstance>>(aOut);

try
{
ReadValue(aCursor, propPtr, storedType);
ReadValue(aCursor, propPtr, propData->type);
}
catch (const std::exception& e)
{
Expand Down
Loading

0 comments on commit 379cf6b

Please sign in to comment.