mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2025-08-19 04:50:05 -07:00
Ran Clang Format.
This commit is contained in:
parent
0efa327a82
commit
c76ead04fb
7 changed files with 172 additions and 141 deletions
|
@ -37,7 +37,8 @@ enum class EntranceType {
|
|||
};
|
||||
|
||||
#define ENTRANCE(check, condition, ...) \
|
||||
Entrance(RandomizerRegion::check, [] { return condition; }, CleanCheckConditionString(#condition), ##__VA_ARGS__)
|
||||
Entrance( \
|
||||
RandomizerRegion::check, [] { return condition; }, CleanCheckConditionString(#condition), ##__VA_ARGS__)
|
||||
|
||||
class Entrance {
|
||||
public:
|
||||
|
|
|
@ -909,7 +909,7 @@ void RegionTable_Init() {
|
|||
}
|
||||
}
|
||||
|
||||
#if 0 // Print all conditions for debugging
|
||||
#if 0 // Print all conditions for debugging
|
||||
// RANDOTODO: Remove before merging
|
||||
std::ostringstream ss;
|
||||
|
||||
|
@ -941,7 +941,7 @@ void RegionTable_Init() {
|
|||
}
|
||||
|
||||
SPDLOG_INFO("Parse Failure Conditions:\n{}", ss.str());
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
constexpr void ReplaceFirstInString(std::string& s, std::string const& toReplace, std::string const& replaceWith) {
|
||||
|
|
|
@ -23,7 +23,8 @@ class Region;
|
|||
constexpr std::string CleanCheckConditionString(std::string condition);
|
||||
|
||||
#define EVENT_ACCESS(event, condition) \
|
||||
EventAccess(&logic->event, #event, [] { return condition; }, CleanCheckConditionString(#condition))
|
||||
EventAccess( \
|
||||
&logic->event, #event, [] { return condition; }, CleanCheckConditionString(#condition))
|
||||
|
||||
class EventAccess {
|
||||
public:
|
||||
|
|
|
@ -15,23 +15,39 @@ std::string LogicExpression::Impl::GetTypeString() const {
|
|||
switch (type) {
|
||||
case Type::Value:
|
||||
switch (valueType) {
|
||||
case ValueType::Boolean: return "Boolean";
|
||||
case ValueType::Number: return "Number";
|
||||
case ValueType::Enum: return "Enum";
|
||||
case ValueType::Identifier: return "Variable";
|
||||
default: return "Unknown Value";
|
||||
case ValueType::Boolean:
|
||||
return "Boolean";
|
||||
case ValueType::Number:
|
||||
return "Number";
|
||||
case ValueType::Enum:
|
||||
return "Enum";
|
||||
case ValueType::Identifier:
|
||||
return "Variable";
|
||||
default:
|
||||
return "Unknown Value";
|
||||
}
|
||||
case Type::FunctionCall: return "Function: " + functionName;
|
||||
case Type::Not: return "Not";
|
||||
case Type::And: return "And";
|
||||
case Type::Or: return "Or";
|
||||
case Type::Comparison: return "Comparison: " + operation;
|
||||
case Type::Add: return "Add";
|
||||
case Type::Subtract: return "Subtract";
|
||||
case Type::Multiply: return "Multiply";
|
||||
case Type::Divide: return "Divide";
|
||||
case Type::Ternary: return "Ternary";
|
||||
default: return "Unknown";
|
||||
case Type::FunctionCall:
|
||||
return "Function: " + functionName;
|
||||
case Type::Not:
|
||||
return "Not";
|
||||
case Type::And:
|
||||
return "And";
|
||||
case Type::Or:
|
||||
return "Or";
|
||||
case Type::Comparison:
|
||||
return "Comparison: " + operation;
|
||||
case Type::Add:
|
||||
return "Add";
|
||||
case Type::Subtract:
|
||||
return "Subtract";
|
||||
case Type::Multiply:
|
||||
return "Multiply";
|
||||
case Type::Divide:
|
||||
return "Divide";
|
||||
case Type::Ternary:
|
||||
return "Ternary";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -255,15 +271,13 @@ class Parser {
|
|||
}
|
||||
|
||||
std::shared_ptr<LogicExpression::Impl> ParseMulDiv() {
|
||||
return ParseBinaryOp(
|
||||
pos, tokens, &Parser::ParsePrimary,
|
||||
{ { "*", LogicExpression::Type::Multiply }, { "/", LogicExpression::Type::Divide } });
|
||||
return ParseBinaryOp(pos, tokens, &Parser::ParsePrimary,
|
||||
{ { "*", LogicExpression::Type::Multiply }, { "/", LogicExpression::Type::Divide } });
|
||||
}
|
||||
|
||||
std::shared_ptr<LogicExpression::Impl> ParseAddSub() {
|
||||
return ParseBinaryOp(
|
||||
pos, tokens, &Parser::ParseMulDiv,
|
||||
{ { "+", LogicExpression::Type::Add }, { "-", LogicExpression::Type::Subtract } });
|
||||
return ParseBinaryOp(pos, tokens, &Parser::ParseMulDiv,
|
||||
{ { "+", LogicExpression::Type::Add }, { "-", LogicExpression::Type::Subtract } });
|
||||
}
|
||||
|
||||
std::shared_ptr<LogicExpression::Impl> ParseComparison() {
|
||||
|
@ -277,13 +291,11 @@ class Parser {
|
|||
}
|
||||
|
||||
std::shared_ptr<LogicExpression::Impl> ParseAnd() {
|
||||
return ParseBinaryOp(pos, tokens, &Parser::ParseComparison,
|
||||
{ { "&&", LogicExpression::Type::And } });
|
||||
return ParseBinaryOp(pos, tokens, &Parser::ParseComparison, { { "&&", LogicExpression::Type::And } });
|
||||
}
|
||||
|
||||
std::shared_ptr<LogicExpression::Impl> ParseOr() {
|
||||
return ParseBinaryOp(pos, tokens, &Parser::ParseAnd,
|
||||
{ { "||", LogicExpression::Type::Or } });
|
||||
return ParseBinaryOp(pos, tokens, &Parser::ParseAnd, { { "||", LogicExpression::Type::Or } });
|
||||
}
|
||||
|
||||
std::shared_ptr<LogicExpression::Impl> ParseTernary() {
|
||||
|
@ -420,8 +432,11 @@ std::string LogicExpression::Impl::GetExprErrorContext() const {
|
|||
#define REGISTER_LOGIC_FUNCTION(fn) \
|
||||
{ #fn, LogicExpression::Impl::RegisterLogicFunction(#fn, &Rando::Logic::fn) }
|
||||
|
||||
#define REGISTER_LOGIC_FUNCTION_WITH_DEFAULTS(fn, ...) \
|
||||
{ #fn, LogicExpression::Impl::RegisterLogicFunctionWithDefaults(#fn, &Rando::Logic::fn, std::make_tuple(__VA_ARGS__)) }
|
||||
#define REGISTER_LOGIC_FUNCTION_WITH_DEFAULTS(fn, ...) \
|
||||
{ \
|
||||
#fn, LogicExpression::Impl::RegisterLogicFunctionWithDefaults(#fn, &Rando::Logic::fn, \
|
||||
std::make_tuple(__VA_ARGS__)) \
|
||||
}
|
||||
|
||||
#define REGISTER_LOGIC_VARIABLE(var) \
|
||||
{ #var, LogicExpression::Impl::RegisterLogicVariable(#var, &Rando::Logic::var) }
|
||||
|
@ -463,7 +478,6 @@ static bool RegionAgeTimeAccess(const RandomizerRegion region, const RegionAgeTi
|
|||
}
|
||||
#pragma endregion
|
||||
|
||||
|
||||
std::unordered_map<std::string, LogicExpression::Impl::FunctionAdapter> LogicExpression::Impl::functionAdapters;
|
||||
void LogicExpression::Impl::PopulateFunctionAdapters() {
|
||||
functionAdapters = {
|
||||
|
@ -558,12 +572,12 @@ LogicExpression::ValueVariant LogicExpression::Impl::EvaluateFunction(const std:
|
|||
auto it = functionAdapters.find(functionName);
|
||||
if (it != functionAdapters.end()) {
|
||||
auto result = it->second(children, path, depth, callback);
|
||||
|
||||
|
||||
// If callback is provided, call it with function info
|
||||
if (callback) {
|
||||
callback(expression, path, depth, GetTypeString(), result);
|
||||
}
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
throw std::runtime_error("Unknown function: " + functionName + GetExprErrorContext());
|
||||
|
@ -773,13 +787,13 @@ LogicExpression::ValueVariant LogicExpression::Impl::EvaluateVariable() const {
|
|||
if (variableAdapters.empty()) {
|
||||
PopulateVariableAdapters();
|
||||
}
|
||||
|
||||
|
||||
auto it = variableAdapters.find(value);
|
||||
if (it != variableAdapters.end()) {
|
||||
std::vector<std::shared_ptr<LogicExpression::Impl>> emptyArgs;
|
||||
return it->second(emptyArgs, "var", 0, nullptr); // Call the variable adapter with empty arguments
|
||||
}
|
||||
|
||||
|
||||
throw std::runtime_error("Unknown variable: '" + value + "'" + GetExprErrorContext());
|
||||
}
|
||||
|
||||
|
@ -788,13 +802,13 @@ LogicExpression::ValueVariant LogicExpression::Impl::EvaluateArithmetic(char op,
|
|||
const EvaluationCallback& callback) const {
|
||||
const auto lhs = children[0]->Evaluate(path + ".0", depth + 1, callback);
|
||||
const auto rhs = children[1]->Evaluate(path + ".1", depth + 1, callback);
|
||||
|
||||
|
||||
auto arith = [&](auto a, auto b) -> ValueVariant {
|
||||
// Accept int, uint8_t, but not bool
|
||||
if constexpr ((std::is_same_v<std::decay_t<decltype(a)>, int> ||
|
||||
std::is_same_v<std::decay_t<decltype(a)>, uint8_t>) &&
|
||||
(std::is_same_v<std::decay_t<decltype(b)>, int> ||
|
||||
std::is_same_v<std::decay_t<decltype(b)>, uint8_t>)) {
|
||||
std::is_same_v<std::decay_t<decltype(a)>,
|
||||
uint8_t>)&&(std::is_same_v<std::decay_t<decltype(b)>, int> ||
|
||||
std::is_same_v<std::decay_t<decltype(b)>, uint8_t>)) {
|
||||
int l = static_cast<int>(a);
|
||||
int r = static_cast<int>(b);
|
||||
ValueVariant result;
|
||||
|
@ -822,37 +836,46 @@ LogicExpression::ValueVariant LogicExpression::Impl::EvaluateArithmetic(char op,
|
|||
GetExprErrorContext());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
try {
|
||||
auto result = std::visit(arith, lhs, rhs);
|
||||
|
||||
|
||||
// If callback is provided, call it
|
||||
if (callback) {
|
||||
std::string opStr;
|
||||
switch (op) {
|
||||
case '+': opStr = "Add"; break;
|
||||
case '-': opStr = "Subtract"; break;
|
||||
case '*': opStr = "Multiply"; break;
|
||||
case '/': opStr = "Divide"; break;
|
||||
default: opStr = "Unknown";
|
||||
case '+':
|
||||
opStr = "Add";
|
||||
break;
|
||||
case '-':
|
||||
opStr = "Subtract";
|
||||
break;
|
||||
case '*':
|
||||
opStr = "Multiply";
|
||||
break;
|
||||
case '/':
|
||||
opStr = "Divide";
|
||||
break;
|
||||
default:
|
||||
opStr = "Unknown";
|
||||
}
|
||||
|
||||
// Get the sub-expression string
|
||||
|
||||
// Get the sub-expression string
|
||||
// Find root to get expression string
|
||||
const Impl* root = this;
|
||||
while (root->parent)
|
||||
root = root->parent;
|
||||
|
||||
|
||||
std::string exprStr;
|
||||
if (root->expressionString) {
|
||||
exprStr = root->expressionString->substr(startIndex, endIndex - startIndex);
|
||||
} else {
|
||||
exprStr = "Unknown expression";
|
||||
}
|
||||
|
||||
|
||||
callback(expression, path, depth, opStr, result);
|
||||
}
|
||||
|
||||
|
||||
return result;
|
||||
} catch (const std::bad_variant_access&) {
|
||||
throw std::runtime_error("Invalid variant access in arithmetic" + GetExprErrorContext());
|
||||
|
@ -862,7 +885,7 @@ LogicExpression::ValueVariant LogicExpression::Impl::EvaluateArithmetic(char op,
|
|||
LogicExpression::ValueVariant LogicExpression::Impl::Evaluate(const std::string& path, int depth,
|
||||
const EvaluationCallback& callback) const {
|
||||
ValueVariant result;
|
||||
|
||||
|
||||
// Get the expression string
|
||||
std::string exprText;
|
||||
if (expressionString) {
|
||||
|
@ -873,16 +896,16 @@ LogicExpression::ValueVariant LogicExpression::Impl::Evaluate(const std::string&
|
|||
const Impl* root = this;
|
||||
while (root->parent)
|
||||
root = root->parent;
|
||||
|
||||
|
||||
if (root->expressionString) {
|
||||
exprText = root->expressionString->substr(startIndex, endIndex - startIndex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (exprText.empty()) {
|
||||
exprText = "Unknown expression";
|
||||
}
|
||||
|
||||
|
||||
switch (type) {
|
||||
case Type::Value:
|
||||
if (valueType == ValueType::Boolean) {
|
||||
|
@ -896,15 +919,15 @@ LogicExpression::ValueVariant LogicExpression::Impl::Evaluate(const std::string&
|
|||
} else {
|
||||
throw std::runtime_error("Unknown value type: " + value + GetExprErrorContext());
|
||||
}
|
||||
|
||||
|
||||
if (callback) {
|
||||
callback(expression, path, depth, GetTypeString(), result);
|
||||
}
|
||||
return result;
|
||||
|
||||
|
||||
case Type::FunctionCall:
|
||||
return EvaluateFunction(path, depth, callback);
|
||||
|
||||
|
||||
case Type::Not: {
|
||||
auto childResult = children[0]->Evaluate(path + ".0", depth + 1, callback);
|
||||
result = !GetValue<bool>(childResult);
|
||||
|
@ -913,7 +936,7 @@ LogicExpression::ValueVariant LogicExpression::Impl::Evaluate(const std::string&
|
|||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
case Type::And: {
|
||||
// Short-circuit evaluation
|
||||
auto leftResult = children[0]->Evaluate(path + ".0", depth + 1, callback);
|
||||
|
@ -924,7 +947,7 @@ LogicExpression::ValueVariant LogicExpression::Impl::Evaluate(const std::string&
|
|||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
auto rightResult = children[1]->Evaluate(path + ".1", depth + 1, callback);
|
||||
result = GetValue<bool>(rightResult);
|
||||
if (callback) {
|
||||
|
@ -932,7 +955,7 @@ LogicExpression::ValueVariant LogicExpression::Impl::Evaluate(const std::string&
|
|||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
case Type::Or: {
|
||||
// Short-circuit evaluation
|
||||
auto leftResult = children[0]->Evaluate(path + ".0", depth + 1, callback);
|
||||
|
@ -943,7 +966,7 @@ LogicExpression::ValueVariant LogicExpression::Impl::Evaluate(const std::string&
|
|||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
auto rightResult = children[1]->Evaluate(path + ".1", depth + 1, callback);
|
||||
result = GetValue<bool>(rightResult);
|
||||
if (callback) {
|
||||
|
@ -951,7 +974,7 @@ LogicExpression::ValueVariant LogicExpression::Impl::Evaluate(const std::string&
|
|||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
case Type::Comparison: {
|
||||
auto leftResult = children[0]->Evaluate(path + ".0", depth + 1, callback);
|
||||
auto rightResult = children[1]->Evaluate(path + ".1", depth + 1, callback);
|
||||
|
@ -959,7 +982,7 @@ LogicExpression::ValueVariant LogicExpression::Impl::Evaluate(const std::string&
|
|||
auto compare = [&](auto a, auto b) -> bool {
|
||||
using A = decltype(a);
|
||||
using B = decltype(b);
|
||||
|
||||
|
||||
// Compare booleans only for equality/inequality.
|
||||
if constexpr (std::is_same_v<A, bool> && std::is_same_v<B, bool>) {
|
||||
if (operation == "==")
|
||||
|
@ -1000,7 +1023,7 @@ LogicExpression::ValueVariant LogicExpression::Impl::Evaluate(const std::string&
|
|||
throw std::runtime_error("Invalid variant access in comparison" + GetExprErrorContext());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
case Type::Add:
|
||||
return EvaluateArithmetic('+', path, depth, callback);
|
||||
case Type::Subtract:
|
||||
|
@ -1009,28 +1032,28 @@ LogicExpression::ValueVariant LogicExpression::Impl::Evaluate(const std::string&
|
|||
return EvaluateArithmetic('*', path, depth, callback);
|
||||
case Type::Divide:
|
||||
return EvaluateArithmetic('/', path, depth, callback);
|
||||
|
||||
|
||||
case Type::Ternary: {
|
||||
auto condResult = children[0]->Evaluate(path + ".0", depth + 1, callback);
|
||||
bool cond = GetValue<bool>(condResult);
|
||||
|
||||
|
||||
if (cond) {
|
||||
result = children[1]->Evaluate(path + ".1", depth + 1, callback);
|
||||
} else {
|
||||
result = children[2]->Evaluate(path + ".2", depth + 1, callback);
|
||||
}
|
||||
|
||||
|
||||
if (callback) {
|
||||
callback(expression, path, depth, GetTypeString() + (cond ? " (true branch)" : " (false branch)"),
|
||||
result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
default:
|
||||
throw std::runtime_error("Unknown expression type" + GetExprErrorContext());
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1040,13 +1063,14 @@ ExpressionEvaluation EvaluateExpression(std::string condition) {
|
|||
|
||||
ExpressionEvaluation EvaluateExpression(std::shared_ptr<LogicExpression> expression) {
|
||||
// Create a vector to store the evaluation sequence
|
||||
std::vector<std::tuple<std::shared_ptr<LogicExpression>, std::string, int, std::string, LogicExpression::ValueVariant>>
|
||||
std::vector<
|
||||
std::tuple<std::shared_ptr<LogicExpression>, std::string, int, std::string, LogicExpression::ValueVariant>>
|
||||
evaluationSequence;
|
||||
|
||||
// Define a callback that records each evaluation step
|
||||
auto recordCallback = [&evaluationSequence](const std::shared_ptr<LogicExpression>& expr,
|
||||
const std::string& path, int depth,
|
||||
const std::string& type, const LogicExpression::ValueVariant& result) {
|
||||
auto recordCallback = [&evaluationSequence](const std::shared_ptr<LogicExpression>& expr, const std::string& path,
|
||||
int depth, const std::string& type,
|
||||
const LogicExpression::ValueVariant& result) {
|
||||
evaluationSequence.emplace_back(expr, path, depth, type, result);
|
||||
};
|
||||
|
||||
|
|
|
@ -76,7 +76,8 @@ class LogicExpression {
|
|||
std::shared_ptr<LogicExpression> expression;
|
||||
|
||||
// Modified to accept path and depth
|
||||
ValueVariant Evaluate(const std::string& path = "0", int depth = 0, const EvaluationCallback& callback = nullptr) const;
|
||||
ValueVariant Evaluate(const std::string& path = "0", int depth = 0,
|
||||
const EvaluationCallback& callback = nullptr) const;
|
||||
|
||||
// Helper to get a string representation of the type
|
||||
std::string GetTypeString() const;
|
||||
|
@ -84,14 +85,16 @@ class LogicExpression {
|
|||
private:
|
||||
std::string GetExprErrorContext() const;
|
||||
// Updated to pass callback to children
|
||||
ValueVariant EvaluateFunction(const std::string& path = "0", int depth = 0, const EvaluationCallback& callback = nullptr) const;
|
||||
ValueVariant EvaluateFunction(const std::string& path = "0", int depth = 0,
|
||||
const EvaluationCallback& callback = nullptr) const;
|
||||
ValueVariant EvaluateEnum() const;
|
||||
ValueVariant EvaluateVariable() const;
|
||||
// Updated to pass callback to children
|
||||
ValueVariant EvaluateArithmetic(char op, const std::string& path = "0", int depth = 0,
|
||||
const EvaluationCallback& callback = nullptr) const;
|
||||
|
||||
using FunctionAdapter = std::function<ValueVariant(const std::vector<std::shared_ptr<Impl>>&, const std::string&, int, const EvaluationCallback&)>;
|
||||
using FunctionAdapter = std::function<ValueVariant(const std::vector<std::shared_ptr<Impl>>&,
|
||||
const std::string&, int, const EvaluationCallback&)>;
|
||||
|
||||
static std::unordered_map<std::string, FunctionAdapter> functionAdapters;
|
||||
static void PopulateFunctionAdapters();
|
||||
|
@ -146,13 +149,13 @@ class LogicExpression {
|
|||
// callable lambda. Otherwise, it evaluates the expression immediately to convert it into a bool, int, or enum
|
||||
// value. Template parameter T represents the expected type of the argument for the function
|
||||
// being registered.
|
||||
template <typename T>
|
||||
static T EvaluateArg(const std::shared_ptr<LogicExpression::Impl>& expr, const std::string& path,
|
||||
int depth, const EvaluationCallback& callback) {
|
||||
template <typename T>
|
||||
static T EvaluateArg(const std::shared_ptr<LogicExpression::Impl>& expr, const std::string& path, int depth,
|
||||
const EvaluationCallback& callback) {
|
||||
if constexpr (std::is_same_v<T, ConditionFn>) {
|
||||
// Wrap the expression in a lambda to delay evaluation until the function is called.
|
||||
return [&expr = *expr, path, depth, callback]() -> bool {
|
||||
return std::get<bool>(expr.Evaluate(path, depth + 1, callback));
|
||||
return [&expr = *expr, path, depth, callback]() -> bool {
|
||||
return std::get<bool>(expr.Evaluate(path, depth + 1, callback));
|
||||
};
|
||||
} else {
|
||||
// For value types, evaluate the expression immediately.
|
||||
|
@ -171,9 +174,9 @@ class LogicExpression {
|
|||
// calls 'function'. functionName is used for error reporting.
|
||||
template <typename Function, typename... Args, size_t... Is>
|
||||
static ValueVariant CallFunctionImpl(const std::string& functionName, Function function,
|
||||
const std::vector<std::shared_ptr<LogicExpression::Impl>>& args,
|
||||
const std::string& path, int depth, const EvaluationCallback& callback,
|
||||
std::index_sequence<Is...>) {
|
||||
const std::vector<std::shared_ptr<LogicExpression::Impl>>& args,
|
||||
const std::string& path, int depth, const EvaluationCallback& callback,
|
||||
std::index_sequence<Is...>) {
|
||||
// Each args[Is] is converted to its expected type using EvaluateArg<Args> and passed to
|
||||
// 'function'.
|
||||
return function(EvaluateArg<Args>(args[Is], path + "." + std::to_string(Is), depth, callback)...);
|
||||
|
@ -186,14 +189,15 @@ class LogicExpression {
|
|||
template <typename Function, typename... Args>
|
||||
static ValueVariant MakeFunctionAdapter(const std::string& functionName, Function function,
|
||||
const std::vector<std::shared_ptr<LogicExpression::Impl>>& args,
|
||||
const std::string& path, int depth, const EvaluationCallback& callback) {
|
||||
const std::string& path, int depth,
|
||||
const EvaluationCallback& callback) {
|
||||
constexpr size_t expectedArgCount = sizeof...(Args);
|
||||
if (args.size() != expectedArgCount) {
|
||||
throw std::runtime_error("Function " + functionName + " expects " + std::to_string(expectedArgCount) +
|
||||
" arguments, but got " + std::to_string(args.size()));
|
||||
" arguments, but got " + std::to_string(args.size()));
|
||||
}
|
||||
return CallFunctionImpl<Function, Args...>(functionName, function, args, path, depth, callback,
|
||||
std::index_sequence_for<Args...>{});
|
||||
std::index_sequence_for<Args...>{});
|
||||
}
|
||||
|
||||
// Wrapper that deduces parameter types from the function and returns a FunctionAdapter.
|
||||
|
@ -204,12 +208,13 @@ class LogicExpression {
|
|||
static FunctionAdapter RegisterFunction(const std::string& functionName, Function function) {
|
||||
using traits = function_traits<Function>;
|
||||
using ArgsTuple = typename traits::args_tuple;
|
||||
return [functionName, function](const std::vector<std::shared_ptr<LogicExpression::Impl>>& args,
|
||||
const std::string& path, int depth, const EvaluationCallback& callback) -> ValueVariant {
|
||||
return [functionName, function](const std::vector<std::shared_ptr<LogicExpression::Impl>>& args,
|
||||
const std::string& path, int depth,
|
||||
const EvaluationCallback& callback) -> ValueVariant {
|
||||
return std::apply(
|
||||
[&](auto... dummy) {
|
||||
return MakeFunctionAdapter<Function, decltype(dummy)...>(functionName, function, args,
|
||||
path, depth, callback);
|
||||
return MakeFunctionAdapter<Function, decltype(dummy)...>(functionName, function, args, path,
|
||||
depth, callback);
|
||||
},
|
||||
ArgsTuple{}); // Unpacks the expected parameter types.
|
||||
};
|
||||
|
@ -218,10 +223,11 @@ class LogicExpression {
|
|||
// Helper to call pointer-to-member function on "logic" with extracted arguments.
|
||||
template <typename MemberFunction, typename... Args, size_t... Is>
|
||||
static ValueVariant CallMemberFunctionImpl(const std::string& functionName, MemberFunction function,
|
||||
const std::vector<std::shared_ptr<LogicExpression::Impl>>& args,
|
||||
const std::string& path, int depth, const EvaluationCallback& callback,
|
||||
std::index_sequence<Is...>) {
|
||||
return ((*logic).*function)(EvaluateArg<Args>(args[Is], path + "." + std::to_string(Is), depth, callback)...);
|
||||
const std::vector<std::shared_ptr<LogicExpression::Impl>>& args,
|
||||
const std::string& path, int depth,
|
||||
const EvaluationCallback& callback, std::index_sequence<Is...>) {
|
||||
return ((*logic).*
|
||||
function)(EvaluateArg<Args>(args[Is], path + "." + std::to_string(Is), depth, callback)...);
|
||||
}
|
||||
|
||||
// Implementation of RegisterLogicFunction that wraps a pointer-to-member function from Logic.
|
||||
|
@ -229,18 +235,19 @@ class LogicExpression {
|
|||
static FunctionAdapter RegisterLogicFunction(const std::string& functionName, Function function) {
|
||||
using traits = function_traits<Function>;
|
||||
using ArgsTuple = typename traits::args_tuple;
|
||||
return [functionName, function](const std::vector<std::shared_ptr<LogicExpression::Impl>>& args,
|
||||
const std::string& path, int depth, const EvaluationCallback& callback) -> ValueVariant {
|
||||
return [functionName, function](const std::vector<std::shared_ptr<LogicExpression::Impl>>& args,
|
||||
const std::string& path, int depth,
|
||||
const EvaluationCallback& callback) -> ValueVariant {
|
||||
return std::apply(
|
||||
[&](auto... dummy) {
|
||||
constexpr size_t expectedArgCount = sizeof...(dummy);
|
||||
if (args.size() != expectedArgCount) {
|
||||
throw std::runtime_error("Function " + functionName + " expects " +
|
||||
std::to_string(expectedArgCount) + " arguments, but got " +
|
||||
std::to_string(args.size()));
|
||||
std::to_string(expectedArgCount) + " arguments, but got " +
|
||||
std::to_string(args.size()));
|
||||
}
|
||||
return CallMemberFunctionImpl<Function, decltype(dummy)...>(
|
||||
functionName, function, args, path, depth, callback,
|
||||
functionName, function, args, path, depth, callback,
|
||||
std::index_sequence_for<decltype(dummy)...>{});
|
||||
},
|
||||
ArgsTuple{});
|
||||
|
@ -252,49 +259,51 @@ class LogicExpression {
|
|||
template <typename Function, typename Tuple, size_t... Is>
|
||||
static ValueVariant
|
||||
CallMemberFunctionWithDefaultsImpl(const std::string& functionName, Function function,
|
||||
const std::vector<std::shared_ptr<LogicExpression::Impl>>& args,
|
||||
const std::string& path, int depth, const EvaluationCallback& callback,
|
||||
Tuple&& defaults, std::index_sequence<Is...>) {
|
||||
const std::vector<std::shared_ptr<LogicExpression::Impl>>& args,
|
||||
const std::string& path, int depth, const EvaluationCallback& callback,
|
||||
Tuple&& defaults, std::index_sequence<Is...>) {
|
||||
constexpr size_t expectedArgCount = sizeof...(Is);
|
||||
|
||||
// Ensure the number of provided arguments does not exceed the expected count
|
||||
if (args.size() > expectedArgCount) {
|
||||
throw std::runtime_error("Function " + functionName + " expects up to " +
|
||||
std::to_string(expectedArgCount) + " arguments, but got " +
|
||||
std::to_string(args.size()));
|
||||
std::to_string(expectedArgCount) + " arguments, but got " +
|
||||
std::to_string(args.size()));
|
||||
}
|
||||
|
||||
// Evaluate provided arguments and fill missing ones with defaults
|
||||
return ((*logic).*
|
||||
function)((Is < args.size() ?
|
||||
EvaluateArg<std::tuple_element_t<Is, std::decay_t<Tuple>>>(args[Is], path + "." + std::to_string(Is), depth, callback)
|
||||
: std::get<Is>(defaults))...);
|
||||
return ((*logic).*function)((Is < args.size()
|
||||
? EvaluateArg<std::tuple_element_t<Is, std::decay_t<Tuple>>>(
|
||||
args[Is], path + "." + std::to_string(Is), depth, callback)
|
||||
: std::get<Is>(defaults))...);
|
||||
}
|
||||
|
||||
// Wrapper for member functions with default parameters
|
||||
template <typename Function, typename... Args>
|
||||
static FunctionAdapter RegisterLogicFunctionWithDefaults(const std::string& functionName, Function function,
|
||||
std::tuple<Args...> defaults) {
|
||||
return [functionName, function, defaults](const std::vector<std::shared_ptr<LogicExpression::Impl>>& args,
|
||||
const std::string& path, int depth, const EvaluationCallback& callback) -> ValueVariant {
|
||||
std::tuple<Args...> defaults) {
|
||||
return [functionName, function, defaults](const std::vector<std::shared_ptr<LogicExpression::Impl>>& args,
|
||||
const std::string& path, int depth,
|
||||
const EvaluationCallback& callback) -> ValueVariant {
|
||||
constexpr size_t expectedArgCount = sizeof...(Args);
|
||||
return CallMemberFunctionWithDefaultsImpl(functionName, function, args, path, depth, callback,
|
||||
defaults,
|
||||
std::make_index_sequence<expectedArgCount>{});
|
||||
return CallMemberFunctionWithDefaultsImpl(functionName, function, args, path, depth, callback, defaults,
|
||||
std::make_index_sequence<expectedArgCount>{});
|
||||
};
|
||||
}
|
||||
|
||||
// Add this function in the Template Magic section to implement variable registration.
|
||||
template <typename T> static FunctionAdapter RegisterLogicVariable(const std::string& varName, T Rando::Logic::*var) {
|
||||
return [varName, var](const std::vector<std::shared_ptr<LogicExpression::Impl>>& args,
|
||||
const std::string& path, int depth, const EvaluationCallback& callback) -> ValueVariant {
|
||||
if (!args.empty()) {
|
||||
throw std::runtime_error("Variable " + varName + " expects 0 arguments, but got " +
|
||||
std::to_string(args.size()));
|
||||
}
|
||||
auto value = (*logic).*var;
|
||||
return GetValue<T>(value);
|
||||
};
|
||||
template <typename T>
|
||||
static FunctionAdapter RegisterLogicVariable(const std::string& varName, T Rando::Logic::*var) {
|
||||
return
|
||||
[varName, var](const std::vector<std::shared_ptr<LogicExpression::Impl>>& args, const std::string& path,
|
||||
int depth, const EvaluationCallback& callback) -> ValueVariant {
|
||||
if (!args.empty()) {
|
||||
throw std::runtime_error("Variable " + varName + " expects 0 arguments, but got " +
|
||||
std::to_string(args.size()));
|
||||
}
|
||||
auto value = (*logic).*var;
|
||||
return GetValue<T>(value);
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -78,7 +78,7 @@ typedef enum {
|
|||
|
||||
#define MAX_TRICK_NAME_SIZE 50
|
||||
|
||||
#define TWO_ACTOR_PARAMS(a, b) ((((a) & 0xFFFF) << 16) | ((b) & 0xFFFF))
|
||||
#define TWO_ACTOR_PARAMS(a, b) ((((a)&0xFFFF) << 16) | ((b)&0xFFFF))
|
||||
|
||||
// This should probably go in a less rando-specific location
|
||||
// but the best location will probably be in the modding engine
|
||||
|
|
|
@ -68,12 +68,7 @@ static ExpressionTable::ExpressionRow CreateExpressionRows(const std::shared_ptr
|
|||
return row;
|
||||
}
|
||||
|
||||
enum class AgeTime {
|
||||
ChildDay,
|
||||
ChildNight,
|
||||
AdultDay,
|
||||
AdultNight
|
||||
};
|
||||
enum class AgeTime { ChildDay, ChildNight, AdultDay, AdultNight };
|
||||
|
||||
static void PopulateExpressionValues(ExpressionTable::ExpressionRow& row, const ExpressionEvaluation& eval,
|
||||
AgeTime ageTime) {
|
||||
|
@ -107,7 +102,7 @@ static std::tuple<bool, bool, bool> CalculateCombines(const ExpressionTable::Exp
|
|||
combineChild &= childCombineChild;
|
||||
combineAdult &= childCombineAdult;
|
||||
}
|
||||
return {combineAll, combineChild, combineAdult};
|
||||
return { combineAll, combineChild, combineAdult };
|
||||
}
|
||||
|
||||
static void PopulateConnectionExpression(LogicTrackerNode::Connection& connection, std::string expressionStr) {
|
||||
|
@ -196,7 +191,8 @@ void LogicTrackerWindow::ShowRandomizerCheck(RandomizerCheck randomizerCheck) {
|
|||
expandNodeId = node.NodeId;
|
||||
}
|
||||
|
||||
void LogicTrackerWindow::ShowRandomizerRegion(RandomizerRegion toRandomizerRegion, RandomizerRegion fromRandomizerRegion) {
|
||||
void LogicTrackerWindow::ShowRandomizerRegion(RandomizerRegion toRandomizerRegion,
|
||||
RandomizerRegion fromRandomizerRegion) {
|
||||
const auto& region = RegionTable(toRandomizerRegion);
|
||||
|
||||
LogicTrackerNode node;
|
||||
|
@ -294,8 +290,7 @@ static void DrawCondition(const LogicExpression& expression) {
|
|||
{ defaultColor, " " + expression.GetOperation() + " " },
|
||||
{ fontColors[1], expression.GetChildren()[1]->ToString() } });
|
||||
} else if (type == LogicExpression::Type::Not) {
|
||||
DrawColoredWrappedText({ { defaultColor, "!" },
|
||||
{ fontColors[0], expression.GetChildren()[0]->ToString() } });
|
||||
DrawColoredWrappedText({ { defaultColor, "!" }, { fontColors[0], expression.GetChildren()[0]->ToString() } });
|
||||
} else if (type == LogicExpression::Type::FunctionCall) {
|
||||
std::vector<std::pair<ImVec4, std::string>> segments;
|
||||
segments.emplace_back(fontColors[0], expression.GetFunctionName());
|
||||
|
@ -482,8 +477,9 @@ static void DrawNode(LogicTrackerNode& node) {
|
|||
ImGui::SetNextItemOpen(expandNodeId == node.NodeId, ImGuiCond_Always);
|
||||
}
|
||||
|
||||
bool connectionOpen = ImGui::CollapsingHeader(
|
||||
("From " + connection.ParentName).c_str(), ImGuiTreeNodeFlags_AllowOverlap | ImGuiTreeNodeFlags_SpanAvailWidth);
|
||||
bool connectionOpen =
|
||||
ImGui::CollapsingHeader(("From " + connection.ParentName).c_str(),
|
||||
ImGuiTreeNodeFlags_AllowOverlap | ImGuiTreeNodeFlags_SpanAvailWidth);
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Show Connection Logic");
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue