| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #pragma once | ||
| 2 | /* | ||
| 3 | * This file is part of the Falcon Player (FPP) and is Copyright (C) | ||
| 4 | * 2013-2026 by the Falcon Player Developers. | ||
| 5 | * | ||
| 6 | * The Falcon Player (FPP) is free software, and is covered under | ||
| 7 | * multiple Open Source licenses. Please see the included 'LICENSES' | ||
| 8 | * file for descriptions of what files are covered by each license. | ||
| 9 | * | ||
| 10 | * This source file is covered under the LGPL v2.1 as described in the | ||
| 11 | * included LICENSE.LGPL file. | ||
| 12 | */ | ||
| 13 | |||
| 14 | #include "fpp-json-fwd.h" | ||
| 15 | #include <memory> | ||
| 16 | #include <string> | ||
| 17 | #include <vector> | ||
| 18 | |||
| 19 | // Shared condition tree backing the "If" command's Check field (a | ||
| 20 | // conditionlist widget - one or more conditions, AND'd or OR'd together). | ||
| 21 | // Every leaf is a direct, synchronous call into an existing subsystem | ||
| 22 | // accessor - no I/O, no blocking, safe to call from any thread including | ||
| 23 | // (eventually, Phase 3) the player loop. | ||
| 24 | class ConditionNode { | ||
| 25 | public: | ||
| 26 | 2072 | virtual ~ConditionNode() = default; | |
| 27 | virtual bool evaluate() const = 0; | ||
| 28 | |||
| 29 | // Compound tree: {"op":"AND"|"OR","not":bool,"conditions":[...]} for a | ||
| 30 | // group, or {"source":...,"name":...,"comparator":...,"value":...,"not":bool} | ||
| 31 | // for a leaf. Returns nullptr (never throws) on malformed JSON - callers | ||
| 32 | // should treat that as "condition false". | ||
| 33 | static std::unique_ptr<ConditionNode> FromJSON(const Json::Value& j); | ||
| 34 | |||
| 35 | // Reads one leaf's current raw value (before any comparator/Value is | ||
| 36 | // applied) - the exact same lookup a leaf's evaluate() uses internally, | ||
| 37 | // exposed for the If editor's "Show Current Value" preview button so | ||
| 38 | // picking the right Value to compare against isn't guesswork. found is | ||
| 39 | // set false if source/name doesn't currently resolve to anything (e.g. | ||
| 40 | // an MQTT topic never seen, or an unset Variable). | ||
| 41 | static std::string PreviewSourceValue(const std::string& source, const std::string& name, bool& found); | ||
| 42 | |||
| 43 | // Full ad-hoc-leaf evaluation for the Check editor's consolidated | ||
| 44 | // eye-preview modal: given the same Source/Name/Comparator/Value/Not a | ||
| 45 | // saved leaf would have, returns the LHS/RHS values it currently | ||
| 46 | // resolves to and the comparator's result - reuses the exact same | ||
| 47 | // evaluation path a real saved leaf's evaluate() does, so this preview | ||
| 48 | // can never drift from what actually happens at runtime. | ||
| 49 | static void PreviewLeafResult(const std::string& source, const std::string& name, const std::string& comparatorStr, | ||
| 50 | const std::string& value, bool negate, bool& lhsFound, std::string& lhsValue, | ||
| 51 | std::string& rhsValue, bool& result); | ||
| 52 | |||
| 53 | // How a Name/Value field's raw text will actually be treated at | ||
| 54 | // evaluate() time - same priority order as the private | ||
| 55 | // EvaluateNameOrExpression() in Condition.cpp: an exact match against a | ||
| 56 | // real variable name always wins first, before any '='/%%/formula | ||
| 57 | // detection ever runs. Exposed for GET /api/variables?validateExpression | ||
| 58 | // (Variables.cpp) so the Check editor's valid/invalid icon can tell "this | ||
| 59 | // matches a real variable" and "this compiles as a formula" apart from | ||
| 60 | // "this is just inert literal text" (Condition.cpp's own documented, | ||
| 61 | // non-error passthrough for unmatched plain text) - the raw | ||
| 62 | // ExpressionProcessor::compile() the icon used before always reported | ||
| 63 | // "valid" for the literal case too, so a typo'd variable name (e.g. | ||
| 64 | // missing/extra characters) looked identical to a real match. | ||
| 65 | enum class ExpressionKind { Variable, | ||
| 66 | Formula, | ||
| 67 | Literal }; | ||
| 68 | static ExpressionKind ClassifyNameOrExpression(const std::string& text, bool& compileOk); | ||
| 69 | }; | ||
| 70 |