MayaFlux 1.0.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
Logic.hpp
Go to the documentation of this file.
1#pragma once
2
4
6
7/**
8 * @enum LogicMode
9 * @brief Defines the computational model for digital signal evaluation
10 */
11enum class LogicMode : uint8_t {
12 DIRECT, ///< Stateless evaluation of current input only (combinational logic)
13 SEQUENTIAL, ///< State-based evaluation using history of inputs (sequential logic)
14 TEMPORAL, ///< Time-dependent evaluation with timing constraints
15 MULTI_INPUT ///< Parallel evaluation of multiple input signals
16};
17
18/**
19 * @enum LogicOperator
20 * @brief Digital operators for boolean computation
21 */
22enum class LogicOperator : uint8_t {
23 AND, ///< Logical AND - true only when all inputs are true
24 OR, ///< Logical OR - true when any input is true
25 XOR, ///< Logical XOR - true when odd number of inputs are true
26 NOT, ///< Logical NOT - inverts the input
27 NAND, ///< Logical NAND - inverted AND operation
28 NOR, ///< Logical NOR - inverted OR operation
29 IMPLIES, ///< Logical implication - false only when A is true and B is false
30 THRESHOLD, ///< Binary quantization - true when input exceeds threshold
31 HYSTERESIS, ///< Threshold with memory - prevents rapid oscillation at boundary
32 EDGE, ///< Transition detector - identifies state changes
33 CUSTOM ///< User-defined boolean function
34};
35
36/**
37 * @enum EdgeType
38 * @brief Digital transition patterns to detect
39 */
40enum class EdgeType : uint8_t {
41 RISING, ///< Low-to-high transition (0→1)
42 FALLING, ///< High-to-low transition (1→0)
43 BOTH ///< Any state transition
44};
45
46/**
47 * @enum LogicEventType
48 * @brief Events that can trigger callbacks
49 */
50enum class LogicEventType : uint8_t {
51 TICK, // Every sample
52 CHANGE, // Any state change
53 TRUE, // Change to true
54 FALSE, // Change to false
55 WHILE_TRUE, // Every tick while true
56 WHILE_FALSE, // Every tick while false
57 CONDITIONAL // Custom condition
58};
59
60class MAYAFLUX_API LogicContext : public NodeContext {
61public:
62 /**
63 * @brief Constructs a LogicContext with complete state information
64 * @param value Current output value (0.0 for false, 1.0 for true)
65 * @param mode Current computational model
66 * @param operator_type Current boolean operator
67 * @param history Buffer of previous boolean states
68 * @param threshold Decision boundary for binary quantization
69 * @param edge_detected Whether a state transition was detected
70 * @param edge_type Type of transition being monitored
71 * @param inputs Current input values for multi-input evaluation
72 */
75 LogicOperator operator_type,
76 std::span<bool> history,
77 double threshold,
78 bool edge_detected = false,
79 EdgeType edge_type = EdgeType::BOTH,
80 const std::vector<double>& inputs = {})
82 , m_mode(mode)
83 , m_operator(operator_type)
84 , m_history(history)
85 , m_threshold(threshold)
86 , m_edge_detected(edge_detected)
87 , m_edge_type(edge_type)
88 , m_inputs(inputs)
89 , m_input(value)
90 {
91 }
92
93 // Getters for context properties
94 [[nodiscard]] LogicMode get_mode() const { return m_mode; }
95 [[nodiscard]] LogicOperator get_operator() const { return m_operator; }
96 [[nodiscard]] std::span<bool> get_history() const { return m_history; }
97 [[nodiscard]] double get_threshold() const { return m_threshold; }
98 [[nodiscard]] bool is_edge_detected() const { return m_edge_detected; }
99 [[nodiscard]] EdgeType get_edge_type() const { return m_edge_type; }
100 [[nodiscard]] const std::vector<double>& get_inputs() const { return m_inputs; }
101
102 /**
103 * @brief The node's coefficient array as it stands at this tick
104 *
105 * Empty for a node without one. For a node with state in the array this
106 * is that state, after the function has run for the sample.
107 */
108 [[nodiscard]] const std::vector<double>& get_coefficients() const
109 {
110 static const std::vector<double> none;
111 return m_coefficients ? *m_coefficients : none;
112 }
113 [[nodiscard]] const double& get_value() const { return m_input; }
114
115 // Boolean conversion of the current value
116 [[nodiscard]] bool as_bool() const { return get_value() > 0.5; }
117
118private:
119 LogicMode m_mode; ///< Current computational model
120 LogicOperator m_operator; ///< Current boolean operator
121 std::span<bool> m_history; ///< History of boolean states
122 double m_threshold; ///< Decision boundary for binary quantization
123 bool m_edge_detected; ///< Whether a state transition was detected
124 EdgeType m_edge_type; ///< Type of transition being monitored
125 const std::vector<double>& m_inputs; ///< Current input values (for multi-input mode)
126 double m_input; ///< Current input value for multi-input mode
127 const std::vector<double>* m_coefficients {}; ///< The node's coefficient array, set by the node each tick
128
129 friend class Logic;
130};
131
132/**
133 * @class LogicContextGpu
134 * @brief GPU-accelerated context for logic node callbacks
135 */
136class MAYAFLUX_API LogicContextGpu
137 : public LogicContext,
138 public GpuVectorData {
139public:
141 double value,
143 LogicOperator operator_type,
144 std::span<bool> history,
145 double threshold,
146 bool edge_detected,
147 EdgeType edge_type,
148 const std::vector<double>& inputs,
149 std::span<const float> gpu_data)
150 : LogicContext(value, mode, operator_type, history, threshold, edge_detected, edge_type, inputs)
151 , GpuVectorData(gpu_data)
152 {
153 }
154
155 friend class Logic;
156
157 std::vector<float> gpu_float_buffer;
158};
159
160/**
161 * @class Logic
162 * @brief Digital signal processor implementing boolean logic operations
163 *
164 * The Logic node transforms continuous signals into discrete binary outputs
165 * using configurable boolean operations. It supports multiple computational models:
166 *
167 * - Combinational logic: Stateless evaluation based solely on current inputs
168 * - Sequential logic: State-based evaluation using history of previous inputs
169 * - Temporal logic: Time-dependent evaluation with timing constraints
170 * - Multi-input logic: Parallel evaluation of multiple input signals
171 *
172 * Applications include:
173 * - Binary signal generation
174 * - Event detection and triggering
175 * - State machine implementation
176 * - Digital pattern recognition
177 * - Signal quantization and discretization
178 * - Conditional processing chains
179 */
180class MAYAFLUX_API Logic : public Generator {
181public:
182 /**
183 * @brief Function type for stateless boolean evaluation
184 */
185 using DirectFunction = std::function<bool(double)>;
186
187 /**
188 * @brief Function type for parallel input evaluation
189 */
190 using MultiInputFunction = std::function<bool(const std::vector<double>&)>;
191
192 /**
193 * @brief Function type for state-based evaluation
194 */
195 using SequentialFunction = std::function<bool(std::span<bool>)>;
196
197 /**
198 * @brief Function type for time-dependent evaluation
199 */
200 using TemporalFunction = std::function<bool(double, double)>; // input, time
201
202 /**
203 * @brief Function type for stateless evaluation with access to the coefficient array
204 *
205 * Takes the input and the node's own coefficient array, which the function
206 * may read and write. State kept in the array survives clone() and is
207 * saved and restored with the node.
208 */
209 using CoefDirectFunction = std::function<bool(double, std::span<double>)>;
210
211 /**
212 * @brief Function type for state-based evaluation with access to the coefficient array
213 *
214 * Takes the bit history, newest first, and the node's own coefficient array.
215 */
216 using CoefSequentialFunction = std::function<bool(std::span<bool>, std::span<double>)>;
217
218 /**
219 * @brief Function type for time-dependent evaluation with access to the coefficient array
220 *
221 * Takes the input, the time in seconds and the node's own coefficient array.
222 */
223 using CoefTemporalFunction = std::function<bool(double, double, std::span<double>)>;
224
225 /**
226 * @brief Function type for parallel input evaluation with access to the coefficient array
227 *
228 * Takes one value per input slot and the node's own coefficient array.
229 */
230 using CoefMultiInputFunction = std::function<bool(const std::vector<double>&, std::span<double>)>;
231
232 /**
233 * @brief Constructs a Logic node with threshold quantization
234 * @param threshold Decision boundary for binary quantization
235 *
236 * Creates a basic binary quantizer that outputs 1.0 when input exceeds
237 * the threshold and 0.0 otherwise.
238 */
239 explicit Logic(double threshold = 0.5);
240
241 /**
242 * @brief Constructs a Logic node with a specific boolean operator
243 * @param op Boolean operator to apply
244 * @param threshold Decision boundary for binary quantization
245 *
246 * Creates a Logic node configured with one of the standard boolean
247 * operations (AND, OR, XOR, etc.) using the specified threshold
248 * for binary quantization of inputs.
249 */
250 Logic(LogicOperator op, double threshold = 0.5);
251
252 /**
253 * @brief Constructs a Logic node with a custom combinational function
254 * @param function Custom function implementing stateless boolean logic
255 *
256 * Creates a Logic node that applies a user-defined function to each input
257 * sample, enabling custom combinational logic operations beyond the
258 * standard operators.
259 */
260 explicit Logic(DirectFunction function);
261
262 /**
263 * @brief Constructs a Logic node for parallel input evaluation
264 * @param function Function implementing multi-input boolean logic
265 * @param input_count Number of parallel inputs to process
266 *
267 * Creates a Logic node that evaluates multiple inputs simultaneously,
268 * enabling implementation of complex decision functions like voting
269 * systems, majority logic, or custom multi-input boolean operations.
270 */
271 Logic(MultiInputFunction function, size_t input_count);
272
273 /**
274 * @brief Constructs a Logic node for state-based evaluation
275 * @param function Function implementing sequential boolean logic
276 * @param history_size Size of the state history buffer
277 *
278 * Creates a Logic node that maintains a history of previous states
279 * and evaluates new inputs in the context of this history. This enables
280 * implementation of sequential logic circuits, pattern detectors,
281 * and finite state machines.
282 */
283 Logic(SequentialFunction function, size_t history_size);
284
285 /**
286 * @brief Constructs a Logic node for time-dependent evaluation
287 * @param function Function implementing temporal boolean logic
288 *
289 * Creates a Logic node that evaluates inputs based on both their value
290 * and the time at which they occur. This enables implementation of
291 * timing-sensitive operations like pulse width detection, timeout
292 * monitoring, and rate-of-change analysis.
293 */
294 explicit Logic(TemporalFunction function);
295
296 /**
297 * @brief Constructs a Logic node with a stateless function and a coefficient array
298 * @param function Function receiving the input and the coefficient array
299 * @param coefficients Initial contents of the coefficient array
300 */
301 Logic(CoefDirectFunction function, std::vector<double> coefficients);
302
303 /**
304 * @brief Constructs a Logic node with a state-based function and a coefficient array
305 * @param function Function receiving the bit history and the coefficient array
306 * @param history_size Size of the state history buffer
307 * @param coefficients Initial contents of the coefficient array
308 */
309 Logic(CoefSequentialFunction function, size_t history_size, std::vector<double> coefficients = {});
310
311 /**
312 * @brief Constructs a Logic node with a time-dependent function and a coefficient array
313 * @param function Function receiving the input, the time and the coefficient array
314 * @param coefficients Initial contents of the coefficient array
315 */
316 Logic(CoefTemporalFunction function, std::vector<double> coefficients);
317
318 /**
319 * @brief Constructs a Logic node for parallel inputs with a coefficient array
320 * @param function Function receiving one value per slot and the coefficient array
321 * @param input_count Number of input slots
322 * @param coefficients Initial contents of the coefficient array
323 */
324 Logic(CoefMultiInputFunction function, size_t input_count, std::vector<double> coefficients = {});
325
326 virtual ~Logic() = default;
327
328 /**
329 * @brief An independent node with the same behaviour and fresh state
330 *
331 * Same mode, operator, thresholds, function and coefficient array as the
332 * array stands now, so a state-bearing kernel's clone continues from the
333 * current state. History, saved state and hooks are not copied. The input
334 * node, if any, is shared, and so is closure state captured by a function;
335 * the coefficient array is the state that is not.
336 *
337 * Attach one clone per channel instead of one node to several.
338 */
339 [[nodiscard]] std::shared_ptr<Logic> clone() const;
340
341 /**
342 * @brief Replaces the coefficient array
343 * @param coefficients New contents
344 *
345 * Reaches the functions that take the coefficient array. Changing the size
346 * should happen on the scheduler tick, not concurrently with processing.
347 */
348 void set_coefficients(const std::vector<double>& coefficients);
349
350 /**
351 * @brief The coefficient array as it stands now, including state written by a function
352 */
353 [[nodiscard]] const std::vector<double>& get_coefficients() const { return m_coefficients; }
354
355 /**
356 * @brief Processes a single input sample through the logic function
357 * @param input Input value to evaluate
358 * @return 1.0 for true result, 0.0 for false result
359 *
360 * Evaluates the input according to the configured logic operation
361 * and computational model, producing a binary output (0.0 or 1.0).
362 */
363 double process_sample(double input = 0.) override;
364
365 /**
366 * @brief Processes multiple samples in batch mode
367 * @param num_samples Number of samples to generate
368 * @return Vector of binary outputs (1.0 for true, 0.0 for false)
369 *
370 * Generates a sequence of binary values by repeatedly applying
371 * the configured logic operation. In stateful modes, each output
372 * depends on previous results.
373 */
374 std::vector<double> process_batch(unsigned int num_samples) override;
375
376 /**
377 * @brief Processes multiple parallel inputs
378 * @param inputs Vector of input values to evaluate together
379 * @return 1.0 for true result, 0.0 for false result
380 *
381 * Evaluates multiple inputs simultaneously according to the configured
382 * multi-input logic function, producing a single binary output.
383 */
384 double process_multi_input(const std::vector<double>& inputs);
385
386 /**
387 * @brief Resets internal state to initial conditions
388 *
389 * Clears history buffers, resets state variables, and returns
390 * the node to its initial configuration. Essential for restarting
391 * sequential processing or clearing accumulated state.
392 */
393 void reset();
394
395 /**
396 * @brief Sets the decision boundary for binary quantization
397 * @param threshold Value above which input is considered true
398 * @param create_default_direct_function Whether to create a default direct function if none is set
399 *
400 * Configures the threshold used to convert continuous input values
401 * to binary states (true/false). Critical for accurate digital
402 * interpretation of analog-like signals.
403 */
404 void set_threshold(double threshold, bool create_default_direct_function = false);
405
406 /**
407 * @brief Configures noise-resistant binary quantization with memory
408 * @param low_threshold Value below which input becomes false
409 * @param high_threshold Value above which input becomes true
410 * @param create_default_direct_function Whether to create a default direct function if none is set
411 *
412 * Implements a Schmitt trigger with separate thresholds for rising and falling
413 * transitions, preventing rapid oscillation when input hovers near the threshold.
414 * Essential for stable binary quantization of noisy signals.
415 */
416 void set_hysteresis(double low_threshold, double high_threshold, bool create_default_direct_function = false);
417
418 /**
419 * @brief Configures digital transition detection
420 * @param type Type of transition to detect (rising, falling, or both)
421 * @param threshold Decision boundary for state changes
422 *
423 * Sets up the node to detect specific types of state transitions
424 * (edges) in the input signal. Useful for event detection, trigger
425 * generation, and synchronization with external events.
426 */
427 void set_edge_detection(EdgeType type, double threshold = 0.5);
428
429 /**
430 * @brief Sets the boolean operation to perform
431 * @param op Boolean operator to apply
432 * @param create_default_direct_function Whether to create a default direct function if none is set
433 *
434 * Configures the node to use one of the standard boolean operations
435 * (AND, OR, XOR, etc.) for evaluating inputs.
436 */
437 void set_operator(LogicOperator op, bool create_default_direct_function = false);
438
439 /**
440 * @brief Sets a custom combinational logic function
441 * @param function Custom function implementing stateless boolean logic
442 *
443 * Configures the node to use a user-defined function for stateless
444 * evaluation of inputs, enabling custom combinational logic beyond
445 * the standard operators.
446 */
447 void set_direct_function(DirectFunction function);
448
449 /**
450 * @brief Sets a custom parallel input evaluation function
451 * @param function Function implementing multi-input boolean logic
452 * @param input_count Number of parallel inputs to process
453 *
454 * Configures the node to evaluate multiple inputs simultaneously
455 * using a user-defined function, enabling implementation of complex
456 * decision functions like voting systems or custom multi-input operations.
457 */
458 void set_multi_input_function(MultiInputFunction function, size_t input_count);
459
460 /**
461 * @brief Sets a parallel input function that receives the coefficient array
462 * @param function Function receiving one value per slot and the coefficient array
463 * @param input_count Number of input slots
464 */
465 void set_multi_input_function(CoefMultiInputFunction function, size_t input_count);
466
467 /**
468 * @brief Appends a node whose output feeds the next input slot
469 * @param node Node to read each sample
470 *
471 * Applies in parallel input mode. Nodes fill slots 0 to n-1 in the order
472 * they were added, growing the slot count if needed. When more slots are
473 * declared than nodes, slot n receives the sample the node is driven with,
474 * for example a buffer sample from a LogicProcessor; with no nodes that
475 * sample goes to slot 0 as before. A node already processed this cycle is
476 * read, not run again.
477 */
478 void add_input_node(const std::shared_ptr<Node>& node);
479
480 /**
481 * @brief Replaces all input nodes
482 * @param nodes Nodes for slots 0 to n-1; empty removes them
483 */
484 void set_input_nodes(std::vector<std::shared_ptr<Node>> nodes);
485
486 /**
487 * @brief Sets a custom state-based evaluation function
488 * @param function Function implementing sequential boolean logic
489 * @param history_size Size of the state history buffer
490 *
491 * Configures the node to maintain a history of previous states and
492 * evaluate new inputs in this context using a user-defined function.
493 * Enables implementation of sequential logic, pattern detectors, and
494 * finite state machines.
495 */
496 void set_sequential_function(SequentialFunction function, size_t history_size);
497
498 /**
499 * @brief Sets a custom time-dependent evaluation function
500 * @param function Function implementing temporal boolean logic
501 *
502 * Configures the node to evaluate inputs based on both their value
503 * and timing using a user-defined function. Enables implementation of
504 * timing-sensitive operations like pulse width detection and rate analysis.
505 */
506 void set_temporal_function(TemporalFunction function);
507
508 /**
509 * @brief Sets a stateless function that receives the coefficient array
510 * @param function Function receiving the input and the coefficient array
511 */
512 void set_direct_function(CoefDirectFunction function);
513
514 /**
515 * @brief Sets a state-based function that receives the coefficient array
516 * @param function Function receiving the bit history and the coefficient array
517 * @param history_size Size of the state history buffer
518 */
519 void set_sequential_function(CoefSequentialFunction function, size_t history_size);
520
521 /**
522 * @brief Sets a time-dependent function that receives the coefficient array
523 * @param function Function receiving the input, the time and the coefficient array
524 */
525 void set_temporal_function(CoefTemporalFunction function);
526
527 /**
528 * @brief Preloads the state history buffer
529 * @param initial_values Vector of initial boolean states
530 *
531 * Initializes the history buffer with specified values, allowing
532 * sequential logic to begin operation with a predefined state sequence.
533 * Useful for testing specific patterns or starting from known states.
534 */
535 void set_initial_conditions(const std::vector<bool>& initial_values);
536
537 /**
538 * @brief Sets the input node to generate logic values from
539 * @param input_node Node providing the input values
540 *
541 * Configures the node to receive input from another node
542 */
543 inline void set_input_node(const std::shared_ptr<Node>& input_node) { m_input_node = input_node; }
544
545 /**
546 * @brief Gets the current computational model
547 * @return Current logic mode
548 */
549 [[nodiscard]] LogicMode get_mode() const { return m_mode; }
550
551 /**
552 * @brief Gets the current boolean operator
553 * @return Current logic operator
554 */
555 [[nodiscard]] LogicOperator get_operator() const { return m_operator; }
556
557 /**
558 * @brief Gets the decision boundary for binary quantization
559 * @return Current threshold value
560 */
561 [[nodiscard]] double get_threshold() const { return m_threshold; }
562
563 /**
564 * @brief Gets the state history buffer capacity
565 * @return Current history buffer size
566 */
567 [[nodiscard]] size_t get_history_size() const { return m_history_size; }
568
569 /**
570 * @brief Gets the current state history
571 * @return Reference to the history buffer
572 */
573 std::span<bool> get_history();
574
575 /**
576 * @brief Gets the number of parallel inputs expected
577 * @return Number of expected inputs
578 */
579 [[nodiscard]] size_t get_input_count() const { return m_input_count; }
580
581 /**
582 * @brief Checks if a state transition was detected
583 * @return True if a transition matching the configured edge type was detected
584 */
585 [[nodiscard]] bool was_edge_detected() const { return m_edge_detected; }
586
587 /**
588 * @brief Gets the type of transitions being monitored
589 * @return Current edge detection type
590 */
591 [[nodiscard]] EdgeType get_edge_type() const { return m_edge_type; }
592
593 /**
594 * @brief Registers a callback for every generated sample
595 * @param callback Function to call when a new sample is generated
596 */
598
599 /**
600 * @brief Registers a conditional callback for generated samples
601 * @param callback Function to call when condition is met
602 * @param condition Predicate that determines when callback is triggered
603 */
604 HookId on_tick_if(const NodeCondition& condition, const TypedHook<LogicContext>& callback);
605
606 /**
607 * @brief Registers a callback that executes continuously while output is true
608 * @param callback Function to call on each tick when output is true (1.0)
609 */
610 HookId while_true(const TypedHook<LogicContext>& callback);
611
612 /**
613 * @brief Registers a callback that executes continuously while output is false
614 * @param callback Function to call on each tick when output is false (0.0)
615 */
616 HookId while_false(const TypedHook<LogicContext>& callback);
617
618 /**
619 * @brief Registers a callback for when output changes to a specific state
620 * @param target_state The state to detect (true for 1.0, false for 0.0)
621 * @param callback Function to call when state changes to target_state
622 */
623 HookId on_change_to(bool target_state, const TypedHook<LogicContext>& callback);
624
625 /**
626 * @brief Registers a callback for any state change (true↔false)
627 * @param callback Function to call when output changes state
628 */
629 HookId on_change(const TypedHook<LogicContext>& callback);
630
631 /**
632 * @brief Removes a previously registered callback
633 * @param callback The callback function to remove
634 * @return True if the callback was found and removed, false otherwise
635 */
636 bool remove_hook(const TypedHook<LogicContext>& callback);
637
638 /**
639 * @brief Removes a previously registered conditional callback
640 * @param callback The condition function to remove
641 * @return True if the callback was found and removed, false otherwise
642 */
643 bool remove_conditional_hook(const NodeCondition& callback) override;
644
645 void remove_hooks_of_type(LogicEventType type);
646
647 void save_state() override;
648 void restore_state() override;
649
650 /**
651 * @brief Retrieves the last created context object
652 * @return Reference to the last LogicContext object
653 *
654 * This method provides access to the most recent LogicContext object
655 * created by the logic node. This context contains information about
656 * the node's state at the time of the last output generation.
657 */
658 NodeContext& get_last_context() override;
659
660 void set_gpu_compatible(bool compatible) override
661 {
662 Node::set_gpu_compatible(compatible);
663 if (compatible) {
664 m_node_capability |= NodeCapability::VECTOR;
665 } else {
666 m_node_capability &= ~NodeCapability::VECTOR;
667 }
668 }
669
670 /**
671 * @brief Retrieves the current modulators connected to this node
672 * @return Vector of pairs containing the modulator role and the corresponding node
673 */
674 [[nodiscard]] std::vector<std::pair<ModulatorRole, std::shared_ptr<Node>>> get_modulators() const override;
675
676protected:
677 /**
678 * @brief Updates the context with the latest sample value
679 * @param value The current generated sample
680 */
681 void update_context(double value) override;
682
683 /**
684 * @brief Notifies all registered callbacks about a new sample
685 * @param value The newly generated sample
686 *
687 * This method is called internally whenever a new sample is generated,
688 * creating the appropriate context and invoking all registered callbacks
689 * that should receive notification about this sample.
690 */
691 void notify_tick(double value) override;
692
693private:
694 LogicMode m_mode; ///< Current processing mode
695 LogicOperator m_operator; ///< Current logic operator
696 DirectFunction m_direct_function; ///< Function for direct mode
697 MultiInputFunction m_multi_input_function; ///< Function for recursive/feedforward mode
698 SequentialFunction m_sequential_function; ///< Function for sequential mode
699 TemporalFunction m_temporal_function; ///< Function for temporal mode
700 size_t m_history_head {}; ///< Head index for the history ring buffer
701 size_t m_history_count {}; ///< Number of valid entries in the history buffer
702 size_t m_history_size; ///< Maximum size of the history buffer
703 size_t m_input_count; ///< Expected number of inputs for multi-input mode
704 double m_threshold; ///< Threshold for boolean conversion
705 double m_low_threshold; ///< Low threshold for hysteresis
706 double m_high_threshold; ///< High threshold for hysteresis
707 EdgeType m_edge_type; ///< Type of edge to detect
708 bool m_edge_detected {}; ///< Whether an edge was detected in the last processing
709 bool m_hysteresis_state {}; ///< State for hysteresis operator
710 double m_temporal_time {}; ///< Time tracking for temporal mode
711 double m_input {}; ///< Current input value for multi-input mode
712 std::vector<double> m_input_buffer; // Buffer for multi-input mode
713 std::shared_ptr<Node> m_input_node; ///< Input node for processing
714 std::vector<std::shared_ptr<Node>> m_input_nodes; ///< Nodes feeding the input slots in parallel input mode
715 CoefMultiInputFunction m_coef_multi_function; ///< The function behind m_multi_input_function while bound
716 std::vector<uint8_t> m_history_ring; ///< Ring buffer for history storage
717 std::vector<uint8_t> m_history_linear; ///< Linear view of history for easy access
718 std::vector<double> m_coefficients; ///< Coefficient array handed to coefficient-aware functions
719 std::vector<double> m_saved_coefficients; ///< Saved coefficient array, used when a coefficient function is bound
720 CoefDirectFunction m_coef_direct_function; ///< The function behind m_direct_function while bound
721 CoefSequentialFunction m_coef_sequential_function; ///< The function behind m_sequential_function while bound
722 CoefTemporalFunction m_coef_temporal_function; ///< The function behind m_temporal_function while bound
723 bool m_coef_bound {}; ///< True while the active mode runs a coefficient function
724 bool m_default_multi_input {}; ///< True while the parallel function is the built in all-above-threshold one
725
726 // Helper method for multi-input mode
727 void add_input(double input, size_t index);
728
729 void pull_input_nodes();
730 void release_input_nodes();
731
732 MultiInputFunction default_multi_input_function();
733
734 /**
735 * @brief Adds a callback to the list of all callbacks
736 * @param callback The callback function to add
737 * @param type The type of event to trigger the callback
738 * @param condition Optional condition for conditional callbacks
739 */
740 HookId add_callback(const TypedHook<LogicContext>& callback, LogicEventType type, const std::optional<NodeCondition>& condition = std::nullopt)
741 {
742 if (type == LogicEventType::TICK) {
743 return m_callbacks.add(adapt_hook(callback), callback.target_type());
744 }
745 if (type == LogicEventType::CONDITIONAL && condition) {
746 return m_conditional_callbacks.add_conditional(adapt_hook(callback), *condition, callback.target_type());
747 }
748 return m_all_callbacks.add(adapt_hook(callback), callback.target_type(), static_cast<uint8_t>(type));
749 }
750
751 void history_push(bool val);
752
753 std::span<bool> history_linearized_view();
754
755 std::span<double> external_context_view(double input);
756
757 /**
758 * @brief Event-specific callbacks, tagged with their LogicEventType
759 *
760 * Tick and conditional hooks live in the base lists, so they are shared with Node::on_tick.
761 */
762 HookList m_all_callbacks { *this };
763
764 std::vector<uint8_t> m_saved_history_ring;
765 size_t m_saved_history_head {};
766 size_t m_saved_history_count {};
767
768 bool m_saved_hysteresis_state {};
769 bool m_saved_edge_detected {};
770 double m_saved_temporal_time {};
771 double m_saved_last_output {};
774};
775
776} // namespace MayaFlux::Nodes::Generator
Core::GlobalInputConfig input
Definition Config.cpp:42
PickCallback callback
Definition Picker.cpp:22
uint32_t mode
glm::vec3 value
vk::PhysicalDeviceType type
Definition VKDevice.cpp:126
uint32_t index
Definition VKDevice.cpp:122
float threshold
Base class for all signal and pattern generators in Maya Flux.
LogicContextGpu(double value, LogicMode mode, LogicOperator operator_type, std::span< bool > history, double threshold, bool edge_detected, EdgeType edge_type, const std::vector< double > &inputs, std::span< const float > gpu_data)
Definition Logic.hpp:140
GPU-accelerated context for logic node callbacks.
Definition Logic.hpp:138
std::span< bool > get_history() const
Definition Logic.hpp:96
std::span< bool > m_history
History of boolean states.
Definition Logic.hpp:121
const std::vector< double > & get_coefficients() const
The node's coefficient array as it stands at this tick.
Definition Logic.hpp:108
LogicContext(double value, LogicMode mode, LogicOperator operator_type, std::span< bool > history, double threshold, bool edge_detected=false, EdgeType edge_type=EdgeType::BOTH, const std::vector< double > &inputs={})
Constructs a LogicContext with complete state information.
Definition Logic.hpp:73
LogicMode m_mode
Current computational model.
Definition Logic.hpp:119
LogicOperator m_operator
Current boolean operator.
Definition Logic.hpp:120
const std::vector< double > & m_inputs
Current input values (for multi-input mode)
Definition Logic.hpp:125
double m_input
Current input value for multi-input mode.
Definition Logic.hpp:126
const std::vector< double > & get_inputs() const
Definition Logic.hpp:100
EdgeType m_edge_type
Type of transition being monitored.
Definition Logic.hpp:124
bool m_edge_detected
Whether a state transition was detected.
Definition Logic.hpp:123
const double & get_value() const
Definition Logic.hpp:113
LogicOperator get_operator() const
Definition Logic.hpp:95
double m_threshold
Decision boundary for binary quantization.
Definition Logic.hpp:122
SequentialFunction m_sequential_function
Function for sequential mode.
Definition Logic.hpp:698
const std::vector< double > & get_coefficients() const
The coefficient array as it stands now, including state written by a function.
Definition Logic.hpp:353
TemporalFunction m_temporal_function
Function for temporal mode.
Definition Logic.hpp:699
std::vector< uint8_t > m_saved_history_ring
Definition Logic.hpp:764
DirectFunction m_direct_function
Function for direct mode.
Definition Logic.hpp:696
CoefSequentialFunction m_coef_sequential_function
The function behind m_sequential_function while bound.
Definition Logic.hpp:721
CoefDirectFunction m_coef_direct_function
The function behind m_direct_function while bound.
Definition Logic.hpp:720
bool was_edge_detected() const
Checks if a state transition was detected.
Definition Logic.hpp:585
std::vector< uint8_t > m_history_linear
Linear view of history for easy access.
Definition Logic.hpp:717
std::vector< std::shared_ptr< Node > > m_input_nodes
Nodes feeding the input slots in parallel input mode.
Definition Logic.hpp:714
size_t m_history_size
Maximum size of the history buffer.
Definition Logic.hpp:702
EdgeType m_edge_type
Type of edge to detect.
Definition Logic.hpp:707
std::function< bool(std::span< bool >, std::span< double >)> CoefSequentialFunction
Function type for state-based evaluation with access to the coefficient array.
Definition Logic.hpp:216
void set_input_node(const std::shared_ptr< Node > &input_node)
Sets the input node to generate logic values from.
Definition Logic.hpp:543
double m_threshold
Threshold for boolean conversion.
Definition Logic.hpp:704
std::function< bool(double, std::span< double >)> CoefDirectFunction
Function type for stateless evaluation with access to the coefficient array.
Definition Logic.hpp:209
std::function< bool(double)> DirectFunction
Function type for stateless boolean evaluation.
Definition Logic.hpp:185
double m_high_threshold
High threshold for hysteresis.
Definition Logic.hpp:706
CoefTemporalFunction m_coef_temporal_function
The function behind m_temporal_function while bound.
Definition Logic.hpp:722
std::vector< double > m_input_buffer
Definition Logic.hpp:712
std::vector< double > m_coefficients
Coefficient array handed to coefficient-aware functions.
Definition Logic.hpp:718
std::shared_ptr< Node > m_input_node
Input node for processing.
Definition Logic.hpp:713
LogicMode get_mode() const
Gets the current computational model.
Definition Logic.hpp:549
std::span< double > external_context_view(double input)
LogicOperator m_operator
Current logic operator.
Definition Logic.hpp:695
std::function< bool(const std::vector< double > &)> MultiInputFunction
Function type for parallel input evaluation.
Definition Logic.hpp:190
std::function< bool(const std::vector< double > &, std::span< double >)> CoefMultiInputFunction
Function type for parallel input evaluation with access to the coefficient array.
Definition Logic.hpp:230
double m_low_threshold
Low threshold for hysteresis.
Definition Logic.hpp:705
MultiInputFunction m_multi_input_function
Function for recursive/feedforward mode.
Definition Logic.hpp:697
std::function< bool(std::span< bool >)> SequentialFunction
Function type for state-based evaluation.
Definition Logic.hpp:195
std::vector< uint8_t > m_history_ring
Ring buffer for history storage.
Definition Logic.hpp:716
std::function< bool(double, double, std::span< double >)> CoefTemporalFunction
Function type for time-dependent evaluation with access to the coefficient array.
Definition Logic.hpp:223
double get_threshold() const
Gets the decision boundary for binary quantization.
Definition Logic.hpp:561
EdgeType get_edge_type() const
Gets the type of transitions being monitored.
Definition Logic.hpp:591
size_t get_input_count() const
Gets the number of parallel inputs expected.
Definition Logic.hpp:579
void set_gpu_compatible(bool compatible) override
Sets whether the node is compatible with GPU processing.
Definition Logic.hpp:660
LogicOperator get_operator() const
Gets the current boolean operator.
Definition Logic.hpp:555
CoefMultiInputFunction m_coef_multi_function
The function behind m_multi_input_function while bound.
Definition Logic.hpp:715
LogicMode m_mode
Current processing mode.
Definition Logic.hpp:694
std::function< bool(double, double)> TemporalFunction
Function type for time-dependent evaluation.
Definition Logic.hpp:200
std::vector< double > m_saved_coefficients
Saved coefficient array, used when a coefficient function is bound.
Definition Logic.hpp:719
size_t get_history_size() const
Gets the state history buffer capacity.
Definition Logic.hpp:567
HookId add_callback(const TypedHook< LogicContext > &callback, LogicEventType type, const std::optional< NodeCondition > &condition=std::nullopt)
Adds a callback to the list of all callbacks.
Definition Logic.hpp:740
size_t m_input_count
Expected number of inputs for multi-input mode.
Definition Logic.hpp:703
Digital signal processor implementing boolean logic operations.
Definition Logic.hpp:180
GPU-uploadable 1D array data interface.
Stores, fires and clears the hooks of one node channel.
Definition NodeUtils.hpp:93
Base context class for node callbacks.
Definition Node.hpp:53
EdgeType
Digital transition patterns to detect.
Definition Logic.hpp:40
@ FALLING
High-to-low transition (1→0)
@ RISING
Low-to-high transition (0→1)
LogicMode
Defines the computational model for digital signal evaluation.
Definition Logic.hpp:11
@ SEQUENTIAL
State-based evaluation using history of inputs (sequential logic)
@ DIRECT
Stateless evaluation of current input only (combinational logic)
@ TEMPORAL
Time-dependent evaluation with timing constraints.
@ MULTI_INPUT
Parallel evaluation of multiple input signals.
LogicEventType
Events that can trigger callbacks.
Definition Logic.hpp:50
LogicOperator
Digital operators for boolean computation.
Definition Logic.hpp:22
@ NOT
Logical NOT - inverts the input.
@ NOR
Logical NOR - inverted OR operation.
@ OR
Logical OR - true when any input is true.
@ IMPLIES
Logical implication - false only when A is true and B is false.
@ NAND
Logical NAND - inverted AND operation.
@ THRESHOLD
Binary quantization - true when input exceeds threshold.
@ AND
Logical AND - true only when all inputs are true.
@ EDGE
Transition detector - identifies state changes.
@ HYSTERESIS
Threshold with memory - prevents rapid oscillation at boundary.
@ CUSTOM
User-defined boolean function.
@ XOR
Logical XOR - true when odd number of inputs are true.
uint64_t HookId
Identifies one registration inside a HookList.
Definition NodeUtils.hpp:60
NodeCapability
Bitmask flags declaring what data shapes a node's context can produce.
Definition NodeSpec.hpp:109
std::function< void(ContextT &)> TypedHook
Callback function type for node processing events, parameterised on context type.
Definition NodeUtils.hpp:28
std::function< bool(NodeContext &)> NodeCondition
Predicate function type for conditional callbacks.
Definition NodeUtils.hpp:54
NodeHook adapt_hook(const TypedHook< ContextT > &hook)
Wraps a context-typed hook into a NodeHook.