diff --git a/src/ZoneCodeGeneratorLib/Generating/Templates/Internal/BaseTemplate.cpp b/src/ZoneCodeGeneratorLib/Generating/Templates/Internal/BaseTemplate.cpp index 9b8b39d1..57b8f6d4 100644 --- a/src/ZoneCodeGeneratorLib/Generating/Templates/Internal/BaseTemplate.cpp +++ b/src/ZoneCodeGeneratorLib/Generating/Templates/Internal/BaseTemplate.cpp @@ -98,6 +98,15 @@ std::string BaseTemplate::MakeMemberAccess(StructureInformation* info, MemberInf return str.str(); } +std::string BaseTemplate::MakeMemberAccess(const std::string& variableName, StructureInformation* info, MemberInformation* member, const DeclarationModifierComputations& modifier) +{ + std::ostringstream str; + str << variableName << "->" << member->m_member->m_name; + MakeArrayIndicesInternal(modifier, str); + + return str.str(); +} + std::string BaseTemplate::MakeTypeDecl(const TypeDeclaration* decl) { std::ostringstream str; diff --git a/src/ZoneCodeGeneratorLib/Generating/Templates/Internal/BaseTemplate.h b/src/ZoneCodeGeneratorLib/Generating/Templates/Internal/BaseTemplate.h index 194c2d49..8b478cb6 100644 --- a/src/ZoneCodeGeneratorLib/Generating/Templates/Internal/BaseTemplate.h +++ b/src/ZoneCodeGeneratorLib/Generating/Templates/Internal/BaseTemplate.h @@ -40,6 +40,7 @@ protected: static std::string MakeTypePtrVarName(const DataDefinition* def); static std::string MakeSafeTypeName(const DataDefinition* def); static std::string MakeMemberAccess(StructureInformation* info, MemberInformation* member, const DeclarationModifierComputations& modifier); + static std::string MakeMemberAccess(const std::string& variableName, StructureInformation* info, MemberInformation* member, const DeclarationModifierComputations& modifier); static std::string MakeTypeDecl(const TypeDeclaration* decl); static std::string MakeFollowingReferences(const std::vector& modifiers); static std::string MakeArrayIndices(const DeclarationModifierComputations& modifierComputations); diff --git a/src/ZoneCodeGeneratorLib/Generating/Templates/ZoneWriteTemplate.cpp b/src/ZoneCodeGeneratorLib/Generating/Templates/ZoneWriteTemplate.cpp index 3ab13566..ecda827c 100644 --- a/src/ZoneCodeGeneratorLib/Generating/Templates/ZoneWriteTemplate.cpp +++ b/src/ZoneCodeGeneratorLib/Generating/Templates/ZoneWriteTemplate.cpp @@ -128,7 +128,7 @@ class ZoneWriteTemplate::Internal final : BaseTemplate { LINE("varScriptString = " << MakeMemberAccess(info, member, modifier) << ";") LINE("WriteScriptStringArray(true, " << MakeEvaluation(modifier.GetArrayPointerCountEvaluation()) << ");") - LINE("m_stream->MarkFollowing("<MarkFollowing("<MarkFollowing(" << MakeMemberAccess("writtenData", info, member, modifier) << ");") } } else @@ -209,8 +210,8 @@ class ZoneWriteTemplate::Internal final : BaseTemplate { LINE("m_stream->Write<" << MakeTypeDecl(member->m_member->m_type_declaration.get()) << MakeFollowingReferences(modifier.GetFollowingDeclarationModifiers()) << ">(" << MakeMemberAccess(info, member, modifier) << ", " << MakeEvaluation(modifier.GetArrayPointerCountEvaluation()) << ");") - LINE("m_stream->MarkFollowing("<MarkFollowing(" << MakeMemberAccess("writtenData", info, member, modifier) << ");") } void WriteMember_PointerArray(StructureInformation* info, MemberInformation* member, const DeclarationModifierComputations& modifier) const @@ -223,6 +224,7 @@ class ZoneWriteTemplate::Internal final : BaseTemplate else { LINE("WritePtrArray_" << MakeSafeTypeName(member->m_member->m_type_declaration->m_type) << "(true, " << MakeEvaluation(modifier.GetPointerArrayCountEvaluation()) << ");") + LINE("m_stream->MarkFollowing("<m_definition->GetType() == DataDefinitionType::UNION && StructureComputations(info).GetDynamicMember())) + memberAccess = MakeMemberAccess("originalData", info, member, modifier); + else + memberAccess = MakeMemberAccess(info, member, modifier); + if (!member->m_is_leaf) { - LINE(MakeTypeVarName(member->m_member->m_type_declaration->m_type) << " = " << MakeMemberAccess(info, member, modifier) << ";") - if (computations.IsAfterPartialLoad()) { + LINE(MakeTypeVarName(member->m_member->m_type_declaration->m_type)<<" = "<m_member->m_type_declaration->m_type) << "(true, " << arraySizeStr << ");") } else { + LINE(MakeTypeVarName(member->m_member->m_type_declaration->m_type) << " = " << MakeMemberAccess(info, member, modifier) << ";") LINE("WriteArray_" << MakeSafeTypeName(member->m_member->m_type_declaration->m_type) << "(false, " << arraySizeStr << ");") } } else if (computations.IsAfterPartialLoad()) { LINE("m_stream->Write<" << MakeTypeDecl(member->m_member->m_type_declaration.get()) << MakeFollowingReferences(modifier.GetFollowingDeclarationModifiers()) - << ">(" << MakeMemberAccess(info, member, modifier) << ", " << arraySizeStr << ");") + << ">(" << memberAccess << ", " << arraySizeStr << ");") } } void WriteMember_DynamicArray(StructureInformation* info, MemberInformation* member, const DeclarationModifierComputations& modifier) const { + std::string memberAccess; + if(!(info->m_definition->GetType() == DataDefinitionType::UNION && StructureComputations(info).GetDynamicMember())) + memberAccess = MakeMemberAccess("originalData", info, member, modifier); + else + memberAccess = MakeMemberAccess(info, member, modifier); + if (member->m_type && !member->m_type->m_is_leaf) { - LINE(MakeTypeVarName(member->m_member->m_type_declaration->m_type) << " = " << MakeMemberAccess(info, member, modifier) << ";") + LINE(MakeTypeVarName(member->m_member->m_type_declaration->m_type) << " = " << memberAccess << ";") LINE("WriteArray_" << MakeSafeTypeName(member->m_member->m_type_declaration->m_type) << "(true, " << MakeEvaluation(modifier.GetDynamicArraySizeEvaluation()) << ");") } else { LINE("m_stream->Write<" << MakeTypeDecl(member->m_member->m_type_declaration.get()) << MakeFollowingReferences(modifier.GetFollowingDeclarationModifiers()) - << ">(" << MakeMemberAccess(info, member, modifier) << ", " << MakeEvaluation(modifier.GetDynamicArraySizeEvaluation()) << ");") + << ">(" << memberAccess << ", " << MakeEvaluation(modifier.GetDynamicArraySizeEvaluation()) << ");") } } void WriteMember_Embedded(StructureInformation* info, MemberInformation* member, const DeclarationModifierComputations& modifier) const { const MemberComputations computations(member); + + std::string memberAccess; + if (!(info->m_definition->GetType() == DataDefinitionType::UNION && StructureComputations(info).GetDynamicMember())) + memberAccess = MakeMemberAccess("originalData", info, member, modifier); + else + memberAccess = MakeMemberAccess(info, member, modifier); + if (!member->m_is_leaf) { - LINE(MakeTypeVarName(member->m_member->m_type_declaration->m_type) << " = &" << MakeMemberAccess(info, member, modifier) << ";") - if (computations.IsAfterPartialLoad()) { + LINE(MakeTypeVarName(member->m_member->m_type_declaration->m_type) << " = &" << memberAccess << ";") LINE("Write_" << MakeSafeTypeName(member->m_member->m_type_declaration->m_type) << "(true);") } else { + LINE(MakeTypeVarName(member->m_member->m_type_declaration->m_type) << " = &" << MakeMemberAccess(info, member, modifier) << ";") LINE("Write_" << MakeSafeTypeName(member->m_member->m_type_declaration->m_type) << "(false);") } } else if (computations.IsAfterPartialLoad()) { LINE("m_stream->Write<" << MakeTypeDecl(member->m_member->m_type_declaration.get()) << MakeFollowingReferences(modifier.GetFollowingDeclarationModifiers()) - << ">(&" << MakeMemberAccess(info, member, modifier) << ");") + << ">(&" << memberAccess << ");") } } @@ -305,8 +326,8 @@ class ZoneWriteTemplate::Internal final : BaseTemplate { LINE("m_stream->Write<" << MakeTypeDecl(member->m_member->m_type_declaration.get()) << MakeFollowingReferences(modifier.GetFollowingDeclarationModifiers()) << ">(" << MakeMemberAccess(info, member, modifier) << ");") - LINE("m_stream->MarkFollowing("<MarkFollowing(" << MakeMemberAccess("writtenData", info, member, modifier) << ");") } void WriteMember_TypeCheck(StructureInformation* info, MemberInformation* member, const DeclarationModifierComputations& modifier, const MemberWriteType writeType) const @@ -358,7 +379,50 @@ class ZoneWriteTemplate::Internal final : BaseTemplate } } - static bool WriteMember_ShouldMakeAlloc(StructureInformation* info, MemberInformation* member, const DeclarationModifierComputations& modifier, const MemberWriteType writeType) + static bool WriteMember_ShouldMakeInsertReuse(StructureInformation* info, MemberInformation* member, const DeclarationModifierComputations& modifier, const MemberWriteType writeType) + { + if (writeType != MemberWriteType::ARRAY_POINTER + && writeType != MemberWriteType::SINGLE_POINTER + && writeType != MemberWriteType::POINTER_ARRAY) + { + return false; + } + + if (writeType == MemberWriteType::POINTER_ARRAY + && modifier.IsArray()) + { + return false; + } + + return true; + } + + void WriteMember_InsertReuse(StructureInformation* info, MemberInformation* member, const DeclarationModifierComputations& modifier, const MemberWriteType writeType) + { + if (!WriteMember_ShouldMakeInsertReuse(info, member, modifier, writeType) + || !member->m_is_reusable) + { + WriteMember_TypeCheck(info, member, modifier, writeType); + return; + } + + if(writeType == MemberWriteType::ARRAY_POINTER) + { + LINE("m_stream->ReusableAddOffset("<ReusableAddOffset("<ReusableAddOffset("<Align("<m_is_reusable) { - WriteMember_Alloc(info, member, modifier, writeType); + WriteMember_Align(info, member, modifier, writeType); return; } @@ -439,7 +503,7 @@ class ZoneWriteTemplate::Internal final : BaseTemplate LINE("{") m_intendation++; - WriteMember_Alloc(info, member, modifier, writeType); + WriteMember_Align(info, member, modifier, writeType); m_intendation--; LINE("}") @@ -679,23 +743,31 @@ class ZoneWriteTemplate::Internal final : BaseTemplate if (!(info->m_definition->GetType() == DataDefinitionType::UNION && dynamicMember)) { LINE("") + + if(dynamicMember) + { + LINE("auto* originalData = "<m_definition)<<";") + } + LINE("if(atStreamStart)") m_intendation++; if (dynamicMember == nullptr) { - LINE(MakeTypeVarName(info->m_definition)<<"= m_stream->Write<" << info->m_definition->GetFullName() << ">(" << MakeTypeVarName(info->m_definition) << "); // Size: " << info-> + LINE(MakeTypeVarName(info->m_definition)<<" = m_stream->Write<" << info->m_definition->GetFullName() << ">(" << MakeTypeVarName(info->m_definition) << "); // Size: " << info-> m_definition->GetSize()) } else { - // TODO: Introduce "full" variable that enables writing of second part - LINE(MakeTypeVarName(info->m_definition) << "= m_stream->WritePartial<" << info->m_definition->GetFullName() << ">(" << MakeTypeVarName(info->m_definition) << ", offsetof(" << info-> + LINE(MakeTypeVarName(info->m_definition) << " = m_stream->WritePartial<" << info->m_definition->GetFullName() << ">(" << MakeTypeVarName(info->m_definition) << ", offsetof(" << info-> m_definition->GetFullName() << ", " << dynamicMember->m_member->m_name << "));") } m_intendation--; + + LINE("") + LINE("auto* writtenData = "<m_definition)<<";") } else { @@ -750,7 +822,7 @@ class ZoneWriteTemplate::Internal final : BaseTemplate m_intendation++; LINE("m_stream->Align(" << info->m_definition->GetAlignment() << ");") - + LINE("m_stream->ReusableAddOffset(*"<m_definition)<<");") LINE("") if (!info->m_is_leaf) { @@ -824,10 +896,15 @@ class ZoneWriteTemplate::Internal final : BaseTemplate LINE("}") } - void PrintWritePtrArrayMethod_Loading(const DataDefinition* def, StructureInformation* info) const + void PrintWritePtrArrayMethod_Loading(const DataDefinition* def, StructureInformation* info, const bool reusable) const { LINE("m_stream->Align("<GetAlignment()<<");") + if(reusable) + { + LINE("m_stream->ReusableAddOffset(*"<m_is_leaf) { LINE(MakeTypeVarName(info->m_definition) << " = *" << MakeTypePtrVarName(def) << ";") @@ -859,14 +936,14 @@ class ZoneWriteTemplate::Internal final : BaseTemplate LINE("{") m_intendation++; - PrintWritePtrArrayMethod_Loading(def, info); + PrintWritePtrArrayMethod_Loading(def, info, reusable); m_intendation--; LINE("}") } else { - PrintWritePtrArrayMethod_Loading(def, info); + PrintWritePtrArrayMethod_Loading(def, info, reusable); } } diff --git a/src/ZoneWriting/Zone/Stream/IZoneOutputStream.h b/src/ZoneWriting/Zone/Stream/IZoneOutputStream.h index e1244a4c..40768515 100644 --- a/src/ZoneWriting/Zone/Stream/IZoneOutputStream.h +++ b/src/ZoneWriting/Zone/Stream/IZoneOutputStream.h @@ -19,19 +19,26 @@ public: virtual void IncBlockPos(size_t size) = 0; virtual void WriteNullTerminated(const void* dst) = 0; - virtual bool ReusableShouldWrite(void** pPtr, size_t size, size_t count, std::type_index type) = 0; + virtual bool ReusableShouldWrite(void** pPtr, size_t size, std::type_index type) = 0; + virtual void ReusableAddOffset(void* ptr, size_t size, size_t count, std::type_index type) = 0; virtual void MarkFollowing(void** pPtr) = 0; template bool ReusableShouldWrite(T** pPtr) { - return ReusableShouldWrite(reinterpret_cast(reinterpret_cast(pPtr)), sizeof(T), 1, std::type_index(typeid(T))); + return ReusableShouldWrite(reinterpret_cast(reinterpret_cast(pPtr)), sizeof(T), std::type_index(typeid(T))); } template - bool ReusableShouldWrite(T** pPtr, const size_t count) + void ReusableAddOffset(T* ptr) { - return ReusableShouldWrite(reinterpret_cast(reinterpret_cast(pPtr)), sizeof(T), count, std::type_index(typeid(T))); + ReusableAddOffset(const_cast(reinterpret_cast(ptr)), sizeof(T), 1, std::type_index(typeid(T))); + } + + template + void ReusableAddOffset(T* ptr, const size_t count) + { + ReusableAddOffset(const_cast(reinterpret_cast(ptr)), sizeof(T), count, std::type_index(typeid(T))); } template diff --git a/src/ZoneWriting/Zone/Stream/Impl/InMemoryZoneOutputStream.cpp b/src/ZoneWriting/Zone/Stream/Impl/InMemoryZoneOutputStream.cpp index 633c3cf0..df4411ed 100644 --- a/src/ZoneWriting/Zone/Stream/Impl/InMemoryZoneOutputStream.cpp +++ b/src/ZoneWriting/Zone/Stream/Impl/InMemoryZoneOutputStream.cpp @@ -170,7 +170,7 @@ void InMemoryZoneOutputStream::MarkFollowing(void** pPtr) *pPtr = m_block_stack.top()->m_type == XBlock::Type::BLOCK_TYPE_TEMP ? PTR_INSERT : PTR_FOLLOWING; } -bool InMemoryZoneOutputStream::ReusableShouldWrite(void** pPtr, const size_t entrySize, const size_t entryCount, std::type_index type) +bool InMemoryZoneOutputStream::ReusableShouldWrite(void** pPtr, const size_t entrySize, const std::type_index type) { assert(!m_block_stack.empty()); assert(pPtr != nullptr); @@ -178,15 +178,9 @@ bool InMemoryZoneOutputStream::ReusableShouldWrite(void** pPtr, const size_t ent if (*pPtr == nullptr) return false; - const auto inTemp = m_block_stack.top()->m_type == XBlock::Type::BLOCK_TYPE_TEMP; const auto foundEntriesForType = m_reusable_entries.find(type); if (foundEntriesForType == m_reusable_entries.end()) { - std::vector entries; - auto zoneOffset = inTemp ? InsertPointer() : GetCurrentZonePointer(); - entries.emplace_back(*pPtr, entrySize, entryCount, zoneOffset); - m_reusable_entries.emplace(std::make_pair(type, std::move(entries))); - return true; } @@ -199,9 +193,25 @@ bool InMemoryZoneOutputStream::ReusableShouldWrite(void** pPtr, const size_t ent return false; } } - - auto zoneOffset = inTemp ? InsertPointer() : GetCurrentZonePointer(); - foundEntriesForType->second.emplace_back(*pPtr, entrySize, entryCount, zoneOffset); return true; } + +void InMemoryZoneOutputStream::ReusableAddOffset(void* ptr, size_t size, size_t count, std::type_index type) +{ + assert(!m_block_stack.empty()); + + const auto inTemp = m_block_stack.top()->m_type == XBlock::Type::BLOCK_TYPE_TEMP; + auto zoneOffset = inTemp ? InsertPointer() : GetCurrentZonePointer(); + const auto foundEntriesForType = m_reusable_entries.find(type); + if (foundEntriesForType == m_reusable_entries.end()) + { + std::vector entries; + entries.emplace_back(ptr, size, count, zoneOffset); + m_reusable_entries.emplace(std::make_pair(type, std::move(entries))); + } + else + { + foundEntriesForType->second.emplace_back(ptr, size, count, zoneOffset); + } +} diff --git a/src/ZoneWriting/Zone/Stream/Impl/InMemoryZoneOutputStream.h b/src/ZoneWriting/Zone/Stream/Impl/InMemoryZoneOutputStream.h index 183ea4bb..f255591c 100644 --- a/src/ZoneWriting/Zone/Stream/Impl/InMemoryZoneOutputStream.h +++ b/src/ZoneWriting/Zone/Stream/Impl/InMemoryZoneOutputStream.h @@ -46,5 +46,6 @@ public: void IncBlockPos(size_t size) override; void WriteNullTerminated(const void* src) override; void MarkFollowing(void** pPtr) override; - bool ReusableShouldWrite(void** pPtr, size_t entrySize, size_t entryCount, std::type_index type) override; + bool ReusableShouldWrite(void** pPtr, size_t entrySize, std::type_index type) override; + void ReusableAddOffset(void* ptr, size_t size, size_t count, std::type_index type) override; };