mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-05-10 06:24:57 +00:00
Add base for calculation sizes of structs for StructuredDataDef
This commit is contained in:
parent
c131c58bbe
commit
77420495f6
@ -3,6 +3,7 @@
|
||||
#include <sstream>
|
||||
|
||||
#include "Parsing/Simple/Matcher/SimpleMatcherFactory.h"
|
||||
#include "StructuredDataDef/Parsing/StructuredDataDefSizeCalculator.h"
|
||||
|
||||
namespace sdd::def_scope_sequences
|
||||
{
|
||||
@ -223,6 +224,18 @@ namespace sdd::def_scope_sequences
|
||||
}
|
||||
}
|
||||
|
||||
static void CalculateSizesAndOffsetsForDef(const StructuredDataDefParserState* state)
|
||||
{
|
||||
try
|
||||
{
|
||||
StructuredDataDefSizeCalculator::CalculateSizesAndOffsetsForDef(*state->m_current_def);
|
||||
}
|
||||
catch(SizeCalculationException& e)
|
||||
{
|
||||
throw ParsingException(TokenPos(), e.Message());
|
||||
}
|
||||
}
|
||||
|
||||
static void SetDefSizeFromRootStruct(const StructuredDataDefParserState* state)
|
||||
{
|
||||
if (state->m_current_def->m_root_type.m_category == CommonStructuredDataTypeCategory::STRUCT
|
||||
@ -242,7 +255,7 @@ namespace sdd::def_scope_sequences
|
||||
CreateDefaultStructWhenNoStructsSpecified(state);
|
||||
EnsureAllUsedTypesHaveBeenDefined(state);
|
||||
ReplaceUndefinedTypeReference(state);
|
||||
// TODO: Calculate struct sizes and property offsets
|
||||
CalculateSizesAndOffsetsForDef(state);
|
||||
SetDefSizeFromRootStruct(state);
|
||||
|
||||
if (!state->m_checksum_overriden)
|
||||
|
@ -0,0 +1,143 @@
|
||||
#include "StructuredDataDefSizeCalculator.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <sstream>
|
||||
|
||||
#include "Utils/ClassUtils.h"
|
||||
|
||||
using namespace sdd;
|
||||
|
||||
SizeCalculationException::SizeCalculationException(std::string message)
|
||||
: m_message(std::move(message))
|
||||
{
|
||||
}
|
||||
|
||||
const std::string& SizeCalculationException::Message() const
|
||||
{
|
||||
return m_message;
|
||||
}
|
||||
|
||||
char const* SizeCalculationException::what() const
|
||||
{
|
||||
return m_message.c_str();
|
||||
}
|
||||
|
||||
class StructuredDataDefSizeCalculatorInternal
|
||||
{
|
||||
CommonStructuredDataDef& m_def;
|
||||
std::vector<CommonStructuredDataType> m_type_stack;
|
||||
std::vector<bool> m_struct_in_calculation;
|
||||
std::vector<bool> m_struct_calculated;
|
||||
std::vector<bool> m_indexed_array_calculated;
|
||||
std::vector<bool> m_enumed_array_calculated;
|
||||
|
||||
_NORETURN void ThrowCircularDependencyException(const size_t structIndex) const
|
||||
{
|
||||
assert(structIndex < m_def.m_structs.size());
|
||||
|
||||
std::ostringstream ss;
|
||||
|
||||
ss << "Circular dependencies detected: ";
|
||||
|
||||
auto foundDependencyChainStart = false;
|
||||
for(const auto& type : m_type_stack)
|
||||
{
|
||||
if(foundDependencyChainStart)
|
||||
{
|
||||
if(type.m_category == CommonStructuredDataTypeCategory::STRUCT)
|
||||
{
|
||||
assert(type.m_info.type_index < m_def.m_structs.size());
|
||||
ss << " -> " << m_def.m_structs[type.m_info.type_index]->m_name;
|
||||
}
|
||||
}
|
||||
else if (type.m_category == CommonStructuredDataTypeCategory::STRUCT && type.m_info.type_index == structIndex)
|
||||
{
|
||||
foundDependencyChainStart = true;
|
||||
ss << m_def.m_structs[structIndex]->m_name;
|
||||
}
|
||||
}
|
||||
|
||||
ss << " -> " << m_def.m_structs[structIndex]->m_name;
|
||||
|
||||
throw SizeCalculationException(ss.str());
|
||||
}
|
||||
|
||||
void CalculateForStruct(const size_t index, CommonStructuredDataStruct& _struct)
|
||||
{
|
||||
if (m_struct_calculated[index])
|
||||
return;
|
||||
|
||||
if (m_struct_in_calculation[index])
|
||||
ThrowCircularDependencyException(index);
|
||||
m_struct_in_calculation[index] = true;
|
||||
|
||||
m_type_stack.emplace_back(CommonStructuredDataTypeCategory::STRUCT, index);
|
||||
|
||||
// TODO: Actually calculate stuff
|
||||
|
||||
m_struct_calculated[index] = true;
|
||||
m_type_stack.pop_back();
|
||||
}
|
||||
|
||||
void CalculateForIndexedArray(size_t index, CommonStructuredDataIndexedArray& indexedArray)
|
||||
{
|
||||
// TODO: Actually calculate stuff
|
||||
}
|
||||
|
||||
void CalculateForEnumedArray(size_t index, CommonStructuredDataEnumedArray& enumedArray)
|
||||
{
|
||||
// TODO: Actually calculate stuff
|
||||
}
|
||||
|
||||
void CalculateForType(const CommonStructuredDataType type)
|
||||
{
|
||||
switch (type.m_category)
|
||||
{
|
||||
case CommonStructuredDataTypeCategory::STRUCT:
|
||||
assert(type.m_info.type_index < m_def.m_structs.size());
|
||||
CalculateForStruct(type.m_info.type_index, *m_def.m_structs[type.m_info.type_index]);
|
||||
break;
|
||||
case CommonStructuredDataTypeCategory::INDEXED_ARRAY:
|
||||
assert(type.m_info.type_index < m_def.m_indexed_arrays.size());
|
||||
CalculateForIndexedArray(type.m_info.type_index, m_def.m_indexed_arrays[type.m_info.type_index]);
|
||||
break;
|
||||
case CommonStructuredDataTypeCategory::ENUM_ARRAY:
|
||||
assert(type.m_info.type_index < m_def.m_enumed_arrays.size());
|
||||
CalculateForEnumedArray(type.m_info.type_index, m_def.m_enumed_arrays[type.m_info.type_index]);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
explicit StructuredDataDefSizeCalculatorInternal(CommonStructuredDataDef& def)
|
||||
: m_def(def),
|
||||
m_struct_in_calculation(def.m_structs.size()),
|
||||
m_struct_calculated(def.m_structs.size()),
|
||||
m_indexed_array_calculated(def.m_indexed_arrays.size()),
|
||||
m_enumed_array_calculated(def.m_enumed_arrays.size())
|
||||
{
|
||||
}
|
||||
|
||||
void CalculateSizesAndOffsets()
|
||||
{
|
||||
auto index = 0u;
|
||||
for (auto& _struct : m_def.m_structs)
|
||||
CalculateForStruct(index++, *_struct);
|
||||
|
||||
index = 0u;
|
||||
for (auto& indexedArray : m_def.m_indexed_arrays)
|
||||
CalculateForIndexedArray(index++, indexedArray);
|
||||
|
||||
index = 0u;
|
||||
for (auto& enumedArray : m_def.m_enumed_arrays)
|
||||
CalculateForEnumedArray(index++, enumedArray);
|
||||
}
|
||||
};
|
||||
|
||||
void StructuredDataDefSizeCalculator::CalculateSizesAndOffsetsForDef(CommonStructuredDataDef& def)
|
||||
{
|
||||
StructuredDataDefSizeCalculatorInternal calculator(def);
|
||||
calculator.CalculateSizesAndOffsets();
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <exception>
|
||||
|
||||
#include "Utils/ClassUtils.h"
|
||||
#include "StructuredDataDef/CommonStructuredDataDef.h"
|
||||
|
||||
namespace sdd
|
||||
{
|
||||
class SizeCalculationException final : std::exception
|
||||
{
|
||||
std::string m_message;
|
||||
|
||||
public:
|
||||
explicit SizeCalculationException(std::string message);
|
||||
|
||||
_NODISCARD const std::string& Message() const;
|
||||
_NODISCARD char const* what() const override;
|
||||
};
|
||||
|
||||
class StructuredDataDefSizeCalculator
|
||||
{
|
||||
public:
|
||||
static void CalculateSizesAndOffsetsForDef(CommonStructuredDataDef& def);
|
||||
};
|
||||
}
|
@ -16,10 +16,16 @@
|
||||
#undef _NODISCARD
|
||||
#endif
|
||||
|
||||
#ifdef _NORETURN
|
||||
#undef _NORETURN
|
||||
#endif
|
||||
|
||||
#if _CPP_VERSION >= 201703L
|
||||
#define _NODISCARD [[nodiscard]]
|
||||
#define _NORETURN [[noreturn]]
|
||||
#else
|
||||
#define _NODISCARD
|
||||
#define _NORETURN
|
||||
#endif
|
||||
|
||||
template <class T>
|
||||
|
Loading…
x
Reference in New Issue
Block a user