mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2025-08-19 13:00:11 -07:00
Added missing logic variables and REGISTER_FUNCTION_WITH_DEFAULTS.
This commit is contained in:
parent
c055e8cd92
commit
3e8b45165d
5 changed files with 86 additions and 30 deletions
|
@ -909,38 +909,48 @@ void RegionTable_Init() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0 // Print all conditions for debugging
|
#if 1 // Print all conditions for debugging
|
||||||
// RANDOTODO: Remove before merging
|
// RANDOTODO: Remove before merging
|
||||||
|
if (Rando::Context::GetInstance()->GetLogic()->mSaveContext != nullptr) {
|
||||||
|
std::function<void(std::shared_ptr<LogicExpression>)> eval;
|
||||||
|
eval = [&eval](std::shared_ptr<LogicExpression> expression) {
|
||||||
|
expression->Evaluate<bool>();
|
||||||
|
for (auto& child : expression->GetChildren()) {
|
||||||
|
eval(child);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
std::ostringstream ss;
|
std::ostringstream ss;
|
||||||
|
|
||||||
for (uint32_t i = RR_ROOT; i <= RR_GANONS_CASTLE; i++) {
|
for (uint32_t i = RR_ROOT; i <= RR_GANONS_CASTLE; i++) {
|
||||||
for (EventAccess& eventAccess : areaTable[i].events) {
|
for (EventAccess& eventAccess : areaTable[i].events) {
|
||||||
try {
|
try {
|
||||||
LogicExpression::Parse(eventAccess.GetConditionStr());
|
eval(LogicExpression::Parse(eventAccess.GetConditionStr()));
|
||||||
}
|
} catch (std::exception& ex) {
|
||||||
catch (std::exception& ex) {
|
|
||||||
ss << eventAccess.GetConditionStr() << std::endl;
|
ss << eventAccess.GetConditionStr() << std::endl;
|
||||||
|
ss << ex.what() << std::endl << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (LocationAccess& locPair : areaTable[i].locations) {
|
for (LocationAccess& locPair : areaTable[i].locations) {
|
||||||
try {
|
try {
|
||||||
LogicExpression::Parse(locPair.GetConditionStr());
|
eval(LogicExpression::Parse(locPair.GetConditionStr()));
|
||||||
}
|
} catch (std::exception& ex) {
|
||||||
catch (std::exception& ex) {
|
|
||||||
ss << locPair.GetConditionStr() << std::endl;
|
ss << locPair.GetConditionStr() << std::endl;
|
||||||
|
ss << ex.what() << std::endl << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (Entrance& exit : areaTable[i].exits) {
|
for (Entrance& exit : areaTable[i].exits) {
|
||||||
try {
|
try {
|
||||||
LogicExpression::Parse(exit.GetConditionStr());
|
eval(LogicExpression::Parse(exit.GetConditionStr()));
|
||||||
}
|
} catch (std::exception& ex) {
|
||||||
catch (std::exception& ex) {
|
|
||||||
ss << exit.GetConditionStr() << std::endl;
|
ss << exit.GetConditionStr() << std::endl;
|
||||||
|
ss << ex.what() << std::endl << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SPDLOG_INFO("Parse Failure Conditions:\n{}", ss.str());
|
SPDLOG_INFO("Parse/Eval Failure Conditions:\n{}", ss.str());
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -429,6 +429,9 @@ std::string LogicExpression::Impl::GetExprErrorContext() const {
|
||||||
#define REGISTER_FUNCTION(fn) \
|
#define REGISTER_FUNCTION(fn) \
|
||||||
{ #fn, LogicExpression::Impl::RegisterFunction(#fn, fn) }
|
{ #fn, LogicExpression::Impl::RegisterFunction(#fn, fn) }
|
||||||
|
|
||||||
|
#define REGISTER_FUNCTION_WITH_DEFAULTS(fn, ...) \
|
||||||
|
{ #fn, LogicExpression::Impl::RegisterFunctionWithDefaults(#fn, fn, std::make_tuple(__VA_ARGS__)) }
|
||||||
|
|
||||||
#define REGISTER_LOGIC_FUNCTION(fn) \
|
#define REGISTER_LOGIC_FUNCTION(fn) \
|
||||||
{ #fn, LogicExpression::Impl::RegisterLogicFunction(#fn, &Rando::Logic::fn) }
|
{ #fn, LogicExpression::Impl::RegisterLogicFunction(#fn, &Rando::Logic::fn) }
|
||||||
|
|
||||||
|
@ -482,9 +485,10 @@ std::unordered_map<std::string, LogicExpression::Impl::FunctionAdapter> LogicExp
|
||||||
void LogicExpression::Impl::PopulateFunctionAdapters() {
|
void LogicExpression::Impl::PopulateFunctionAdapters() {
|
||||||
functionAdapters = {
|
functionAdapters = {
|
||||||
REGISTER_FUNCTION(Here),
|
REGISTER_FUNCTION(Here),
|
||||||
REGISTER_FUNCTION(MQSpiritSharedBrokenWallRoom),
|
REGISTER_FUNCTION_WITH_DEFAULTS(MQSpiritSharedBrokenWallRoom, RandomizerRegion{}, ConditionFn{}, false),
|
||||||
REGISTER_FUNCTION(MQSpiritSharedStatueRoom),
|
REGISTER_FUNCTION_WITH_DEFAULTS(MQSpiritSharedStatueRoom, RandomizerRegion{}, ConditionFn{}, false),
|
||||||
REGISTER_FUNCTION(CanBuyAnother),
|
REGISTER_FUNCTION(CanBuyAnother),
|
||||||
|
REGISTER_FUNCTION(CanBuyCheck),
|
||||||
REGISTER_FUNCTION(GetOption),
|
REGISTER_FUNCTION(GetOption),
|
||||||
REGISTER_FUNCTION(GetTrickOption),
|
REGISTER_FUNCTION(GetTrickOption),
|
||||||
REGISTER_FUNCTION(HasAccessTo),
|
REGISTER_FUNCTION(HasAccessTo),
|
||||||
|
@ -781,6 +785,11 @@ void LogicExpression::Impl::PopulateVariableAdapters() {
|
||||||
REGISTER_LOGIC_VARIABLE(MQSpirit3SunsEnemies),
|
REGISTER_LOGIC_VARIABLE(MQSpirit3SunsEnemies),
|
||||||
REGISTER_LOGIC_VARIABLE(Spirit1FSilverRupees),
|
REGISTER_LOGIC_VARIABLE(Spirit1FSilverRupees),
|
||||||
REGISTER_LOGIC_VARIABLE(JabuRutoIn1F),
|
REGISTER_LOGIC_VARIABLE(JabuRutoIn1F),
|
||||||
|
REGISTER_LOGIC_VARIABLE(THRescuedAllCarpenters),
|
||||||
|
REGISTER_LOGIC_VARIABLE(THCouldFree1TorchCarpenter),
|
||||||
|
REGISTER_LOGIC_VARIABLE(THCouldFreeDoubleCellCarpenter),
|
||||||
|
REGISTER_LOGIC_VARIABLE(TH_CouldFreeDeadEndCarpenter),
|
||||||
|
REGISTER_LOGIC_VARIABLE(THCouldRescueSlopeCarpenter),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -220,6 +220,42 @@ class LogicExpression {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Helper to call member function with default parameters
|
||||||
|
// This function evaluates provided arguments and fills missing ones with defaults.
|
||||||
|
template <typename Function, typename Tuple, size_t... Is>
|
||||||
|
static ValueVariant
|
||||||
|
CallFunctionWithDefaultsImpl(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...>) {
|
||||||
|
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()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluate provided arguments and fill missing ones with defaults
|
||||||
|
return 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 RegisterFunctionWithDefaults(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 {
|
||||||
|
constexpr size_t expectedArgCount = sizeof...(Args);
|
||||||
|
return CallFunctionWithDefaultsImpl(functionName, function, args, path, depth, callback, defaults,
|
||||||
|
std::make_index_sequence<expectedArgCount>{});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// Helper to call pointer-to-member function on "logic" with extracted arguments.
|
// Helper to call pointer-to-member function on "logic" with extracted arguments.
|
||||||
template <typename MemberFunction, typename... Args, size_t... Is>
|
template <typename MemberFunction, typename... Args, size_t... Is>
|
||||||
static ValueVariant CallMemberFunctionImpl(const std::string& functionName, MemberFunction function,
|
static ValueVariant CallMemberFunctionImpl(const std::string& functionName, MemberFunction function,
|
||||||
|
|
|
@ -111,8 +111,7 @@ static void PopulateConnectionExpression(LogicTrackerNode::Connection& connectio
|
||||||
|
|
||||||
try {
|
try {
|
||||||
expression = LogicExpression::Parse(expressionStr);
|
expression = LogicExpression::Parse(expressionStr);
|
||||||
}
|
} catch (const std::exception& e) {
|
||||||
catch (const std::exception& e) {
|
|
||||||
connection.ExpressionTable.Root.ErrorMessage = std::string("Parse Error: ") + e.what();
|
connection.ExpressionTable.Root.ErrorMessage = std::string("Parse Error: ") + e.what();
|
||||||
connection.ExpressionTable.Root.Children.clear();
|
connection.ExpressionTable.Root.Children.clear();
|
||||||
connection.ExpressionTable.CombineAll = true;
|
connection.ExpressionTable.CombineAll = true;
|
||||||
|
|
|
@ -441,6 +441,8 @@ typedef enum {
|
||||||
{ "RO_ZF_OPEN", RO_ZF_OPEN },
|
{ "RO_ZF_OPEN", RO_ZF_OPEN },
|
||||||
{ "RO_WATERFALL_CLOSED", RO_WATERFALL_CLOSED },
|
{ "RO_WATERFALL_CLOSED", RO_WATERFALL_CLOSED },
|
||||||
{ "RO_WATERFALL_OPEN", RO_WATERFALL_OPEN },
|
{ "RO_WATERFALL_OPEN", RO_WATERFALL_OPEN },
|
||||||
|
{ "RO_JABU_CLOSED", RO_JABU_CLOSED },
|
||||||
|
{ "RO_JABU_OPEN", RO_JABU_OPEN },
|
||||||
{ "RO_AGE_CHILD", RO_AGE_CHILD },
|
{ "RO_AGE_CHILD", RO_AGE_CHILD },
|
||||||
{ "RO_AGE_ADULT", RO_AGE_ADULT },
|
{ "RO_AGE_ADULT", RO_AGE_ADULT },
|
||||||
{ "RO_AGE_RANDOM", RO_AGE_RANDOM },
|
{ "RO_AGE_RANDOM", RO_AGE_RANDOM },
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue