DiffEq - Modern C++ ODE Integration Library 1.0.0
High-performance C++ library for solving ODEs with async signal processing
Loading...
Searching...
No Matches
signal_processor_simple.hpp
1#pragma once
2
3#include <functional>
4#include <memory>
5#include <vector>
6#include <unordered_map>
7#include <string>
8#include <chrono>
9#include <any>
10
11// Forward declaration
12namespace diffeq::async {
13 template<typename S>
14 class AsyncIntegrator;
15}
16
17namespace diffeq::signal {
18
25template<typename T>
26struct Signal {
27 T data;
28 std::chrono::steady_clock::time_point timestamp;
29 std::string type_id;
30 double priority = 1.0;
31
32 template<typename U>
33 Signal(U&& d, std::string_view id = "", double prio = 1.0)
34 : data(std::forward<U>(d))
35 , timestamp(std::chrono::steady_clock::now())
36 , type_id(id)
37 , priority(prio) {}
38};
39
46template<typename S>
47class SignalProcessor {
48public:
49 using state_type = S;
50 using time_type = typename S::value_type;
51
52 // Signal handler function types
53 template<typename T>
54 using SignalHandler = std::function<void(const Signal<T>&)>;
55
56private:
57 // Generic signal handlers using type erasure
58 std::unordered_map<std::string, std::function<void(const std::any&)>> custom_handlers_;
59
60 // Parameter update handlers
61 std::unordered_map<std::string, std::function<void(double)>> parameter_handlers_;
62
63public:
64 SignalProcessor() = default;
65
69 template<typename T>
70 void emit_signal(std::string_view signal_type, T&& data, double priority = 1.0) {
71 Signal<std::decay_t<T>> signal(std::forward<T>(data), signal_type, priority);
72 process_signal(signal);
73 }
74
78 template<typename T, typename Handler>
79 void register_handler(std::string_view signal_type, Handler&& handler) {
80 static_assert(std::is_invocable_v<Handler, const Signal<T>&>,
81 "Handler must be callable with Signal<T>");
82
83 custom_handlers_[std::string(signal_type)] =
84 [h = std::forward<Handler>(handler)](const std::any& signal) {
85 try {
86 const auto& typed_signal = std::any_cast<const Signal<T>&>(signal);
87 h(typed_signal);
88 } catch (const std::bad_any_cast&) {
89 // Type mismatch - ignore or log
90 }
91 };
92 }
93
97 void update_parameter(const std::string& param_name, double value) {
98 auto it = parameter_handlers_.find(param_name);
99 if (it != parameter_handlers_.end()) {
100 it->second(value);
101 }
102 }
103
104private:
108 template<typename SignalType>
109 void process_signal(const SignalType& signal) {
110 // Find and call appropriate handler
111 auto it = custom_handlers_.find(signal.type_id);
112 if (it != custom_handlers_.end()) {
113 it->second(std::any(signal));
114 }
115 }
116};
117
121template<typename S>
122auto make_signal_processor(std::shared_ptr<async::AsyncIntegrator<S>> integrator = nullptr) {
123 return std::make_shared<SignalProcessor<S>>();
124}
125
129template<typename S>
130auto make_signal_processor() {
131 return std::make_shared<SignalProcessor<S>>();
132}
133
137namespace signals {
138 using DoubleSignal = Signal<double>;
139 using VectorSignal = Signal<std::vector<double>>;
140 using StringSignal = Signal<std::string>;
141}
142
143} // namespace diffeq::signal
void emit_signal(std::string_view signal_type, T &&data, double priority=1.0)
Emit a signal with arbitrary data.
void register_handler(std::string_view signal_type, Handler &&handler)
Register a typed signal handler.
void update_parameter(const std::string &param_name, double value)
Update integration parameters.
Generic signal data structure.