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 <sstream>
|
||||||
|
|
||||||
#include "Parsing/Simple/Matcher/SimpleMatcherFactory.h"
|
#include "Parsing/Simple/Matcher/SimpleMatcherFactory.h"
|
||||||
|
#include "StructuredDataDef/Parsing/StructuredDataDefSizeCalculator.h"
|
||||||
|
|
||||||
namespace sdd::def_scope_sequences
|
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)
|
static void SetDefSizeFromRootStruct(const StructuredDataDefParserState* state)
|
||||||
{
|
{
|
||||||
if (state->m_current_def->m_root_type.m_category == CommonStructuredDataTypeCategory::STRUCT
|
if (state->m_current_def->m_root_type.m_category == CommonStructuredDataTypeCategory::STRUCT
|
||||||
@ -242,7 +255,7 @@ namespace sdd::def_scope_sequences
|
|||||||
CreateDefaultStructWhenNoStructsSpecified(state);
|
CreateDefaultStructWhenNoStructsSpecified(state);
|
||||||
EnsureAllUsedTypesHaveBeenDefined(state);
|
EnsureAllUsedTypesHaveBeenDefined(state);
|
||||||
ReplaceUndefinedTypeReference(state);
|
ReplaceUndefinedTypeReference(state);
|
||||||
// TODO: Calculate struct sizes and property offsets
|
CalculateSizesAndOffsetsForDef(state);
|
||||||
SetDefSizeFromRootStruct(state);
|
SetDefSizeFromRootStruct(state);
|
||||||
|
|
||||||
if (!state->m_checksum_overriden)
|
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
|
#undef _NODISCARD
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef _NORETURN
|
||||||
|
#undef _NORETURN
|
||||||
|
#endif
|
||||||
|
|
||||||
#if _CPP_VERSION >= 201703L
|
#if _CPP_VERSION >= 201703L
|
||||||
#define _NODISCARD [[nodiscard]]
|
#define _NODISCARD [[nodiscard]]
|
||||||
|
#define _NORETURN [[noreturn]]
|
||||||
#else
|
#else
|
||||||
#define _NODISCARD
|
#define _NODISCARD
|
||||||
|
#define _NORETURN
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user