mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-06-08 05:48:19 -05:00
93 lines
3.8 KiB
C++
93 lines
3.8 KiB
C++
#include "StateMapHandler.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
|
|
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;
|
|
}
|