// eqpalg/utility/expression_engine.h #pragma once #include #include #include #include #include #include #include #include #include #include #include #include using MExp = mix_cc::matheval::Expression; using TimePoint = std::chrono::system_clock::time_point; /** * @brief 统一表达式引擎 * * 集中管理所有命名表达式的注册、求值、FunVars 状态函数、 * 变量刷新(共享内存/IHDB)、hold 变量。 * * 替代 ExpModule + ExpBase 的表达式管理,消除 is_exp_alg_ 补丁。 */ class ExpressionEngine { public: /** * @param mm_vars 变量映射(由 AlgBase 持有,此处引用) * @param m_tags 数据 tag 点列表(由 AlgBase 持有,此处引用) */ ExpressionEngine(std::map& mm_vars, std::vector& m_tags); ~ExpressionEngine() = default; // 禁止拷贝/移动 ExpressionEngine(const ExpressionEngine&) = delete; ExpressionEngine& operator=(const ExpressionEngine&) = delete; // ========== 表达式注册 ========== /** * @brief 注册一个命名表达式(自动进行 FunVars 状态函数替换) * @param name 表达式名称 ("act", "feedback", "result", "pre_result", ...) * @param raw_exp_str 原始表达式字符串(可含 KeepC(tag1,1) 等状态函数) * @return 0 成功,-1 失败 */ int registerExpression(const std::string& name, const std::string& raw_exp_str); /** * @brief 注册不带 FunVars 替换的原始表达式 */ int registerRawExpression(const std::string& name, const std::string& raw_exp_str); /** 查询表达式是否已注册 */ bool hasExpression(const std::string& name) const { return exps_.count(name) > 0; } // ========== 表达式求值 ========== double evaluate(const std::string& name); bool evaluateBool(const std::string& name); /** * @brief 获取变量 map 引用(供外部直接读写) */ std::map& vars() { return mm_vars_; } // ========== 每周期数据刷新 ========== void refreshFromMemory(const TimePoint& now_time, mix_cc::time_range_t& query_time_range); void refreshFromIhdRow(int row, const Eigen::Matrix& queried_data, const std::vector& queried_time, TimePoint& now_time, mix_cc::time_range_t& query_time_range); int firstFill(int data_source, TimePoint& now_time, mix_cc::time_range_t& query_time_range); // ========== FunVars 控制 ========== void autoResetFunVars(); void markFunVarsNeedReset(); void forceResetFunVars(); // ========== hold 变量 ========== void refreshHoldVars(); // ========== 调试 ========== void printVars(const std::string& exp_str = ""); private: std::map& mm_vars_; std::vector& m_tags_; StatExp::FunVars fun_vars_; bool fun_vars_need_reset_ = false; // 表达式注册表 struct ExpEntry { std::string raw_str; std::string processed_str; std::unique_ptr ptr; }; std::map exps_; // hold(n,T) 变量 std::map> hold_times_; VarsCache var_cache_; static constexpr size_t PV_NUM = 6; static void ensureVarCache(VarsCache& vc, size_t tag_count) { if (vc.tag_num == 0 && tag_count > 0) { vc.init(tag_count, 6); } } // 内部辅助 int initHoldExpStr(const std::string& exp_str); };