Skip to content

Commit

Permalink
Merge pull request #151 from Laupetin/fix/realloc-iw5-clipinfo
Browse files Browse the repository at this point in the history
fix: not reallocating IW5 clipMap pInfo from temp block
  • Loading branch information
Laupetin authored Mar 30, 2024
2 parents 89d80ca + 666ea2b commit 2650669
Show file tree
Hide file tree
Showing 9 changed files with 136 additions and 59 deletions.
1 change: 1 addition & 0 deletions src/ZoneCode/Game/IW5/XAssets/clipMap_t.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ set string name;
set name name;
set block pInfo XFILE_BLOCK_TEMP;
set reusable pInfo;
set action pInfo ReallocClipInfo(ClipInfo, clipMap_t);
set count staticModelList numStaticModels;
set count nodes numNodes;
set count leafs numLeafs;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
#include "Domain/Evaluation/IEvaluation.h"
#include "Domain/FastFile/FastFileBlock.h"
#include "StructureInformation.h"
#include "Utils/ClassUtils.h"

#include <memory>

Expand All @@ -22,6 +21,7 @@ class MemberInformation
bool m_is_leaf;
std::unique_ptr<IEvaluation> m_condition;
std::unique_ptr<IEvaluation> m_alloc_alignment;
std::unique_ptr<CustomAction> m_post_load_action;
const FastFileBlock* m_fast_file_block;
const EnumMember* m_asset_ref;

Expand Down
46 changes: 37 additions & 9 deletions src/ZoneCodeGeneratorLib/Generating/RenderingContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
#include "Domain/Computations/MemberComputations.h"
#include "Domain/Computations/StructureComputations.h"

#include <algorithm>

RenderingUsedType::RenderingUsedType(const DataDefinition* type, StructureInformation* info)
: m_members_loaded(false),
m_type(type),
Expand Down Expand Up @@ -140,26 +142,52 @@ void RenderingContext::CreateUsedTypeCollections()
{
if (usedType->m_info != nullptr)
{
StructureComputations computations(usedType->m_info);
const StructureComputations computations(usedType->m_info);

if (usedType->m_info->m_definition == usedType->m_type)
m_used_structures.push_back(usedType);

if (computations.IsAsset() && usedType->m_info != m_asset)
m_referenced_assets.push_back(usedType);
if (computations.IsAsset())
{
if (usedType->m_info != m_asset)
m_referenced_assets.push_back(usedType);
else
usedType->m_is_context_asset = true;
}

if (!m_has_actions)
if (!m_has_actions && UsedTypeHasActions(usedType))
{
if ((!computations.IsAsset() || usedType->m_is_context_asset) && usedType->m_non_runtime_reference_exists
&& usedType->m_info->m_post_load_action)
{
m_has_actions = true;
}
m_has_actions = true;
}
}
}
}

bool RenderingContext::UsedTypeHasActions(const RenderingUsedType* usedType) const
{
const StructureComputations computations(usedType->m_info);

if (computations.IsAsset() && !usedType->m_is_context_asset)
return false;

if (!usedType->m_non_runtime_reference_exists && !usedType->m_is_context_asset)
return false;

if (usedType->m_info->m_post_load_action)
return true;

if (std::ranges::any_of(usedType->m_info->m_ordered_members,
[](const auto& member) -> bool
{
return member->m_post_load_action && !MemberComputations(member.get()).ShouldIgnore();
}))
{
return true;
}

return false;
}

std::unique_ptr<RenderingContext> RenderingContext::BuildContext(const IDataRepository* repository, StructureInformation* asset)
{
auto context = std::make_unique<RenderingContext>(RenderingContext(repository->GetGameName(), repository->GetAllFastFileBlocks()));
Expand Down
1 change: 1 addition & 0 deletions src/ZoneCodeGeneratorLib/Generating/RenderingContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ class RenderingContext
void ScanUsedTypeIfNeeded(const IDataRepository* repository, MemberComputations* computations, RenderingUsedType* usedType);
void MakeAsset(const IDataRepository* repository, StructureInformation* asset);
void CreateUsedTypeCollections();
bool UsedTypeHasActions(const RenderingUsedType* usedType) const;

public:
std::string m_game;
Expand Down
24 changes: 24 additions & 0 deletions src/ZoneCodeGeneratorLib/Generating/Templates/ZoneLoadTemplate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,12 @@ class ZoneLoadTemplate::Internal final : BaseTemplate
LINE("")
LINE(MakeCustomActionCall(member->m_type->m_post_load_action.get()))
}

if (member->m_post_load_action)
{
LINE("")
LINE(MakeCustomActionCall(member->m_post_load_action.get()))
}
}
else
{
Expand Down Expand Up @@ -378,6 +384,12 @@ class ZoneLoadTemplate::Internal final : BaseTemplate
LINE("")
LINE(MakeCustomActionCall(member->m_type->m_post_load_action.get()))
}

if (member->m_post_load_action)
{
LINE("")
LINE(MakeCustomActionCall(member->m_post_load_action.get()))
}
}
else if (computations.IsAfterPartialLoad())
{
Expand Down Expand Up @@ -424,6 +436,12 @@ class ZoneLoadTemplate::Internal final : BaseTemplate
LINE("")
LINE(MakeCustomActionCall(member->m_type->m_post_load_action.get()))
}

if (member->m_post_load_action)
{
LINE("")
LINE(MakeCustomActionCall(member->m_post_load_action.get()))
}
}
else if (computations.IsAfterPartialLoad())
{
Expand All @@ -446,6 +464,12 @@ class ZoneLoadTemplate::Internal final : BaseTemplate
LINE("")
LINE(MakeCustomActionCall(member->m_type->m_post_load_action.get()))
}

if (member->m_post_load_action)
{
LINE("")
LINE(MakeCustomActionCall(member->m_post_load_action.get()))
}
}
else
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ SequenceAction::SequenceAction()
void SequenceAction::ProcessMatch(CommandsParserState* state, SequenceResult<CommandsParserValue>& result) const
{
StructureInformation* type;
MemberInformation* member = nullptr;
const auto& actionNameToken = result.NextCapture(CAPTURE_ACTION_NAME);

// If a typename was specified then try to parse it
Expand All @@ -53,11 +54,7 @@ void SequenceAction::ProcessMatch(CommandsParserState* state, SequenceResult<Com
throw ParsingException(typeNameToken.GetPos(), "Unknown type");

if (!memberChain.empty())
{
type = memberChain.back()->m_type;
if (type == nullptr)
throw ParsingException(typeNameToken.GetPos(), "Member is not a data type with members.");
}
member = memberChain.back();
}
else if (state->GetInUse() != nullptr)
{
Expand All @@ -79,5 +76,12 @@ void SequenceAction::ProcessMatch(CommandsParserState* state, SequenceResult<Com
parameterTypes.push_back(dataDefinition);
}

type->m_post_load_action = std::make_unique<CustomAction>(actionNameToken.IdentifierValue(), std::move(parameterTypes));
auto action = std::make_unique<CustomAction>(actionNameToken.IdentifierValue(), std::move(parameterTypes));

if (member != nullptr)
member->m_post_load_action = std::move(action);
else if (type != nullptr)
type->m_post_load_action = std::move(action);
else
throw ParsingException(actionNameToken.GetPos(), "Unknown type");
}
17 changes: 17 additions & 0 deletions src/ZoneLoading/Game/IW5/XAssets/clipmap_t/clipmap_t_actions.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#include "clipmap_t_actions.h"

#include <cassert>
#include <cstring>

using namespace IW5;

Actions_clipMap_t::Actions_clipMap_t(Zone* zone)
: AssetLoadingActions(zone)
{
}

void Actions_clipMap_t::ReallocClipInfo(ClipInfo* clipInfo, clipMap_t* clipMap) const
{
clipMap->pInfo = static_cast<ClipInfo*>(m_zone->GetMemory()->Alloc(sizeof(ClipInfo)));
memcpy(clipMap->pInfo, clipInfo, sizeof(ClipInfo));
}
15 changes: 15 additions & 0 deletions src/ZoneLoading/Game/IW5/XAssets/clipmap_t/clipmap_t_actions.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#pragma once

#include "Game/IW5/IW5.h"
#include "Loading/AssetLoadingActions.h"

namespace IW5
{
class Actions_clipMap_t final : public AssetLoadingActions
{
public:
explicit Actions_clipMap_t(Zone* zone);

void ReallocClipInfo(ClipInfo* clipInfo, clipMap_t* clipMap) const;
};
} // namespace IW5
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,12 @@ namespace test::parsing::commands::sequence::sequence_action
std::unique_ptr<CommandsParserState> m_state;
std::unique_ptr<ILexer<CommandsParserValue>> m_lexer;

StructDefinition* m_test_struct_raw;
StructDefinition* m_test_struct_t;
StructureInformation* m_test_struct;

StructDefinition* m_test_struct2_raw;
StructureInformation* m_test_struct2;
StructDefinition* m_container_struct_t;
StructureInformation* m_container_struct;
MemberInformation* m_container_struct_child;

StructDefinition* m_arg_struct_raw;
StructureInformation* m_arg_struct;
Expand All @@ -37,10 +38,12 @@ namespace test::parsing::commands::sequence::sequence_action
private:
void RetrieveInformationPointers()
{
m_test_struct = m_repository->GetInformationFor(m_test_struct_raw);
m_test_struct = m_repository->GetInformationFor(m_test_struct_t);
REQUIRE(m_test_struct != nullptr);
m_test_struct2 = m_repository->GetInformationFor(m_test_struct2_raw);
REQUIRE(m_test_struct2 != nullptr);
m_container_struct = m_repository->GetInformationFor(m_container_struct_t);
REQUIRE(m_container_struct != nullptr);
m_container_struct_child = m_container_struct->m_ordered_members[0].get();
REQUIRE(m_container_struct_child != nullptr);
m_arg_struct = m_repository->GetInformationFor(m_arg_struct_raw);
REQUIRE(m_arg_struct != nullptr);
m_arg_struct2 = m_repository->GetInformationFor(m_arg_struct2_raw);
Expand All @@ -61,12 +64,12 @@ namespace test::parsing::commands::sequence::sequence_action
{
auto def = std::make_unique<StructDefinition>("", "test_struct_t", 8);
def->m_members.emplace_back(std::make_shared<Variable>("m_test", std::make_unique<TypeDeclaration>(BaseTypeDefinition::BOOL)));
m_test_struct_raw = def.get();
m_test_struct_t = def.get();
m_repository->Add(std::move(def));

def = std::make_unique<StructDefinition>("", "container_struct_t", 8);
def->m_members.emplace_back(std::make_shared<Variable>("m_child", std::make_unique<TypeDeclaration>(m_test_struct_raw)));
m_test_struct2_raw = def.get();
def->m_members.emplace_back(std::make_shared<Variable>("m_child", std::make_unique<TypeDeclaration>(m_test_struct_t)));
m_container_struct_t = def.get();
m_repository->Add(std::move(def));

def = std::make_unique<StructDefinition>("", "arg_t", 8);
Expand All @@ -91,10 +94,10 @@ namespace test::parsing::commands::sequence::sequence_action
CommandsSequenceTestsHelper()
: m_repository(std::make_unique<InMemoryRepository>()),
m_state(std::make_unique<CommandsParserState>(m_repository.get())),
m_test_struct_raw(nullptr),
m_test_struct_t(nullptr),
m_test_struct(nullptr),
m_test_struct2_raw(nullptr),
m_test_struct2(nullptr),
m_container_struct_t(nullptr),
m_container_struct(nullptr),
m_arg_struct_raw(nullptr),
m_arg_struct(nullptr),
m_arg_struct2_raw(nullptr),
Expand Down Expand Up @@ -339,9 +342,11 @@ namespace test::parsing::commands::sequence::sequence_action

REQUIRE(result);
REQUIRE(helper.m_consumed_token_count == 10);
REQUIRE(helper.m_test_struct->m_post_load_action);
REQUIRE(helper.m_test_struct->m_post_load_action->m_action_name == "TestMethod");
REQUIRE(helper.m_test_struct->m_post_load_action->m_parameter_types.empty());
REQUIRE(helper.m_test_struct->m_post_load_action == nullptr);

REQUIRE(helper.m_container_struct_child->m_post_load_action);
REQUIRE(helper.m_container_struct_child->m_post_load_action->m_action_name == "TestMethod");
REQUIRE(helper.m_container_struct_child->m_post_load_action->m_parameter_types.empty());
}

TEST_CASE("SequenceAction: Ensure can parse action directive with type from member and in use", "[parsing][sequence]")
Expand All @@ -358,15 +363,17 @@ namespace test::parsing::commands::sequence::sequence_action
CommandsParserValue::Character(pos, ';'),
CommandsParserValue::EndOfFile(pos),
});
helper.m_state->SetInUse(helper.m_test_struct2);
helper.m_state->SetInUse(helper.m_container_struct);

auto result = helper.PerformTest();

REQUIRE(result);
REQUIRE(helper.m_consumed_token_count == 7);
REQUIRE(helper.m_test_struct->m_post_load_action);
REQUIRE(helper.m_test_struct->m_post_load_action->m_action_name == "TestMethod");
REQUIRE(helper.m_test_struct->m_post_load_action->m_parameter_types.empty());
REQUIRE(helper.m_test_struct->m_post_load_action == nullptr);

REQUIRE(helper.m_container_struct_child->m_post_load_action);
REQUIRE(helper.m_container_struct_child->m_post_load_action->m_action_name == "TestMethod");
REQUIRE(helper.m_container_struct_child->m_post_load_action->m_parameter_types.empty());
}

TEST_CASE("SequenceAction: Ensure can use different struct even though something is used", "[parsing][sequence]")
Expand All @@ -392,30 +399,10 @@ namespace test::parsing::commands::sequence::sequence_action

REQUIRE(result);
REQUIRE(helper.m_consumed_token_count == 10);
REQUIRE(helper.m_test_struct->m_post_load_action);
REQUIRE(helper.m_test_struct->m_post_load_action->m_action_name == "TestMethod");
REQUIRE(helper.m_test_struct->m_post_load_action->m_parameter_types.empty());
}

TEST_CASE("SequenceAction: Ensure member must be type with members", "[parsing][sequence]")
{
CommandsSequenceTestsHelper helper;
const TokenPos pos;
helper.Tokens({
CommandsParserValue::Identifier(pos, new std::string("set")),
CommandsParserValue::Identifier(pos, new std::string("action")),
CommandsParserValue::Identifier(pos, new std::string("test_struct_t")),
CommandsParserValue::Character(pos, ':'),
CommandsParserValue::Character(pos, ':'),
CommandsParserValue::Identifier(pos, new std::string("m_test")),
CommandsParserValue::Identifier(pos, new std::string("TestMethod")),
CommandsParserValue::Character(pos, '('),
CommandsParserValue::Character(pos, ')'),
CommandsParserValue::Character(pos, ';'),
CommandsParserValue::EndOfFile(pos),
});

REQUIRE_THROWS_AS(helper.PerformTest(), ParsingException);
REQUIRE(helper.m_test_struct->m_post_load_action == nullptr);

REQUIRE(helper.m_container_struct_child->m_post_load_action);
REQUIRE(helper.m_container_struct_child->m_post_load_action->m_action_name == "TestMethod");
REQUIRE(helper.m_container_struct_child->m_post_load_action->m_parameter_types.empty());
}
} // namespace test::parsing::commands::sequence::sequence_action

0 comments on commit 2650669

Please sign in to comment.