2
0
mirror of https://github.com/Laupetin/OpenAssetTools.git synced 2026-02-14 19:33:02 +00:00

fix: compilation with CommonTechset

This commit is contained in:
Jan Laupetin
2026-02-04 21:05:39 +00:00
parent 2e3e4821a0
commit 9c728e2dd5
28 changed files with 15 additions and 19 deletions

View File

@@ -9,9 +9,9 @@
#include "Gdt/AbstractGdtEntryReader.h"
#include "Gdt/IGdtQueryable.h"
#include "Pool/GlobalAssetPool.h"
#include "StateMap/StateMapFromTechniqueExtractor.h"
#include "StateMap/StateMapHandler.h"
#include "Techset/CommonTechsetCache.h"
#include "Techset/StateMap/StateMapFromTechniqueExtractor.h"
#include "Techset/StateMap/StateMapHandler.h"
#include "Techset/TechniqueFileReader.h"
#include "Techset/TechniqueStateMapCache.h"
#include "Techset/TechsetCommon.h"

View File

@@ -6,9 +6,9 @@
#include "Game/IW4/Techset/TechsetConstantsIW4.h"
#include "Shader/D3D9ShaderAnalyser.h"
#include "Shader/ShaderCommon.h"
#include "StateMap/StateMapReader.h"
#include "Techset/CommonTechsetCache.h"
#include "Techset/CommonTechsetLoader.h"
#include "Techset/StateMap/StateMapReader.h"
#include "Techset/TechniqueFileReader.h"
#include "Techset/TechniqueStateMapCache.h"
#include "Techset/TechsetCommon.h"

View File

@@ -3,8 +3,8 @@
#include "Asset/IAssetCreator.h"
#include "Game/IW4/IW4.h"
#include "SearchPath/ISearchPath.h"
#include "StateMap/StateMapDefinition.h"
#include "Techset/CommonTechset.h"
#include "Techset/StateMap/StateMapDefinition.h"
#include "Utils/MemoryManager.h"
#include <memory>

View File

@@ -0,0 +1,18 @@
#include "CommonTechsetCache.h"
using namespace techset;
CommonTechset* CommonTechsetCache::GetCachedTechsetDefinition(const std::string& techsetName) const
{
const auto foundTechset = m_cache.find(techsetName);
if (foundTechset != m_cache.end())
return foundTechset->second.get();
return nullptr;
}
void CommonTechsetCache::AddCommonTechsetToCache(std::string name, std::unique_ptr<CommonTechset> definition)
{
m_cache.emplace(std::make_pair(std::move(name), std::move(definition)));
}

View File

@@ -0,0 +1,21 @@
#pragma once
#include "Asset/IZoneAssetCreationState.h"
#include "Techset/CommonTechset.h"
#include <memory>
#include <string>
#include <unordered_map>
namespace techset
{
class CommonTechsetCache final : public IZoneAssetCreationState
{
public:
[[nodiscard]] CommonTechset* GetCachedTechsetDefinition(const std::string& techsetName) const;
void AddCommonTechsetToCache(std::string name, std::unique_ptr<CommonTechset> definition);
private:
std::unordered_map<std::string, std::unique_ptr<CommonTechset>> m_cache;
};
} // namespace techset

View File

@@ -0,0 +1,50 @@
#include "StateMapExpressionMatchers.h"
#include "Parsing/Simple/Expression/SimpleExpressionScopeValue.h"
#include "Parsing/Simple/Matcher/SimpleMatcherFactory.h"
using namespace state_map;
static constexpr int CAPTURE_VALUE = SimpleExpressionMatchers::CAPTURE_OFFSET_EXPRESSION_EXT + 1;
StateMapExpressionMatchers::StateMapExpressionMatchers()
: StateMapExpressionMatchers(nullptr)
{
}
StateMapExpressionMatchers::StateMapExpressionMatchers(StateMapParserState* state)
: SimpleExpressionMatchers(false, false, false, false, true),
m_state(state)
{
}
std::unique_ptr<SimpleExpressionMatchers::matcher_t> StateMapExpressionMatchers::ParseOperandExtension(const supplier_t* labelSupplier) const
{
const SimpleMatcherFactory create(labelSupplier);
return create.Or({
create.Identifier().Capture(CAPTURE_VALUE),
create.Integer().Capture(CAPTURE_VALUE),
});
}
std::unique_ptr<ISimpleExpression> StateMapExpressionMatchers::ProcessOperandExtension(SequenceResult<SimpleParserValue>& result) const
{
assert(m_state);
const auto& valueToken = result.NextCapture(CAPTURE_VALUE);
auto value = valueToken.m_type == SimpleParserValueType::IDENTIFIER ? valueToken.IdentifierValue() : std::to_string(valueToken.IntegerValue());
if (value.rfind("mtl", 0) == 0)
{
if (m_state->m_valid_vars.find(value) == m_state->m_valid_vars.end())
throw ParsingException(valueToken.GetPos(), "Unknown variable");
return std::make_unique<SimpleExpressionScopeValue>(value);
}
if (m_state->m_valid_values.find(value) == m_state->m_valid_values.end())
throw ParsingException(valueToken.GetPos(), "Unknown value");
return std::make_unique<SimpleExpressionValue>(value);
}

View File

@@ -0,0 +1,23 @@
#pragma once
#include "Parsing/Simple/Expression/SimpleExpressionMatchers.h"
#include "Techset/StateMap/Parsing/StateMapParserState.h"
#include <memory>
namespace state_map
{
class StateMapExpressionMatchers final : public SimpleExpressionMatchers
{
public:
StateMapExpressionMatchers();
explicit StateMapExpressionMatchers(StateMapParserState* state);
protected:
std::unique_ptr<matcher_t> ParseOperandExtension(const supplier_t* labelSupplier) const override;
std::unique_ptr<ISimpleExpression> ProcessOperandExtension(SequenceResult<SimpleParserValue>& result) const override;
private:
StateMapParserState* m_state;
};
} // namespace state_map

View File

@@ -0,0 +1,251 @@
#include "StateMapParser.h"
#include "Matcher/StateMapExpressionMatchers.h"
#include "Parsing/Simple/Matcher/SimpleMatcherFactory.h"
using namespace state_map;
namespace state_map
{
class SequenceStateMapEntry final : public StateMapParser::sequence_t
{
static constexpr auto CAPTURE_ENTRY_NAME = 1;
public:
SequenceStateMapEntry()
{
const SimpleMatcherFactory create(this);
AddMatchers({
create.Identifier().Capture(CAPTURE_ENTRY_NAME),
create.Char('{'),
});
}
protected:
void ProcessMatch(StateMapParserState* state, SequenceResult<SimpleParserValue>& result) const override
{
const auto& entryNameToken = result.NextCapture(CAPTURE_ENTRY_NAME);
const auto foundEntry = state->m_valid_state_map_entry_names.find(entryNameToken.IdentifierValue());
if (foundEntry == state->m_valid_state_map_entry_names.end())
throw ParsingException(entryNameToken.GetPos(), "Unknown entry name");
state->m_in_entry = true;
state->m_current_entry_index = foundEntry->second;
}
};
class SequenceStateMapEntryClose final : public StateMapParser::sequence_t
{
static constexpr auto CAPTURE_FIRST_TOKEN = 1;
public:
SequenceStateMapEntryClose()
{
const SimpleMatcherFactory create(this);
AddMatchers({
create.Char('}').Capture(CAPTURE_FIRST_TOKEN),
});
}
protected:
void ProcessMatch(StateMapParserState* state, SequenceResult<SimpleParserValue>& result) const override
{
if (!state->m_entry_has_default)
throw ParsingException(result.NextCapture(CAPTURE_FIRST_TOKEN).GetPos(), "Entry must have a default case");
state->m_in_entry = false;
state->m_entry_has_default = false;
}
};
class SequenceCondition final : public StateMapParser::sequence_t
{
static constexpr auto TAG_DEFAULT = 1;
static constexpr auto TAG_EXPRESSION = 2;
public:
SequenceCondition()
{
AddLabeledMatchers(StateMapExpressionMatchers().Expression(this), StateMapExpressionMatchers::LABEL_EXPRESSION);
const SimpleMatcherFactory create(this);
AddMatchers({
create.Or({
create.Keyword("default").Tag(TAG_DEFAULT),
create.Label(StateMapExpressionMatchers::LABEL_EXPRESSION).Tag(TAG_EXPRESSION),
}),
create.Char(':'),
});
}
protected:
void ProcessMatch(StateMapParserState* state, SequenceResult<SimpleParserValue>& result) const override
{
assert(state->m_definition);
assert(state->m_in_entry);
if (!state->m_current_rule)
{
auto newRule = std::make_unique<StateMapRule>();
state->m_current_rule = newRule.get();
state->m_definition->m_state_map_entries[state->m_current_entry_index].m_rules.emplace_back(std::move(newRule));
}
if (result.PeekAndRemoveIfTag(TAG_EXPRESSION) == TAG_EXPRESSION)
{
auto expression = StateMapExpressionMatchers(state).ProcessExpression(result);
state->m_current_rule->m_conditions.emplace_back(std::move(expression));
}
else
{
assert(result.PeekAndRemoveIfTag(TAG_DEFAULT) == TAG_DEFAULT);
auto& entry = state->m_definition->m_state_map_entries[state->m_current_entry_index];
state->m_entry_has_default = true;
entry.m_default_index = entry.m_rules.size() - 1;
}
}
};
class SequenceValue final : public StateMapParser::sequence_t
{
static constexpr auto TAG_PASSTHROUGH = 1;
static constexpr auto TAG_VALUE_LIST = 2;
static constexpr auto CAPTURE_VALUE = 1;
static constexpr auto CAPTURE_VALUE_END = 2;
static constexpr auto LABEL_VALUE_LIST = 1;
static constexpr auto LABEL_VALUE = 2;
public:
SequenceValue()
{
const SimpleMatcherFactory create(this);
AddLabeledMatchers(create.Or({
create.Identifier(),
create.Integer(),
}),
LABEL_VALUE);
AddLabeledMatchers(
{
create.Label(LABEL_VALUE).Capture(CAPTURE_VALUE),
create.OptionalLoop(create.And({
create.Char(','),
create.Label(LABEL_VALUE).Capture(CAPTURE_VALUE),
})),
},
LABEL_VALUE_LIST);
AddMatchers({
create.Or({
create.Keyword("passthrough").Tag(TAG_PASSTHROUGH),
create.Label(LABEL_VALUE_LIST).Tag(TAG_VALUE_LIST),
}),
create.Char(';').Capture(CAPTURE_VALUE_END),
});
}
protected:
void ProcessMatch(StateMapParserState* state, SequenceResult<SimpleParserValue>& result) const override
{
assert(state->m_in_entry);
assert(state->m_current_rule);
const auto& layoutEntry = state->m_layout.m_entry_layout.m_entries[state->m_current_entry_index];
if (result.PeekAndRemoveIfTag(TAG_VALUE_LIST) == TAG_VALUE_LIST)
{
auto resultIndex = 0u;
while (result.HasNextCapture(CAPTURE_VALUE))
{
const auto& valueToken = result.NextCapture(CAPTURE_VALUE);
if (resultIndex >= layoutEntry.m_result_vars.size())
throw ParsingException(valueToken.GetPos(), "Too many results");
const auto& resultVar = layoutEntry.m_result_vars[resultIndex];
const auto varForResult = state->m_valid_vars.find(resultVar);
if (varForResult != state->m_valid_vars.end())
{
const auto& var = state->m_layout.m_var_layout.m_vars[varForResult->second];
const auto tokenValue =
valueToken.m_type == SimpleParserValueType::IDENTIFIER ? valueToken.IdentifierValue() : std::to_string(valueToken.IntegerValue());
const auto referencedValue = std::ranges::find_if(var.m_values,
[&tokenValue](const StateMapLayoutVarValue& value)
{
return value.m_name == tokenValue;
});
if (referencedValue == var.m_values.end())
throw ParsingException(valueToken.GetPos(), "Not part of the valid values for this var");
state->m_current_rule->m_value |= referencedValue->m_state_bits_mask;
}
else
throw ParsingException(valueToken.GetPos(), "Unknown var for result?");
resultIndex++;
}
if (resultIndex < layoutEntry.m_result_vars.size())
throw ParsingException(result.NextCapture(CAPTURE_VALUE_END).GetPos(), "Not enough results");
}
else
{
// A rule without values is considered passthrough therefore just don't add values
assert(result.PeekAndRemoveIfTag(TAG_PASSTHROUGH) == TAG_PASSTHROUGH);
state->m_current_rule->m_passthrough = true;
}
state->m_current_rule = nullptr;
}
};
} // namespace state_map
StateMapParser::StateMapParser(SimpleLexer* lexer, std::string stateMapName, const StateMapLayout& layout)
: AbstractParser(lexer, std::make_unique<StateMapParserState>(std::move(stateMapName), layout))
{
}
const std::vector<StateMapParser::sequence_t*>& StateMapParser::GetTestsForState()
{
static std::vector<sequence_t*> rootSequences({
new SequenceStateMapEntry(),
});
static std::vector<sequence_t*> entrySequences({
new SequenceStateMapEntryClose(),
new SequenceCondition(),
});
static std::vector<sequence_t*> ruleSequences({
new SequenceCondition(),
new SequenceValue(),
});
if (m_state->m_in_entry)
{
return m_state->m_current_rule ? ruleSequences : entrySequences;
}
return rootSequences;
}
std::unique_ptr<StateMapDefinition> StateMapParser::GetStateMapDefinition() const
{
return std::move(m_state->m_definition);
}
StateMapParserState* StateMapParser::GetState() const
{
return m_state.get();
}

View File

@@ -0,0 +1,20 @@
#pragma once
#include "Parsing/Impl/AbstractParser.h"
#include "Parsing/Simple/SimpleLexer.h"
#include "Parsing/Simple/SimpleParserValue.h"
#include "StateMapParserState.h"
namespace state_map
{
class StateMapParser final : public AbstractParser<SimpleParserValue, StateMapParserState>
{
protected:
const std::vector<sequence_t*>& GetTestsForState() override;
public:
StateMapParser(SimpleLexer* lexer, std::string stateMapName, const StateMapLayout& layout);
[[nodiscard]] std::unique_ptr<StateMapDefinition> GetStateMapDefinition() const;
[[nodiscard]] StateMapParserState* GetState() const;
};
} // namespace state_map

View File

@@ -0,0 +1,24 @@
#include "StateMapParserState.h"
using namespace state_map;
StateMapParserState::StateMapParserState(std::string stateMapName, const StateMapLayout& layout)
: m_layout(layout),
m_definition(std::make_unique<StateMapDefinition>(std::move(stateMapName), layout.m_entry_layout.m_entries.size())),
m_in_entry(false),
m_entry_has_default(false),
m_current_entry_index(0u),
m_current_rule(nullptr)
{
for (auto i = 0u; i < m_layout.m_entry_layout.m_entries.size(); i++)
m_valid_state_map_entry_names.emplace(m_layout.m_entry_layout.m_entries[i].m_name, i);
for (auto varIndex = 0u; varIndex < layout.m_var_layout.m_vars.size(); varIndex++)
{
const auto& var = layout.m_var_layout.m_vars[varIndex];
m_valid_vars.emplace(std::make_pair(var.m_name, varIndex));
for (const auto& value : var.m_values)
m_valid_values.emplace(value.m_name);
}
}

View File

@@ -0,0 +1,29 @@
#pragma once
#include "Techset/StateMap/StateMapDefinition.h"
#include "Techset/StateMap/StateMapLayout.h"
#include <memory>
#include <set>
#include <string>
#include <unordered_map>
namespace state_map
{
class StateMapParserState
{
public:
const StateMapLayout& m_layout;
std::unordered_map<std::string, size_t> m_valid_state_map_entry_names;
std::unordered_map<std::string, size_t> m_valid_vars;
std::set<std::string> m_valid_values;
std::unique_ptr<StateMapDefinition> m_definition;
bool m_in_entry;
bool m_entry_has_default;
size_t m_current_entry_index;
StateMapRule* m_current_rule;
StateMapParserState(std::string stateMapName, const StateMapLayout& layout);
};
} // namespace state_map

View File

@@ -0,0 +1,20 @@
#include "StateMapDefinition.h"
using namespace state_map;
StateMapRule::StateMapRule()
: m_value(0u),
m_passthrough(false)
{
}
StateMapEntry::StateMapEntry()
: m_default_index(0u)
{
}
StateMapDefinition::StateMapDefinition(std::string name, const size_t entryCount)
: m_name(std::move(name)),
m_state_map_entries(entryCount)
{
}

View File

@@ -0,0 +1,38 @@
#pragma once
#include "Parsing/Simple/Expression/ISimpleExpression.h"
#include <memory>
#include <string>
#include <vector>
namespace state_map
{
class StateMapRule
{
public:
std::vector<std::unique_ptr<ISimpleExpression>> m_conditions;
size_t m_value;
bool m_passthrough;
StateMapRule();
};
class StateMapEntry
{
public:
size_t m_default_index;
std::vector<std::unique_ptr<StateMapRule>> m_rules;
StateMapEntry();
};
class StateMapDefinition
{
public:
StateMapDefinition(std::string name, size_t entryCount);
std::string m_name;
std::vector<StateMapEntry> m_state_map_entries;
};
} // namespace state_map

View File

@@ -0,0 +1,68 @@
#include "StateMapFromTechniqueExtractor.h"
using namespace state_map;
std::string StateMapFromTechniqueExtractor::RetrieveStateMap()
{
return std::move(m_state_map);
}
void StateMapFromTechniqueExtractor::AcceptNextPass() {}
bool StateMapFromTechniqueExtractor::AcceptEndPass(std::string& errorMessage)
{
return true;
}
bool StateMapFromTechniqueExtractor::AcceptStateMap(const std::string& stateMapName, std::string& errorMessage)
{
m_state_map = stateMapName;
return true;
}
bool StateMapFromTechniqueExtractor::AcceptVertexShader(const std::string& vertexShaderName, std::string& errorMessage)
{
return true;
}
bool StateMapFromTechniqueExtractor::AcceptPixelShader(const std::string& pixelShaderName, std::string& errorMessage)
{
return true;
}
bool StateMapFromTechniqueExtractor::AcceptShaderConstantArgument(techset::ShaderSelector shader,
techset::ShaderArgument shaderArgument,
techset::ShaderArgumentCodeSource source,
std::string& errorMessage)
{
return true;
}
bool StateMapFromTechniqueExtractor::AcceptShaderSamplerArgument(techset::ShaderSelector shader,
techset::ShaderArgument shaderArgument,
techset::ShaderArgumentCodeSource source,
std::string& errorMessage)
{
return true;
}
bool StateMapFromTechniqueExtractor::AcceptShaderLiteralArgument(techset::ShaderSelector shader,
techset::ShaderArgument shaderArgument,
techset::ShaderArgumentLiteralSource source,
std::string& errorMessage)
{
return true;
}
bool StateMapFromTechniqueExtractor::AcceptShaderMaterialArgument(techset::ShaderSelector shader,
techset::ShaderArgument shaderArgument,
techset::ShaderArgumentMaterialSource source,
std::string& errorMessage)
{
return true;
}
bool StateMapFromTechniqueExtractor::AcceptVertexStreamRouting(const std::string& destination, const std::string& source, std::string& errorMessage)
{
return true;
}

View File

@@ -0,0 +1,40 @@
#pragma once
#include "Techset/TechniqueDefinitionAcceptor.h"
#include <string>
namespace state_map
{
class StateMapFromTechniqueExtractor final : public techset::ITechniqueDefinitionAcceptor
{
public:
std::string RetrieveStateMap();
void AcceptNextPass() override;
bool AcceptEndPass(std::string& errorMessage) override;
bool AcceptStateMap(const std::string& stateMapName, std::string& errorMessage) override;
bool AcceptVertexShader(const std::string& vertexShaderName, std::string& errorMessage) override;
bool AcceptPixelShader(const std::string& pixelShaderName, std::string& errorMessage) override;
bool AcceptShaderConstantArgument(techset::ShaderSelector shader,
techset::ShaderArgument shaderArgument,
techset::ShaderArgumentCodeSource source,
std::string& errorMessage) override;
bool AcceptShaderSamplerArgument(techset::ShaderSelector shader,
techset::ShaderArgument shaderArgument,
techset::ShaderArgumentCodeSource source,
std::string& errorMessage) override;
bool AcceptShaderLiteralArgument(techset::ShaderSelector shader,
techset::ShaderArgument shaderArgument,
techset::ShaderArgumentLiteralSource source,
std::string& errorMessage) override;
bool AcceptShaderMaterialArgument(techset::ShaderSelector shader,
techset::ShaderArgument shaderArgument,
techset::ShaderArgumentMaterialSource source,
std::string& errorMessage) override;
bool AcceptVertexStreamRouting(const std::string& destination, const std::string& source, std::string& errorMessage) override;
private:
std::string m_state_map;
};
} // namespace state_map

View File

@@ -0,0 +1,94 @@
#include "StateMapHandler.h"
#include "Utils/Logging/Log.h"
#include <algorithm>
#include <cassert>
#include <iostream>
using namespace state_map;
void StateMapVars::AddValue(std::string key, std::string value)
{
m_vars.emplace(std::make_pair(std::move(key), std::move(value)));
}
SimpleExpressionValue StateMapVars::ValueByName(const std::string& name) const
{
const auto foundValue = m_vars.find(name);
if (foundValue != m_vars.end())
return SimpleExpressionValue(foundValue->second);
return SimpleExpressionValue(0);
}
StateMapHandler::StateMapHandler(const StateMapLayout& stateMapLayout, const StateMapDefinition& stateMap)
: m_state_map_layout(stateMapLayout),
m_state_map(stateMap)
{
}
void StateMapHandler::ApplyStateMap(const uint32_t* baseStateBits, uint32_t* outStateBits) const
{
assert(baseStateBits != nullptr);
assert(outStateBits != nullptr);
const auto vars = BuildVars(baseStateBits);
for (auto i = 0u; i < m_state_map_layout.m_state_bits_count; i++)
outStateBits[i] = baseStateBits[i];
for (auto entryIndex = 0u; entryIndex < m_state_map.m_state_map_entries.size(); entryIndex++)
{
const auto& entry = m_state_map.m_state_map_entries[entryIndex];
const auto matchingRule = std::ranges::find_if(entry.m_rules,
[&vars](const std::unique_ptr<StateMapRule>& rule)
{
const auto matchingCondition =
std::ranges::find_if(rule->m_conditions,
[&vars](std::unique_ptr<ISimpleExpression>& condition)
{
return condition->EvaluateNonStatic(&vars).IsTruthy();
});
return matchingCondition != rule->m_conditions.end();
});
if (matchingRule != entry.m_rules.end())
ApplyRule(m_state_map_layout.m_entry_layout.m_entries[entryIndex], **matchingRule, outStateBits);
else
ApplyRule(m_state_map_layout.m_entry_layout.m_entries[entryIndex], *entry.m_rules[entry.m_default_index], outStateBits);
}
}
StateMapVars StateMapHandler::BuildVars(const uint32_t* baseStateBits) const
{
StateMapVars result;
for (const auto& var : m_state_map_layout.m_var_layout.m_vars)
{
const auto baseStateBitField = baseStateBits[var.m_state_bits_index];
const auto matchingValue = std::ranges::find_if(var.m_values,
[&baseStateBitField](const StateMapLayoutVarValue& value)
{
return (baseStateBitField & value.m_state_bits_mask) == value.m_state_bits_mask;
});
if (matchingValue != var.m_values.end())
result.AddValue(var.m_name, matchingValue->m_name);
else
con::error("Could not find base value for state map var \"{}\"", var.m_name);
}
return result;
}
void StateMapHandler::ApplyRule(const StateMapLayoutEntry& entry, const StateMapRule& rule, uint32_t* outStateBits)
{
if (rule.m_passthrough)
return;
outStateBits[entry.m_state_bits_index] &= ~entry.m_state_bits_mask;
outStateBits[entry.m_state_bits_index] |= rule.m_value;
}

View File

@@ -0,0 +1,35 @@
#pragma once
#include "Techset/StateMap/StateMapDefinition.h"
#include "Techset/StateMap/StateMapLayout.h"
#include <cstdint>
#include <unordered_map>
namespace state_map
{
class StateMapVars final : public ISimpleExpressionScopeValues
{
public:
void AddValue(std::string key, std::string value);
[[nodiscard]] SimpleExpressionValue ValueByName(const std::string& name) const override;
private:
std::unordered_map<std::string, std::string> m_vars;
};
class StateMapHandler
{
public:
StateMapHandler(const StateMapLayout& stateMapLayout, const StateMapDefinition& stateMap);
void ApplyStateMap(const uint32_t* baseStateBits, uint32_t* outStateBits) const;
private:
StateMapVars BuildVars(const uint32_t* baseStateBits) const;
static void ApplyRule(const StateMapLayoutEntry& entry, const StateMapRule& rule, uint32_t* outStateBits);
const StateMapLayout& m_state_map_layout;
const StateMapDefinition& m_state_map;
};
} // namespace state_map

View File

@@ -0,0 +1,72 @@
#include "StateMapReader.h"
#include "Parsing/Impl/CommentRemovingStreamProxy.h"
#include "Parsing/Impl/ParserSingleInputStream.h"
#include "Parsing/Matcher/StateMapExpressionMatchers.h"
#include "Parsing/StateMapParser.h"
#include "Utils/Logging/Log.h"
#include <iostream>
using namespace state_map;
StateMapReader::StateMapReader(std::istream& stream, std::string fileName, std::string stateMapName, const StateMapLayout& layout)
: m_state_map_name(std::move(stateMapName)),
m_file_name(std::move(fileName)),
m_state_map_layout(layout)
{
m_base_stream = std::make_unique<ParserSingleInputStream>(stream, m_file_name);
m_comment_proxy = std::make_unique<CommentRemovingStreamProxy>(m_base_stream.get());
}
bool StateMapReader::IsValidEndState(const StateMapParserState* state) const
{
if (state->m_current_rule)
{
con::error("In \"{}\": Unclosed rule at end of file!", m_file_name);
return false;
}
if (state->m_in_entry)
{
con::error("In \"{}\": Unclosed entry at end of file!", m_file_name);
return false;
}
for (auto i = 0u; i < state->m_layout.m_entry_layout.m_entries.size(); i++)
{
if (state->m_definition->m_state_map_entries[i].m_rules.empty())
{
con::error("In \"{}\": State map must define a rule for \"{}\"!", m_file_name, state->m_layout.m_entry_layout.m_entries[i].m_name);
return false;
}
}
return true;
}
std::unique_ptr<StateMapDefinition> StateMapReader::ReadStateMapDefinition() const
{
SimpleLexer::Config lexerConfig;
lexerConfig.m_emit_new_line_tokens = false;
lexerConfig.m_read_strings = false;
lexerConfig.m_read_integer_numbers = true;
lexerConfig.m_read_floating_point_numbers = false;
StateMapExpressionMatchers().ApplyTokensToLexerConfig(lexerConfig);
const auto lexer = std::make_unique<SimpleLexer>(m_comment_proxy.get(), std::move(lexerConfig));
const auto parser = std::make_unique<StateMapParser>(lexer.get(), m_state_map_name, m_state_map_layout);
const auto success = parser->Parse();
if (!success)
{
con::error("Parsing state map file \"{}\" failed!", m_file_name);
return {};
}
const auto* parserEndState = parser->GetState();
if (!IsValidEndState(parserEndState))
return nullptr;
return parser->GetStateMapDefinition();
}

View File

@@ -0,0 +1,28 @@
#pragma once
#include "Parsing/IParserLineStream.h"
#include "Parsing/StateMapParserState.h"
#include "StateMapDefinition.h"
#include "Techset/StateMap/StateMapLayout.h"
#include "Utils/ClassUtils.h"
#include <memory>
#include <string>
namespace state_map
{
class StateMapReader
{
std::string m_state_map_name;
std::string m_file_name;
const StateMapLayout& m_state_map_layout;
std::unique_ptr<IParserLineStream> m_base_stream;
std::unique_ptr<IParserLineStream> m_comment_proxy;
public:
StateMapReader(std::istream& stream, std::string fileName, std::string stateMapName, const StateMapLayout& layout);
_NODISCARD bool IsValidEndState(const StateMapParserState* state) const;
_NODISCARD std::unique_ptr<StateMapDefinition> ReadStateMapDefinition() const;
};
} // namespace state_map

View File

@@ -0,0 +1,116 @@
#include "TechniqueDefinitionAcceptor.h"
using namespace techset;
ShaderArgument::ShaderArgument()
: m_argument_index_specified(false),
m_argument_index(0u)
{
}
ShaderArgument::ShaderArgument(std::string argumentName)
: m_argument_name(std::move(argumentName)),
m_argument_index_specified(false),
m_argument_index(0u)
{
}
ShaderArgument::ShaderArgument(std::string argumentName, const unsigned argumentIndex)
: m_argument_name(std::move(argumentName)),
m_argument_index_specified(true),
m_argument_index(argumentIndex)
{
}
ShaderArgumentCodeSource::ShaderArgumentCodeSource()
: m_index_accessor_specified(false),
m_index_accessor(0u)
{
}
ShaderArgumentCodeSource::ShaderArgumentCodeSource(std::vector<std::string> accessors)
: m_accessors(std::move(accessors)),
m_index_accessor_specified(false),
m_index_accessor(0u)
{
}
ShaderArgumentCodeSource::ShaderArgumentCodeSource(std::vector<std::string> accessors, const unsigned indexAccessor)
: m_accessors(std::move(accessors)),
m_index_accessor_specified(true),
m_index_accessor(indexAccessor)
{
}
ShaderArgumentLiteralSource::ShaderArgumentLiteralSource()
: m_value{}
{
}
ShaderArgumentLiteralSource::ShaderArgumentLiteralSource(const float v0, const float v1, const float v2, const float v3)
: m_value{v0, v1, v2, v3}
{
}
ShaderArgumentLiteralSource::ShaderArgumentLiteralSource(float value[4])
: m_value{value[0], value[1], value[2], value[3]}
{
}
namespace techset
{
bool operator<(const ShaderArgumentLiteralSource& lhs, const ShaderArgumentLiteralSource& rhs)
{
if (lhs.m_value[0] < rhs.m_value[0])
return true;
if (lhs.m_value[0] > rhs.m_value[0])
return false;
if (lhs.m_value[1] < rhs.m_value[1])
return true;
if (lhs.m_value[1] > rhs.m_value[1])
return false;
if (lhs.m_value[2] < rhs.m_value[2])
return true;
if (lhs.m_value[2] > rhs.m_value[2])
return false;
if (lhs.m_value[3] < rhs.m_value[3])
return true;
if (lhs.m_value[3] > rhs.m_value[3])
return false;
return false;
}
bool operator<=(const ShaderArgumentLiteralSource& lhs, const ShaderArgumentLiteralSource& rhs)
{
return !(rhs < lhs);
}
bool operator>(const ShaderArgumentLiteralSource& lhs, const ShaderArgumentLiteralSource& rhs)
{
return rhs < lhs;
}
bool operator>=(const ShaderArgumentLiteralSource& lhs, const ShaderArgumentLiteralSource& rhs)
{
return !(lhs < rhs);
}
} // namespace techset
ShaderArgumentMaterialSource::ShaderArgumentMaterialSource()
: m_is_hash(false),
m_hash(0u)
{
}
ShaderArgumentMaterialSource::ShaderArgumentMaterialSource(const unsigned hash)
: m_is_hash(true),
m_hash(hash)
{
}
ShaderArgumentMaterialSource::ShaderArgumentMaterialSource(std::string name)
: m_is_hash(false),
m_hash(0u),
m_name(std::move(name))
{
}

View File

@@ -0,0 +1,100 @@
#pragma once
#include <string>
#include <vector>
namespace techset
{
enum class ShaderSelector
{
VERTEX_SHADER,
PIXEL_SHADER
};
class ShaderArgument
{
public:
std::string m_argument_name;
bool m_argument_index_specified;
unsigned m_argument_index;
ShaderArgument();
explicit ShaderArgument(std::string argumentName);
ShaderArgument(std::string argumentName, unsigned argumentIndex);
};
class ShaderArgumentCodeSource
{
public:
std::vector<std::string> m_accessors;
bool m_index_accessor_specified;
unsigned m_index_accessor;
ShaderArgumentCodeSource();
explicit ShaderArgumentCodeSource(std::vector<std::string> accessors);
ShaderArgumentCodeSource(std::vector<std::string> accessors, unsigned indexAccessor);
};
class ShaderArgumentLiteralSource
{
public:
float m_value[4];
ShaderArgumentLiteralSource();
ShaderArgumentLiteralSource(float v0, float v1, float v2, float v3);
explicit ShaderArgumentLiteralSource(float value[4]);
friend bool operator<(const ShaderArgumentLiteralSource& lhs, const ShaderArgumentLiteralSource& rhs);
friend bool operator<=(const ShaderArgumentLiteralSource& lhs, const ShaderArgumentLiteralSource& rhs);
friend bool operator>(const ShaderArgumentLiteralSource& lhs, const ShaderArgumentLiteralSource& rhs);
friend bool operator>=(const ShaderArgumentLiteralSource& lhs, const ShaderArgumentLiteralSource& rhs);
};
class ShaderArgumentMaterialSource
{
public:
ShaderArgumentMaterialSource();
explicit ShaderArgumentMaterialSource(unsigned hash);
explicit ShaderArgumentMaterialSource(std::string name);
bool m_is_hash;
unsigned m_hash;
std::string m_name;
};
class ITechniqueDefinitionAcceptor
{
protected:
ITechniqueDefinitionAcceptor() = default;
public:
virtual ~ITechniqueDefinitionAcceptor() = default;
ITechniqueDefinitionAcceptor(const ITechniqueDefinitionAcceptor& other) = default;
ITechniqueDefinitionAcceptor(ITechniqueDefinitionAcceptor&& other) noexcept = default;
ITechniqueDefinitionAcceptor& operator=(const ITechniqueDefinitionAcceptor& other) = default;
ITechniqueDefinitionAcceptor& operator=(ITechniqueDefinitionAcceptor&& other) noexcept = default;
virtual void AcceptNextPass() = 0;
virtual bool AcceptEndPass(std::string& errorMessage) = 0;
virtual bool AcceptStateMap(const std::string& stateMapName, std::string& errorMessage) = 0;
virtual bool AcceptVertexShader(const std::string& vertexShaderName, std::string& errorMessage) = 0;
virtual bool AcceptPixelShader(const std::string& pixelShaderName, std::string& errorMessage) = 0;
virtual bool
AcceptShaderConstantArgument(ShaderSelector shader, ShaderArgument shaderArgument, ShaderArgumentCodeSource source, std::string& errorMessage) = 0;
virtual bool
AcceptShaderSamplerArgument(ShaderSelector shader, ShaderArgument shaderArgument, ShaderArgumentCodeSource source, std::string& errorMessage) = 0;
virtual bool AcceptShaderLiteralArgument(ShaderSelector shader,
ShaderArgument shaderArgument,
ShaderArgumentLiteralSource source,
std::string& errorMessage) = 0;
virtual bool AcceptShaderMaterialArgument(ShaderSelector shader,
ShaderArgument shaderArgument,
ShaderArgumentMaterialSource source,
std::string& errorMessage) = 0;
virtual bool AcceptVertexStreamRouting(const std::string& destination, const std::string& source, std::string& errorMessage) = 0;
};
} // namespace techset

View File

@@ -0,0 +1,39 @@
#include "TechniqueFileReader.h"
#include "Parsing/Impl/CommentRemovingStreamProxy.h"
#include "Parsing/Impl/ParserSingleInputStream.h"
#include "Parsing/Simple/SimpleLexer.h"
#include "Techset/Parsing/TechniqueFileParser.h"
#include "Utils/Logging/Log.h"
#include <iostream>
using namespace techset;
TechniqueFileReader::TechniqueFileReader(std::istream& stream, std::string fileName, ITechniqueDefinitionAcceptor* acceptor)
: m_file_name(std::move(fileName)),
m_acceptor(acceptor)
{
m_base_stream = std::make_unique<ParserSingleInputStream>(stream, m_file_name);
m_comment_proxy = std::make_unique<CommentRemovingStreamProxy>(m_base_stream.get());
}
bool TechniqueFileReader::ReadTechniqueDefinition() const
{
SimpleLexer::Config lexerConfig;
lexerConfig.m_emit_new_line_tokens = false;
lexerConfig.m_read_strings = true;
lexerConfig.m_string_escape_sequences = false;
lexerConfig.m_read_integer_numbers = true;
lexerConfig.m_read_floating_point_numbers = true;
const auto lexer = std::make_unique<SimpleLexer>(m_comment_proxy.get(), std::move(lexerConfig));
const auto parser = std::make_unique<TechniqueParser>(lexer.get(), m_acceptor);
const auto success = parser->Parse();
if (success)
return true;
con::error("Parsing technique file \"{}\" failed!", m_file_name);
return false;
}

View File

@@ -0,0 +1,24 @@
#pragma once
#include "Parsing/IParserLineStream.h"
#include "TechniqueDefinitionAcceptor.h"
#include <memory>
#include <string>
namespace techset
{
class TechniqueFileReader
{
public:
TechniqueFileReader(std::istream& stream, std::string fileName, ITechniqueDefinitionAcceptor* acceptor);
[[nodiscard]] bool ReadTechniqueDefinition() const;
private:
std::string m_file_name;
ITechniqueDefinitionAcceptor* m_acceptor;
std::unique_ptr<IParserLineStream> m_base_stream;
std::unique_ptr<IParserLineStream> m_comment_proxy;
};
} // namespace techset

View File

@@ -0,0 +1,33 @@
#include "TechniqueStateMapCache.h"
using namespace techset;
const state_map::StateMapDefinition* TechniqueStateMapCache::GetCachedStateMap(const std::string& name) const
{
const auto foundStateMap = m_state_map_cache.find(name);
if (foundStateMap != m_state_map_cache.end())
return foundStateMap->second.get();
return nullptr;
}
void TechniqueStateMapCache::AddStateMapToCache(std::unique_ptr<state_map::StateMapDefinition> stateMap)
{
m_state_map_cache.emplace(std::make_pair(stateMap->m_name, std::move(stateMap)));
}
const state_map::StateMapDefinition* TechniqueStateMapCache::GetStateMapForTechnique(const std::string& techniqueName) const
{
const auto foundTechnique = m_state_map_per_technique.find(techniqueName);
if (foundTechnique != m_state_map_per_technique.end())
return foundTechnique->second;
return nullptr;
}
void TechniqueStateMapCache::SetTechniqueUsesStateMap(std::string techniqueName, const state_map::StateMapDefinition* stateMap)
{
m_state_map_per_technique.emplace(std::make_pair(std::move(techniqueName), stateMap));
}

View File

@@ -0,0 +1,26 @@
#pragma once
#include "Asset/IZoneAssetCreationState.h"
#include "StateMap/StateMapDefinition.h"
#include "Utils/ClassUtils.h"
#include <memory>
#include <string>
#include <unordered_map>
namespace techset
{
class TechniqueStateMapCache final : public IZoneAssetCreationState
{
public:
_NODISCARD const state_map::StateMapDefinition* GetCachedStateMap(const std::string& name) const;
void AddStateMapToCache(std::unique_ptr<state_map::StateMapDefinition> stateMap);
_NODISCARD const state_map::StateMapDefinition* GetStateMapForTechnique(const std::string& techniqueName) const;
void SetTechniqueUsesStateMap(std::string techniqueName, const state_map::StateMapDefinition* stateMap);
private:
std::unordered_map<std::string, const state_map::StateMapDefinition*> m_state_map_per_technique;
std::unordered_map<std::string, std::unique_ptr<state_map::StateMapDefinition>> m_state_map_cache;
};
} // namespace techset