// eqpalg/utility/expression_engine.cpp #include #include #include #include #include ExpressionEngine::ExpressionEngine(std::map& mm_vars, std::vector& m_tags) : mm_vars_(mm_vars), m_tags_(m_tags) {} // 惰性初始化 VarsCache(首次变量刷新时调用) static void ensureVarCache(VarsCache& vc, size_t tag_count) { if (vc.tag_num == 0 && tag_count > 0) { vc.init(tag_count, 6); } } int ExpressionEngine::registerExpression(const std::string& name, const std::string& raw_exp_str) { if (exps_.count(name)) return 0; // 已注册,幂等 auto& entry = exps_[name]; entry.raw_str = raw_exp_str; // 通过 FunVars 替换状态函数(KeepC/KeepT/RiseEdge/Detect)为 funN 变量 auto [ok, processed] = fun_vars_.add_exp_str(raw_exp_str, &mm_vars_); if (!ok) return -1; entry.processed_str = processed; // 编译表达式 try { entry.ptr = std::make_unique(processed, &mm_vars_); } catch (const std::exception& e) { return -1; } // 从表达式中提取 hold(n,T) 模式 initHoldExpStr(processed); return 0; } int ExpressionEngine::registerRawExpression(const std::string& name, const std::string& raw_exp_str) { if (exps_.count(name)) return 0; auto& entry = exps_[name]; entry.raw_str = raw_exp_str; entry.processed_str = raw_exp_str; try { entry.ptr = std::make_unique(raw_exp_str, &mm_vars_); } catch (const std::exception& e) { return -1; } return 0; } double ExpressionEngine::evaluate(const std::string& name) { auto it = exps_.find(name); if (it == exps_.end()) return 0.0; return it->second.ptr->evaluate(); } bool ExpressionEngine::evaluateBool(const std::string& name) { return static_cast(evaluate(name)); } int ExpressionEngine::initHoldExpStr(const std::string& exp_str) { auto hold_sub_strs = HoldTime::find_substr(exp_str, "_HE"); for (const auto& sub_str : hold_sub_strs) { bool flag; double timeM; std::string tagi; std::string var_name; std::tie(flag, timeM, tagi, var_name) = HoldTime::find_hold(sub_str); if (flag) { if (hold_times_.find(var_name) == hold_times_.end()) { hold_times_.emplace(std::make_pair( var_name, std::make_unique(timeM, tagi, var_name))); } } } refreshHoldVars(); return 0; } // ========== FunVars 控制 ========== void ExpressionEngine::autoResetFunVars() { if (fun_vars_need_reset_) { fun_vars_.refresh_fun_vars(true, &mm_vars_); fun_vars_need_reset_ = false; } } void ExpressionEngine::markFunVarsNeedReset() { fun_vars_need_reset_ = true; } void ExpressionEngine::forceResetFunVars() { fun_vars_.refresh_fun_vars(true, &mm_vars_); fun_vars_need_reset_ = false; } void ExpressionEngine::refreshFromMemory( const TimePoint& now_time, mix_cc::time_range_t& query_time_range) { ensureVarCache(var_cache_, m_tags_.size()); for (size_t i = 0; i < m_tags_.size(); i++) { double current = SingletonTemplate::GetInstance()[m_tags_[i]]; // pN = 旧 tagN mm_vars_[var_cache_.p_keys[i]] = mm_vars_[var_cache_.tag_keys[i]]; // tagN = 当前值 mm_vars_[var_cache_.tag_keys[i]] = current; // pvN 历史移位 for (size_t j = PV_NUM - 1; j > 0; j--) { mm_vars_[var_cache_.pv_keys[i][j]] = mm_vars_[var_cache_.pv_keys[i][j - 1]]; } mm_vars_[var_cache_.pv_keys[i][0]] = current; } mm_vars_["now"] = std::chrono::duration_cast( now_time.time_since_epoch()) .count(); fun_vars_.refresh_fun_vars(false, &mm_vars_); query_time_range.set_right(now_time); refreshHoldVars(); } void ExpressionEngine::refreshFromIhdRow( int row, const Eigen::Matrix& queried_data, const std::vector& queried_time, TimePoint& now_time, mix_cc::time_range_t& query_time_range) { if (queried_data.rows() == 0 || queried_data.cols() == 0) return; if (row < 0 || row >= queried_data.rows()) return; if (static_cast(m_tags_.size()) > queried_data.cols()) return; ensureVarCache(var_cache_, m_tags_.size()); for (size_t i = 0; i < m_tags_.size(); i++) { // pN = 旧 tagN mm_vars_[var_cache_.p_keys[i]] = mm_vars_[var_cache_.tag_keys[i]]; // tagN = 当前行数据 mm_vars_[var_cache_.tag_keys[i]] = queried_data(row, i); // pvN 历史移位 for (size_t j = PV_NUM - 1; j > 0; j--) { mm_vars_[var_cache_.pv_keys[i][j]] = mm_vars_[var_cache_.pv_keys[i][j - 1]]; } mm_vars_[var_cache_.pv_keys[i][0]] = mm_vars_[var_cache_.tag_keys[i]]; } mm_vars_["now"] = mix_cc::mix_time_t(queried_time[row]).to_milliseconds(); now_time = queried_time[row]; query_time_range.set_right(queried_time[row]); fun_vars_.refresh_fun_vars(false, &mm_vars_); refreshHoldVars(); } void ExpressionEngine::refreshHoldVars() { for (auto& kv : hold_times_) { mm_vars_[kv.first] = static_cast(kv.second->update_value(mm_vars_[kv.second->tagi])); } } // ========== 调试 ========== void ExpressionEngine::printVars(const std::string& exp_str) { // Debug method — prints all variables to LOG }