mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-04-19 15:52:53 +00:00
Apply statemaps to materials
This commit is contained in:
parent
c5cfdfde89
commit
db60287a7b
@ -580,7 +580,7 @@ namespace IW4
|
|||||||
|
|
||||||
inline state_map::StateMapLayoutEntries stateMapEntryLayout({
|
inline state_map::StateMapLayoutEntries stateMapEntryLayout({
|
||||||
{
|
{
|
||||||
"alphaTest", 0, GFXS0_ATEST_MASK, {
|
"alphaTest", 0, GFXS0_ATEST_MASK | GFXS0_ATEST_DISABLE, {
|
||||||
"mtlAlphaTest"
|
"mtlAlphaTest"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -604,7 +604,7 @@ namespace IW4
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"depthTest", 1, GFXS1_DEPTHTEST_MASK, {
|
"depthTest", 1, GFXS1_DEPTHTEST_MASK | GFXS1_DEPTHTEST_DISABLE, {
|
||||||
"mtlDepthTest"
|
"mtlDepthTest"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -12,8 +12,12 @@
|
|||||||
#include "Game/IW4/IW4.h"
|
#include "Game/IW4/IW4.h"
|
||||||
#include "Game/IW4/MaterialConstantsIW4.h"
|
#include "Game/IW4/MaterialConstantsIW4.h"
|
||||||
#include "Game/IW4/ObjConstantsIW4.h"
|
#include "Game/IW4/ObjConstantsIW4.h"
|
||||||
|
#include "Game/IW4/TechsetConstantsIW4.h"
|
||||||
#include "Math/Vector.h"
|
#include "Math/Vector.h"
|
||||||
#include "Pool/GlobalAssetPool.h"
|
#include "Pool/GlobalAssetPool.h"
|
||||||
|
#include "StateMap/StateMapFromTechniqueExtractor.h"
|
||||||
|
#include "StateMap/StateMapHandler.h"
|
||||||
|
#include "Techset/TechniqueFileReader.h"
|
||||||
|
|
||||||
using namespace IW4;
|
using namespace IW4;
|
||||||
|
|
||||||
@ -26,10 +30,12 @@ namespace IW4
|
|||||||
class MaterialGdtLoader : AbstractGdtEntryReader
|
class MaterialGdtLoader : AbstractGdtEntryReader
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MaterialGdtLoader(const GdtEntry& entry, MemoryManager* memory, IAssetLoadingManager* manager)
|
MaterialGdtLoader(const GdtEntry& entry, MemoryManager* memory, ISearchPath* searchPath, IAssetLoadingManager* manager)
|
||||||
: AbstractGdtEntryReader(entry),
|
: AbstractGdtEntryReader(entry),
|
||||||
m_memory(memory),
|
m_memory(memory),
|
||||||
|
m_search_path(searchPath),
|
||||||
m_manager(manager),
|
m_manager(manager),
|
||||||
|
m_state_map_cache(manager->GetAssetLoadingContext()->GetZoneAssetLoaderState<techset::TechniqueStateMapCache>()),
|
||||||
m_material(nullptr),
|
m_material(nullptr),
|
||||||
m_base_state_bits{}
|
m_base_state_bits{}
|
||||||
{
|
{
|
||||||
@ -167,6 +173,9 @@ namespace IW4
|
|||||||
|
|
||||||
void mtl_effect_template()
|
void mtl_effect_template()
|
||||||
{
|
{
|
||||||
|
// TODO
|
||||||
|
throw SkipMaterialException();
|
||||||
|
|
||||||
commonsetup_template();
|
commonsetup_template();
|
||||||
unitlitcommon_template();
|
unitlitcommon_template();
|
||||||
}
|
}
|
||||||
@ -847,6 +856,58 @@ namespace IW4
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GfxStateBits GetStateBitsForTechnique(const std::string& techniqueName)
|
||||||
|
{
|
||||||
|
const auto* stateMap = GetStateMapForTechnique(techniqueName);
|
||||||
|
if (!stateMap)
|
||||||
|
return m_base_state_bits;
|
||||||
|
|
||||||
|
const auto preCalculatedStateBits = m_state_bits_per_state_map.find(stateMap);
|
||||||
|
if (preCalculatedStateBits != m_state_bits_per_state_map.end())
|
||||||
|
return preCalculatedStateBits->second;
|
||||||
|
|
||||||
|
const auto stateBits = CalculateStateBitsWithStateMap(stateMap);
|
||||||
|
m_state_bits_per_state_map.emplace(stateMap, stateBits);
|
||||||
|
|
||||||
|
return stateBits;
|
||||||
|
}
|
||||||
|
|
||||||
|
_NODISCARD const state_map::StateMapDefinition* GetStateMapForTechnique(const std::string& techniqueName) const
|
||||||
|
{
|
||||||
|
const auto* preloadedStateMap = m_state_map_cache->GetStateMapForTechnique(techniqueName);
|
||||||
|
if (preloadedStateMap)
|
||||||
|
return preloadedStateMap;
|
||||||
|
|
||||||
|
const auto techniqueFileName = AssetLoaderTechniqueSet::GetTechniqueFileName(techniqueName);
|
||||||
|
const auto file = m_search_path->Open(techniqueFileName);
|
||||||
|
if (!file.IsOpen())
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
state_map::StateMapFromTechniqueExtractor extractor;
|
||||||
|
const techset::TechniqueFileReader reader(*file.m_stream, techniqueFileName, &extractor);
|
||||||
|
if (!reader.ReadTechniqueDefinition())
|
||||||
|
{
|
||||||
|
m_state_map_cache->SetTechniqueUsesStateMap(techniqueName, nullptr);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto stateMapName = extractor.RetrieveStateMap();
|
||||||
|
const auto* loadedStateMap = AssetLoaderTechniqueSet::LoadStateMapDefinition(stateMapName, m_search_path, m_state_map_cache);
|
||||||
|
m_state_map_cache->SetTechniqueUsesStateMap(techniqueName, loadedStateMap);
|
||||||
|
|
||||||
|
return loadedStateMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
GfxStateBits CalculateStateBitsWithStateMap(const state_map::StateMapDefinition* stateMap) const
|
||||||
|
{
|
||||||
|
const state_map::StateMapHandler stateMapHandler(stateMapLayout, *stateMap);
|
||||||
|
|
||||||
|
GfxStateBits outBits{};
|
||||||
|
stateMapHandler.ApplyStateMap(m_base_state_bits.loadBits, outBits.loadBits);
|
||||||
|
|
||||||
|
return outBits;
|
||||||
|
}
|
||||||
|
|
||||||
void SetTechniqueSetCameraRegion(const techset::TechsetDefinition* techsetDefinition) const
|
void SetTechniqueSetCameraRegion(const techset::TechsetDefinition* techsetDefinition) const
|
||||||
{
|
{
|
||||||
std::string tempName;
|
std::string tempName;
|
||||||
@ -867,12 +928,6 @@ namespace IW4
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GfxStateBits GetStateBitsForTechnique(const std::string& techniqueName)
|
|
||||||
{
|
|
||||||
// TODO: Use technique statemap to evaluate actual statebits
|
|
||||||
return m_base_state_bits;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AddMapTexture(const std::string& typeName, const TileMode_e tileMode, GdtFilter_e filterMode, const TextureSemantic semantic, const std::string& textureName)
|
void AddMapTexture(const std::string& typeName, const TileMode_e tileMode, GdtFilter_e filterMode, const TextureSemantic semantic, const std::string& textureName)
|
||||||
{
|
{
|
||||||
MaterialTextureDef textureDef{};
|
MaterialTextureDef textureDef{};
|
||||||
@ -1263,7 +1318,10 @@ namespace IW4
|
|||||||
}
|
}
|
||||||
|
|
||||||
MemoryManager* m_memory;
|
MemoryManager* m_memory;
|
||||||
|
ISearchPath* m_search_path;
|
||||||
IAssetLoadingManager* m_manager;
|
IAssetLoadingManager* m_manager;
|
||||||
|
techset::TechniqueStateMapCache* m_state_map_cache;
|
||||||
|
std::unordered_map<const state_map::StateMapDefinition*, GfxStateBits> m_state_bits_per_state_map;
|
||||||
std::vector<XAssetInfoGeneric*> m_dependencies;
|
std::vector<XAssetInfoGeneric*> m_dependencies;
|
||||||
|
|
||||||
Material* m_material;
|
Material* m_material;
|
||||||
@ -1293,7 +1351,7 @@ bool AssetLoaderMaterial::LoadFromGdt(const std::string& assetName, IGdtQueryabl
|
|||||||
if (!entry)
|
if (!entry)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
MaterialGdtLoader loader(*entry, memory, manager);
|
MaterialGdtLoader loader(*entry, memory, manager->GetAssetLoadingContext()->m_raw_search_path, manager);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -1007,13 +1007,6 @@ namespace IW4
|
|||||||
ShaderInfoFromFileSystemCacheState* m_shader_info_cache;
|
ShaderInfoFromFileSystemCacheState* m_shader_info_cache;
|
||||||
techset::TechniqueStateMapCache* m_state_map_cache;
|
techset::TechniqueStateMapCache* m_state_map_cache;
|
||||||
|
|
||||||
static std::string GetTechniqueFileName(const std::string& techniqueName)
|
|
||||||
{
|
|
||||||
std::ostringstream ss;
|
|
||||||
ss << "techniques/" << techniqueName << ".tech";
|
|
||||||
return ss.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void UpdateTechniqueFlags(MaterialTechnique& technique)
|
static void UpdateTechniqueFlags(MaterialTechnique& technique)
|
||||||
{
|
{
|
||||||
// This is stupid but that's what the game does for zprepass for sure
|
// This is stupid but that's what the game does for zprepass for sure
|
||||||
@ -1200,7 +1193,7 @@ namespace IW4
|
|||||||
|
|
||||||
MaterialTechnique* LoadTechniqueFromRaw(const std::string& techniqueName, std::vector<XAssetInfoGeneric*>& dependencies) const
|
MaterialTechnique* LoadTechniqueFromRaw(const std::string& techniqueName, std::vector<XAssetInfoGeneric*>& dependencies) const
|
||||||
{
|
{
|
||||||
const auto techniqueFileName = GetTechniqueFileName(techniqueName);
|
const auto techniqueFileName = AssetLoaderTechniqueSet::GetTechniqueFileName(techniqueName);
|
||||||
const auto file = m_search_path->Open(techniqueFileName);
|
const auto file = m_search_path->Open(techniqueFileName);
|
||||||
if (!file.IsOpen())
|
if (!file.IsOpen())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@ -1255,6 +1248,13 @@ std::string AssetLoaderTechniqueSet::GetTechsetFileName(const std::string& techs
|
|||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string AssetLoaderTechniqueSet::GetTechniqueFileName(const std::string& techniqueName)
|
||||||
|
{
|
||||||
|
std::ostringstream ss;
|
||||||
|
ss << "techniques/" << techniqueName << ".tech";
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
std::string AssetLoaderTechniqueSet::GetStateMapFileName(const std::string& stateMapName)
|
std::string AssetLoaderTechniqueSet::GetStateMapFileName(const std::string& stateMapName)
|
||||||
{
|
{
|
||||||
std::ostringstream ss;
|
std::ostringstream ss;
|
||||||
|
@ -12,12 +12,14 @@ namespace IW4
|
|||||||
{
|
{
|
||||||
class AssetLoaderTechniqueSet final : public BasicAssetLoader<ASSET_TYPE_TECHNIQUE_SET, MaterialTechniqueSet>
|
class AssetLoaderTechniqueSet final : public BasicAssetLoader<ASSET_TYPE_TECHNIQUE_SET, MaterialTechniqueSet>
|
||||||
{
|
{
|
||||||
static std::string GetTechsetFileName(const std::string& techsetAssetName);
|
|
||||||
static std::string GetStateMapFileName(const std::string& stateMapName);
|
|
||||||
static bool CreateTechsetFromDefinition(const std::string& assetName, const techset::TechsetDefinition& definition, ISearchPath* searchPath, MemoryManager* memory,
|
static bool CreateTechsetFromDefinition(const std::string& assetName, const techset::TechsetDefinition& definition, ISearchPath* searchPath, MemoryManager* memory,
|
||||||
IAssetLoadingManager* manager);
|
IAssetLoadingManager* manager);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
static std::string GetTechsetFileName(const std::string& techsetAssetName);
|
||||||
|
static std::string GetTechniqueFileName(const std::string& techniqueName);
|
||||||
|
static std::string GetStateMapFileName(const std::string& stateMapName);
|
||||||
|
|
||||||
static techset::TechsetDefinition* LoadTechsetDefinition(const std::string& assetName, ISearchPath* searchPath, techset::TechsetDefinitionCache* definitionCache);
|
static techset::TechsetDefinition* LoadTechsetDefinition(const std::string& assetName, ISearchPath* searchPath, techset::TechsetDefinitionCache* definitionCache);
|
||||||
static const state_map::StateMapDefinition* LoadStateMapDefinition(const std::string& stateMapName, ISearchPath* searchPath, techset::TechniqueStateMapCache* stateMapCache);
|
static const state_map::StateMapDefinition* LoadStateMapDefinition(const std::string& stateMapName, ISearchPath* searchPath, techset::TechniqueStateMapCache* stateMapCache);
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ SimpleExpressionValue CommonExpressionBaseFunctionCall::EvaluateStatic() const
|
|||||||
return SimpleExpressionValue(0);
|
return SimpleExpressionValue(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
SimpleExpressionValue CommonExpressionBaseFunctionCall::EvaluateNonStatic(ISimpleExpressionScopeValues* scopeValues) const
|
SimpleExpressionValue CommonExpressionBaseFunctionCall::EvaluateNonStatic(const ISimpleExpressionScopeValues* scopeValues) const
|
||||||
{
|
{
|
||||||
return SimpleExpressionValue(0);
|
return SimpleExpressionValue(0);
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,6 @@ namespace menu
|
|||||||
_NODISCARD bool Equals(const ISimpleExpression* other) const override;
|
_NODISCARD bool Equals(const ISimpleExpression* other) const override;
|
||||||
_NODISCARD bool IsStatic() const override;
|
_NODISCARD bool IsStatic() const override;
|
||||||
_NODISCARD SimpleExpressionValue EvaluateStatic() const override;
|
_NODISCARD SimpleExpressionValue EvaluateStatic() const override;
|
||||||
_NODISCARD SimpleExpressionValue EvaluateNonStatic(ISimpleExpressionScopeValues* scopeValues) const override;
|
_NODISCARD SimpleExpressionValue EvaluateNonStatic(const ISimpleExpressionScopeValues* scopeValues) const override;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@ SimpleExpressionValue CommonExpressionCustomFunctionCall::EvaluateStatic() const
|
|||||||
return SimpleExpressionValue(0);
|
return SimpleExpressionValue(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
SimpleExpressionValue CommonExpressionCustomFunctionCall::EvaluateNonStatic(ISimpleExpressionScopeValues* scopeValues) const
|
SimpleExpressionValue CommonExpressionCustomFunctionCall::EvaluateNonStatic(const ISimpleExpressionScopeValues* scopeValues) const
|
||||||
{
|
{
|
||||||
return SimpleExpressionValue(0);
|
return SimpleExpressionValue(0);
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,6 @@ namespace menu
|
|||||||
_NODISCARD bool Equals(const ISimpleExpression* other) const override;
|
_NODISCARD bool Equals(const ISimpleExpression* other) const override;
|
||||||
_NODISCARD bool IsStatic() const override;
|
_NODISCARD bool IsStatic() const override;
|
||||||
_NODISCARD SimpleExpressionValue EvaluateStatic() const override;
|
_NODISCARD SimpleExpressionValue EvaluateStatic() const override;
|
||||||
_NODISCARD SimpleExpressionValue EvaluateNonStatic(ISimpleExpressionScopeValues* scopeValues) const override;
|
_NODISCARD SimpleExpressionValue EvaluateNonStatic(const ISimpleExpressionScopeValues* scopeValues) const override;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -5,10 +5,16 @@
|
|||||||
|
|
||||||
using namespace state_map;
|
using namespace state_map;
|
||||||
|
|
||||||
static constexpr int CAPTURE_IDENTIFIER = SimpleExpressionMatchers::CAPTURE_OFFSET_EXPRESSION_EXT + 1;
|
static constexpr int CAPTURE_VALUE = SimpleExpressionMatchers::CAPTURE_OFFSET_EXPRESSION_EXT + 1;
|
||||||
|
|
||||||
StateMapExpressionMatchers::StateMapExpressionMatchers()
|
StateMapExpressionMatchers::StateMapExpressionMatchers()
|
||||||
: SimpleExpressionMatchers(false, false, false, false, true)
|
: StateMapExpressionMatchers(nullptr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
StateMapExpressionMatchers::StateMapExpressionMatchers(StateMapParserState* state)
|
||||||
|
: SimpleExpressionMatchers(false, false, false, false, true),
|
||||||
|
m_state(state)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -17,17 +23,28 @@ std::unique_ptr<SimpleExpressionMatchers::matcher_t> StateMapExpressionMatchers:
|
|||||||
const SimpleMatcherFactory create(labelSupplier);
|
const SimpleMatcherFactory create(labelSupplier);
|
||||||
|
|
||||||
return create.Or({
|
return create.Or({
|
||||||
create.Identifier().Capture(CAPTURE_IDENTIFIER)
|
create.Identifier().Capture(CAPTURE_VALUE),
|
||||||
|
create.Integer().Capture(CAPTURE_VALUE),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<ISimpleExpression> StateMapExpressionMatchers::ProcessOperandExtension(SequenceResult<SimpleParserValue>& result) const
|
std::unique_ptr<ISimpleExpression> StateMapExpressionMatchers::ProcessOperandExtension(SequenceResult<SimpleParserValue>& result) const
|
||||||
{
|
{
|
||||||
const auto& identifierToken = result.NextCapture(CAPTURE_IDENTIFIER);
|
assert(m_state);
|
||||||
auto identifierValue = identifierToken.IdentifierValue();
|
|
||||||
|
|
||||||
if (identifierValue.rfind("mtl", 0) == 0)
|
const auto& valueToken = result.NextCapture(CAPTURE_VALUE);
|
||||||
return std::make_unique<SimpleExpressionScopeValue>(identifierValue);
|
auto value = valueToken.m_type == SimpleParserValueType::IDENTIFIER ? valueToken.IdentifierValue() : std::to_string(valueToken.IntegerValue());
|
||||||
|
|
||||||
return std::make_unique<SimpleExpressionValue>(identifierValue);
|
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);
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include "Parsing/Simple/Expression/SimpleExpressionMatchers.h"
|
#include "Parsing/Simple/Expression/SimpleExpressionMatchers.h"
|
||||||
|
#include "StateMap/Parsing/StateMapParserState.h"
|
||||||
|
|
||||||
namespace state_map
|
namespace state_map
|
||||||
{
|
{
|
||||||
@ -10,9 +11,13 @@ namespace state_map
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
StateMapExpressionMatchers();
|
StateMapExpressionMatchers();
|
||||||
|
explicit StateMapExpressionMatchers(StateMapParserState* state);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::unique_ptr<matcher_t> ParseOperandExtension(const supplier_t* labelSupplier) const override;
|
std::unique_ptr<matcher_t> ParseOperandExtension(const supplier_t* labelSupplier) const override;
|
||||||
std::unique_ptr<ISimpleExpression> ProcessOperandExtension(SequenceResult<SimpleParserValue>& result) const override;
|
std::unique_ptr<ISimpleExpression> ProcessOperandExtension(SequenceResult<SimpleParserValue>& result) const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
StateMapParserState* m_state;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -38,20 +38,26 @@ namespace state_map
|
|||||||
|
|
||||||
class SequenceStateMapEntryClose final : public StateMapParser::sequence_t
|
class SequenceStateMapEntryClose final : public StateMapParser::sequence_t
|
||||||
{
|
{
|
||||||
|
static constexpr auto CAPTURE_FIRST_TOKEN = 1;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SequenceStateMapEntryClose()
|
SequenceStateMapEntryClose()
|
||||||
{
|
{
|
||||||
const SimpleMatcherFactory create(this);
|
const SimpleMatcherFactory create(this);
|
||||||
|
|
||||||
AddMatchers({
|
AddMatchers({
|
||||||
create.Char('}')
|
create.Char('}').Capture(CAPTURE_FIRST_TOKEN)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void ProcessMatch(StateMapParserState* state, SequenceResult<SimpleParserValue>& result) const override
|
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_in_entry = false;
|
||||||
|
state->m_entry_has_default = false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -63,7 +69,7 @@ namespace state_map
|
|||||||
public:
|
public:
|
||||||
SequenceCondition()
|
SequenceCondition()
|
||||||
{
|
{
|
||||||
AddLabeledMatchers(m_expression_matchers.Expression(this), StateMapExpressionMatchers::LABEL_EXPRESSION);
|
AddLabeledMatchers(StateMapExpressionMatchers().Expression(this), StateMapExpressionMatchers::LABEL_EXPRESSION);
|
||||||
const SimpleMatcherFactory create(this);
|
const SimpleMatcherFactory create(this);
|
||||||
|
|
||||||
AddMatchers({
|
AddMatchers({
|
||||||
@ -90,7 +96,7 @@ namespace state_map
|
|||||||
|
|
||||||
if (result.PeekAndRemoveIfTag(TAG_EXPRESSION) == TAG_EXPRESSION)
|
if (result.PeekAndRemoveIfTag(TAG_EXPRESSION) == TAG_EXPRESSION)
|
||||||
{
|
{
|
||||||
auto expression = m_expression_matchers.ProcessExpression(result);
|
auto expression = StateMapExpressionMatchers(state).ProcessExpression(result);
|
||||||
|
|
||||||
state->m_current_rule->m_conditions.emplace_back(std::move(expression));
|
state->m_current_rule->m_conditions.emplace_back(std::move(expression));
|
||||||
}
|
}
|
||||||
@ -98,13 +104,10 @@ namespace state_map
|
|||||||
{
|
{
|
||||||
assert(result.PeekAndRemoveIfTag(TAG_DEFAULT) == TAG_DEFAULT);
|
assert(result.PeekAndRemoveIfTag(TAG_DEFAULT) == TAG_DEFAULT);
|
||||||
auto& entry = state->m_definition->m_state_map_entries[state->m_current_entry_index];
|
auto& entry = state->m_definition->m_state_map_entries[state->m_current_entry_index];
|
||||||
entry.m_has_default = true;
|
state->m_entry_has_default = true;
|
||||||
entry.m_default_index = entry.m_rules.size() - 1;
|
entry.m_default_index = entry.m_rules.size() - 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
|
||||||
StateMapExpressionMatchers m_expression_matchers;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class SequenceValue final : public StateMapParser::sequence_t
|
class SequenceValue final : public StateMapParser::sequence_t
|
||||||
@ -113,19 +116,26 @@ namespace state_map
|
|||||||
static constexpr auto TAG_VALUE_LIST = 2;
|
static constexpr auto TAG_VALUE_LIST = 2;
|
||||||
|
|
||||||
static constexpr auto CAPTURE_VALUE = 1;
|
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_LIST = 1;
|
||||||
|
static constexpr auto LABEL_VALUE = 2;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SequenceValue()
|
SequenceValue()
|
||||||
{
|
{
|
||||||
const SimpleMatcherFactory create(this);
|
const SimpleMatcherFactory create(this);
|
||||||
|
|
||||||
|
AddLabeledMatchers(create.Or({
|
||||||
|
create.Identifier(),
|
||||||
|
create.Integer()
|
||||||
|
}), LABEL_VALUE);
|
||||||
|
|
||||||
AddLabeledMatchers({
|
AddLabeledMatchers({
|
||||||
create.Identifier().Capture(CAPTURE_VALUE),
|
create.Label(LABEL_VALUE).Capture(CAPTURE_VALUE),
|
||||||
create.OptionalLoop(create.And({
|
create.OptionalLoop(create.And({
|
||||||
create.Char(','),
|
create.Char(','),
|
||||||
create.Identifier().Capture(CAPTURE_VALUE)
|
create.Label(LABEL_VALUE).Capture(CAPTURE_VALUE)
|
||||||
}))
|
}))
|
||||||
}, LABEL_VALUE_LIST);
|
}, LABEL_VALUE_LIST);
|
||||||
|
|
||||||
@ -134,7 +144,7 @@ namespace state_map
|
|||||||
create.Keyword("passthrough").Tag(TAG_PASSTHROUGH),
|
create.Keyword("passthrough").Tag(TAG_PASSTHROUGH),
|
||||||
create.Label(LABEL_VALUE_LIST).Tag(TAG_VALUE_LIST)
|
create.Label(LABEL_VALUE_LIST).Tag(TAG_VALUE_LIST)
|
||||||
}),
|
}),
|
||||||
create.Char(';')
|
create.Char(';').Capture(CAPTURE_VALUE_END)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,15 +154,51 @@ namespace state_map
|
|||||||
assert(state->m_in_entry);
|
assert(state->m_in_entry);
|
||||||
assert(state->m_current_rule);
|
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)
|
if (result.PeekAndRemoveIfTag(TAG_VALUE_LIST) == TAG_VALUE_LIST)
|
||||||
{
|
{
|
||||||
|
auto resultIndex = 0u;
|
||||||
|
|
||||||
while (result.HasNextCapture(CAPTURE_VALUE))
|
while (result.HasNextCapture(CAPTURE_VALUE))
|
||||||
state->m_current_rule->m_values.emplace_back(result.NextCapture(CAPTURE_VALUE).IdentifierValue());
|
{
|
||||||
|
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::find_if(var.m_values.begin(), var.m_values.end(), [&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
|
else
|
||||||
{
|
{
|
||||||
// A rule without values is considered passthrough therefore just don't add values
|
// A rule without values is considered passthrough therefore just don't add values
|
||||||
assert(result.PeekAndRemoveIfTag(TAG_PASSTHROUGH) == TAG_PASSTHROUGH);
|
assert(result.PeekAndRemoveIfTag(TAG_PASSTHROUGH) == TAG_PASSTHROUGH);
|
||||||
|
state->m_current_rule->m_passthrough = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
state->m_current_rule = nullptr;
|
state->m_current_rule = nullptr;
|
||||||
|
@ -6,9 +6,19 @@ StateMapParserState::StateMapParserState(std::string stateMapName, const StateMa
|
|||||||
: m_layout(layout),
|
: m_layout(layout),
|
||||||
m_definition(std::make_unique<StateMapDefinition>(std::move(stateMapName), layout.m_entry_layout.m_entries.size())),
|
m_definition(std::make_unique<StateMapDefinition>(std::move(stateMapName), layout.m_entry_layout.m_entries.size())),
|
||||||
m_in_entry(false),
|
m_in_entry(false),
|
||||||
|
m_entry_has_default(false),
|
||||||
m_current_entry_index(0u),
|
m_current_entry_index(0u),
|
||||||
m_current_rule(nullptr)
|
m_current_rule(nullptr)
|
||||||
{
|
{
|
||||||
for (auto i = 0u; i < m_layout.m_entry_layout.m_entries.size(); i++)
|
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);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <map>
|
#include <unordered_map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <set>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "StateMap/StateMapDefinition.h"
|
#include "StateMap/StateMapDefinition.h"
|
||||||
@ -13,10 +14,13 @@ namespace state_map
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
const StateMapLayout& m_layout;
|
const StateMapLayout& m_layout;
|
||||||
std::map<std::string, size_t> m_valid_state_map_entry_names;
|
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;
|
std::unique_ptr<StateMapDefinition> m_definition;
|
||||||
|
|
||||||
bool m_in_entry;
|
bool m_in_entry;
|
||||||
|
bool m_entry_has_default;
|
||||||
size_t m_current_entry_index;
|
size_t m_current_entry_index;
|
||||||
StateMapRule* m_current_rule;
|
StateMapRule* m_current_rule;
|
||||||
|
|
||||||
|
@ -2,14 +2,14 @@
|
|||||||
|
|
||||||
using namespace state_map;
|
using namespace state_map;
|
||||||
|
|
||||||
bool StateMapRule::IsPassthrough() const
|
StateMapRule::StateMapRule()
|
||||||
|
: m_value(0u),
|
||||||
|
m_passthrough(false)
|
||||||
{
|
{
|
||||||
return m_values.empty();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
StateMapEntry::StateMapEntry()
|
StateMapEntry::StateMapEntry()
|
||||||
: m_has_default(false),
|
: m_default_index(0u)
|
||||||
m_default_index(0u)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "Utils/ClassUtils.h"
|
|
||||||
#include "Parsing/Simple/Expression/ISimpleExpression.h"
|
#include "Parsing/Simple/Expression/ISimpleExpression.h"
|
||||||
|
|
||||||
namespace state_map
|
namespace state_map
|
||||||
@ -13,15 +12,15 @@ namespace state_map
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
std::vector<std::unique_ptr<ISimpleExpression>> m_conditions;
|
std::vector<std::unique_ptr<ISimpleExpression>> m_conditions;
|
||||||
std::vector<std::string> m_values;
|
size_t m_value;
|
||||||
|
bool m_passthrough;
|
||||||
_NODISCARD bool IsPassthrough() const;
|
|
||||||
|
StateMapRule();
|
||||||
};
|
};
|
||||||
|
|
||||||
class StateMapEntry
|
class StateMapEntry
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
bool m_has_default;
|
|
||||||
size_t m_default_index;
|
size_t m_default_index;
|
||||||
std::vector<std::unique_ptr<StateMapRule>> m_rules;
|
std::vector<std::unique_ptr<StateMapRule>> m_rules;
|
||||||
|
|
||||||
|
58
src/ObjLoading/StateMap/StateMapFromTechniqueExtractor.cpp
Normal file
58
src/ObjLoading/StateMap/StateMapFromTechniqueExtractor.cpp
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
#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;
|
||||||
|
}
|
28
src/ObjLoading/StateMap/StateMapFromTechniqueExtractor.h
Normal file
28
src/ObjLoading/StateMap/StateMapFromTechniqueExtractor.h
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "Techset/TechniqueDefinitionAcceptor.h"
|
||||||
|
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
}
|
87
src/ObjLoading/StateMap/StateMapHandler.cpp
Normal file
87
src/ObjLoading/StateMap/StateMapHandler.cpp
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
#include "StateMapHandler.h"
|
||||||
|
|
||||||
|
#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::find_if(entry.m_rules.begin(), entry.m_rules.end(), [&vars](const std::unique_ptr<StateMapRule>& rule)
|
||||||
|
{
|
||||||
|
const auto matchingCondition = std::find_if(rule->m_conditions.begin(), rule->m_conditions.end(), [&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::find_if(var.m_values.begin(), var.m_values.end(), [&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
|
||||||
|
std::cerr << "Could not find base value for state map var \"" << var.m_name << "\"\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
36
src/ObjLoading/StateMap/StateMapHandler.h
Normal file
36
src/ObjLoading/StateMap/StateMapHandler.h
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
#include "Utils/ClassUtils.h"
|
||||||
|
#include "StateMap/StateMapDefinition.h"
|
||||||
|
#include "StateMap/StateMapLayout.h"
|
||||||
|
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
}
|
@ -5,6 +5,7 @@
|
|||||||
#include "Parsing/StateMapParser.h"
|
#include "Parsing/StateMapParser.h"
|
||||||
#include "Parsing/Impl/CommentRemovingStreamProxy.h"
|
#include "Parsing/Impl/CommentRemovingStreamProxy.h"
|
||||||
#include "Parsing/Impl/ParserSingleInputStream.h"
|
#include "Parsing/Impl/ParserSingleInputStream.h"
|
||||||
|
#include "Parsing/Matcher/StateMapExpressionMatchers.h"
|
||||||
|
|
||||||
using namespace state_map;
|
using namespace state_map;
|
||||||
|
|
||||||
@ -50,6 +51,7 @@ std::unique_ptr<StateMapDefinition> StateMapReader::ReadStateMapDefinition() con
|
|||||||
lexerConfig.m_read_strings = false;
|
lexerConfig.m_read_strings = false;
|
||||||
lexerConfig.m_read_integer_numbers = true;
|
lexerConfig.m_read_integer_numbers = true;
|
||||||
lexerConfig.m_read_floating_point_numbers = false;
|
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 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 parser = std::make_unique<StateMapParser>(lexer.get(), m_state_map_name, m_state_map_layout);
|
||||||
|
@ -33,7 +33,7 @@ public:
|
|||||||
_NODISCARD virtual bool Equals(const ISimpleExpression* other) const = 0;
|
_NODISCARD virtual bool Equals(const ISimpleExpression* other) const = 0;
|
||||||
_NODISCARD virtual bool IsStatic() const = 0;
|
_NODISCARD virtual bool IsStatic() const = 0;
|
||||||
_NODISCARD virtual SimpleExpressionValue EvaluateStatic() const = 0;
|
_NODISCARD virtual SimpleExpressionValue EvaluateStatic() const = 0;
|
||||||
_NODISCARD virtual SimpleExpressionValue EvaluateNonStatic(ISimpleExpressionScopeValues* scopeValues) const = 0;
|
_NODISCARD virtual SimpleExpressionValue EvaluateNonStatic(const ISimpleExpressionScopeValues* scopeValues) const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Include SimpleExpressionValue after definition to avoid "base class not defined"
|
// Include SimpleExpressionValue after definition to avoid "base class not defined"
|
||||||
|
@ -465,7 +465,7 @@ SimpleExpressionValue SimpleExpressionBinaryOperation::EvaluateStatic() const
|
|||||||
return m_operation_type->m_evaluation_function(m_operand1->EvaluateStatic(), m_operand2->EvaluateStatic());
|
return m_operation_type->m_evaluation_function(m_operand1->EvaluateStatic(), m_operand2->EvaluateStatic());
|
||||||
}
|
}
|
||||||
|
|
||||||
SimpleExpressionValue SimpleExpressionBinaryOperation::EvaluateNonStatic(ISimpleExpressionScopeValues* scopeValues) const
|
SimpleExpressionValue SimpleExpressionBinaryOperation::EvaluateNonStatic(const ISimpleExpressionScopeValues* scopeValues) const
|
||||||
{
|
{
|
||||||
return m_operation_type->m_evaluation_function(m_operand1->EvaluateNonStatic(scopeValues), m_operand2->EvaluateNonStatic(scopeValues));
|
return m_operation_type->m_evaluation_function(m_operand1->EvaluateNonStatic(scopeValues), m_operand2->EvaluateNonStatic(scopeValues));
|
||||||
}
|
}
|
||||||
|
@ -96,5 +96,5 @@ public:
|
|||||||
_NODISCARD bool Equals(const ISimpleExpression* other) const override;
|
_NODISCARD bool Equals(const ISimpleExpression* other) const override;
|
||||||
_NODISCARD bool IsStatic() const override;
|
_NODISCARD bool IsStatic() const override;
|
||||||
_NODISCARD SimpleExpressionValue EvaluateStatic() const override;
|
_NODISCARD SimpleExpressionValue EvaluateStatic() const override;
|
||||||
_NODISCARD SimpleExpressionValue EvaluateNonStatic(ISimpleExpressionScopeValues* scopeValues) const override;
|
_NODISCARD SimpleExpressionValue EvaluateNonStatic(const ISimpleExpressionScopeValues* scopeValues) const override;
|
||||||
};
|
};
|
||||||
|
@ -31,7 +31,7 @@ SimpleExpressionValue SimpleExpressionConditionalOperator::EvaluateStatic() cons
|
|||||||
return m_condition->EvaluateStatic().IsTruthy() ? m_true_value->EvaluateStatic() : m_false_value->EvaluateStatic();
|
return m_condition->EvaluateStatic().IsTruthy() ? m_true_value->EvaluateStatic() : m_false_value->EvaluateStatic();
|
||||||
}
|
}
|
||||||
|
|
||||||
SimpleExpressionValue SimpleExpressionConditionalOperator::EvaluateNonStatic(ISimpleExpressionScopeValues* scopeValues) const
|
SimpleExpressionValue SimpleExpressionConditionalOperator::EvaluateNonStatic(const ISimpleExpressionScopeValues* scopeValues) const
|
||||||
{
|
{
|
||||||
return m_condition->EvaluateNonStatic(scopeValues).IsTruthy()
|
return m_condition->EvaluateNonStatic(scopeValues).IsTruthy()
|
||||||
? m_true_value->EvaluateNonStatic(scopeValues)
|
? m_true_value->EvaluateNonStatic(scopeValues)
|
||||||
|
@ -11,7 +11,7 @@ public:
|
|||||||
_NODISCARD bool Equals(const ISimpleExpression* other) const override;
|
_NODISCARD bool Equals(const ISimpleExpression* other) const override;
|
||||||
_NODISCARD bool IsStatic() const override;
|
_NODISCARD bool IsStatic() const override;
|
||||||
_NODISCARD SimpleExpressionValue EvaluateStatic() const override;
|
_NODISCARD SimpleExpressionValue EvaluateStatic() const override;
|
||||||
_NODISCARD SimpleExpressionValue EvaluateNonStatic(ISimpleExpressionScopeValues* scopeValues) const override;
|
_NODISCARD SimpleExpressionValue EvaluateNonStatic(const ISimpleExpressionScopeValues* scopeValues) const override;
|
||||||
|
|
||||||
SimpleExpressionConditionalOperator();
|
SimpleExpressionConditionalOperator();
|
||||||
SimpleExpressionConditionalOperator(std::unique_ptr<ISimpleExpression> condition, std::unique_ptr<ISimpleExpression> trueExpression, std::unique_ptr<ISimpleExpression> falseExpression);
|
SimpleExpressionConditionalOperator(std::unique_ptr<ISimpleExpression> condition, std::unique_ptr<ISimpleExpression> trueExpression, std::unique_ptr<ISimpleExpression> falseExpression);
|
||||||
|
@ -22,7 +22,7 @@ SimpleExpressionValue SimpleExpressionScopeValue::EvaluateStatic() const
|
|||||||
return SimpleExpressionValue(0);
|
return SimpleExpressionValue(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
SimpleExpressionValue SimpleExpressionScopeValue::EvaluateNonStatic(ISimpleExpressionScopeValues* scopeValues) const
|
SimpleExpressionValue SimpleExpressionScopeValue::EvaluateNonStatic(const ISimpleExpressionScopeValues* scopeValues) const
|
||||||
{
|
{
|
||||||
return scopeValues->ValueByName(m_value_name);
|
return scopeValues->ValueByName(m_value_name);
|
||||||
}
|
}
|
||||||
|
@ -15,5 +15,5 @@ public:
|
|||||||
_NODISCARD bool Equals(const ISimpleExpression* other) const override;
|
_NODISCARD bool Equals(const ISimpleExpression* other) const override;
|
||||||
_NODISCARD bool IsStatic() const override;
|
_NODISCARD bool IsStatic() const override;
|
||||||
_NODISCARD SimpleExpressionValue EvaluateStatic() const override;
|
_NODISCARD SimpleExpressionValue EvaluateStatic() const override;
|
||||||
_NODISCARD SimpleExpressionValue EvaluateNonStatic(ISimpleExpressionScopeValues* scopeValues) const override;
|
_NODISCARD SimpleExpressionValue EvaluateNonStatic(const ISimpleExpressionScopeValues* scopeValues) const override;
|
||||||
};
|
};
|
||||||
|
@ -83,7 +83,7 @@ SimpleExpressionValue SimpleExpressionUnaryOperation::EvaluateStatic() const
|
|||||||
return m_operation_type->m_evaluation_function(m_operand->EvaluateStatic());
|
return m_operation_type->m_evaluation_function(m_operand->EvaluateStatic());
|
||||||
}
|
}
|
||||||
|
|
||||||
SimpleExpressionValue SimpleExpressionUnaryOperation::EvaluateNonStatic(ISimpleExpressionScopeValues* scopeValues) const
|
SimpleExpressionValue SimpleExpressionUnaryOperation::EvaluateNonStatic(const ISimpleExpressionScopeValues* scopeValues) const
|
||||||
{
|
{
|
||||||
return m_operation_type->m_evaluation_function(m_operand->EvaluateNonStatic(scopeValues));
|
return m_operation_type->m_evaluation_function(m_operand->EvaluateNonStatic(scopeValues));
|
||||||
}
|
}
|
||||||
|
@ -49,5 +49,5 @@ public:
|
|||||||
_NODISCARD bool Equals(const ISimpleExpression* other) const override;
|
_NODISCARD bool Equals(const ISimpleExpression* other) const override;
|
||||||
_NODISCARD bool IsStatic() const override;
|
_NODISCARD bool IsStatic() const override;
|
||||||
_NODISCARD SimpleExpressionValue EvaluateStatic() const override;
|
_NODISCARD SimpleExpressionValue EvaluateStatic() const override;
|
||||||
_NODISCARD SimpleExpressionValue EvaluateNonStatic(ISimpleExpressionScopeValues* scopeValues) const override;
|
_NODISCARD SimpleExpressionValue EvaluateNonStatic(const ISimpleExpressionScopeValues* scopeValues) const override;
|
||||||
};
|
};
|
||||||
|
@ -51,7 +51,7 @@ SimpleExpressionValue SimpleExpressionValue::EvaluateStatic() const
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
SimpleExpressionValue SimpleExpressionValue::EvaluateNonStatic(ISimpleExpressionScopeValues* scopeValues) const
|
SimpleExpressionValue SimpleExpressionValue::EvaluateNonStatic(const ISimpleExpressionScopeValues* scopeValues) const
|
||||||
{
|
{
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,6 @@ public:
|
|||||||
_NODISCARD bool Equals(const ISimpleExpression* other) const override;
|
_NODISCARD bool Equals(const ISimpleExpression* other) const override;
|
||||||
_NODISCARD bool IsStatic() const override;
|
_NODISCARD bool IsStatic() const override;
|
||||||
_NODISCARD SimpleExpressionValue EvaluateStatic() const override;
|
_NODISCARD SimpleExpressionValue EvaluateStatic() const override;
|
||||||
_NODISCARD SimpleExpressionValue EvaluateNonStatic(ISimpleExpressionScopeValues* scopeValues) const override;
|
_NODISCARD SimpleExpressionValue EvaluateNonStatic(const ISimpleExpressionScopeValues* scopeValues) const override;
|
||||||
_NODISCARD bool IsTruthy() const;
|
_NODISCARD bool IsTruthy() const;
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user