MayaFlux 0.4.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
SignalSourceContainer.hpp
Go to the documentation of this file.
1#pragma once
2
5
6namespace MayaFlux::Kakshya {
7
8class DataProcessor;
9class DataProcessingChain;
10class DataAccess;
11
12/**
13 * @enum ProcessingState
14 * @brief Represents the current processing lifecycle state of a container
15 *
16 * ProcessingState tracks a container's position in the data processing lifecycle,
17 * enabling coordinated processing across components and optimizing resource usage.
18 * This state-based approach allows the system to make intelligent decisions about
19 * when to process data and how to handle dependencies between components.
20 *
21 * The state transitions typically follow this sequence:
22 * 1. IDLE → READY (when data is loaded/prepared)
23 * 2. READY → PROCESSING (when processing begins)
24 * 3. PROCESSING → PROCESSED (when processing completes)
25 * 4. PROCESSED → READY (when new processing is needed)
26 * 5. Any state → NEEDS_REMOVAL (when container should be removed)
27 *
28 * Components can register for state change notifications to coordinate their
29 * activities with the container's lifecycle, enabling efficient resource
30 * management and processing optimization.
31 */
32enum class ProcessingState : uint8_t {
33 /**
34 * Container is inactive with no data or not ready for processing.
35 * Typically the initial state or when a container is reset.
36 */
37 IDLE,
38
39 /**
40 * Container has data loaded and is ready for processing.
41 * Processing can begin when resources are available.
42 */
43 READY,
44
45 /**
46 * Container is actively being processed.
47 * Other components should avoid modifying the data during this state.
48 */
50
51 /**
52 * Container has completed processing and results are available.
53 * Data can be consumed by downstream components.
54 */
56
57 /**
58 * Container is marked for removal from the system.
59 * Resources should be released and references cleared.
60 */
62
63 /**
64 * Container is in an error state and cannot proceed.
65 * Typically requires external intervention to resolve.
66 */
67 ERROR
68};
69
70/**
71 * @class SignalSourceContainer
72 * @brief Data-driven interface for managing arbitrary processable signal sources.
73 *
74 * SignalSourceContainer provides a flexible, extensible abstraction for handling any data source
75 * that can be interpreted and processed as an audio signal or multi-dimensional stream. Unlike
76 * AudioBuffer, which is specialized for direct audio sample storage, this container is designed
77 * for digital-first workflows and can manage:
78 * - Audio files of any format or structure
79 * - Network or streaming sources
80 * - External buffers from other applications or devices
81 * - Algorithmically generated or procedurally synthesized data
82 * - Any data source larger than or structurally different from AudioBuffer
83 *
84 * The container maintains its own processing state and lifecycle, decoupled from the engine's
85 * BufferManager, enabling asynchronous, scheduled, or on-demand processing. It acts as a bridge
86 * between raw, heterogeneous data sources and the Maya Flux processing system, using DataProcessor
87 * objects to transform and organize data into processable, channel-oriented forms.
88 *
89 * Key features:
90 * - Explicit, observable processing state for robust orchestration and resource management
91 * - Support for registering state change callbacks for event-driven workflows
92 * - Pluggable processing chains and processors for custom or default data transformation
93 * - Fine-grained reader/consumer tracking for safe, concurrent, and efficient access
94 * - Designed for composability with digital-first nodes, routines, and buffer systems
95 * - Enables data-driven, non-analog-centric development and integration of new data modalities
96 *
97 * This interface is foundational for advanced, data-driven workflows in Maya Flux, supporting
98 * real-time streaming, offline analysis, hybrid computation, and seamless integration of
99 * unconventional or future-facing signal sources.
100 */
101class MAYAFLUX_API SignalSourceContainer : public NDDataContainer, public std::enable_shared_from_this<SignalSourceContainer> {
102public:
103 ~SignalSourceContainer() override = default;
104
105 /**
106 * @brief Get the current processing state of the container.
107 * @return Current ProcessingState (IDLE, READY, PROCESSING, etc.)
108 *
109 * Enables orchestration and coordination of processing across the system.
110 */
112
113 /**
114 * @brief Update the processing state of the container.
115 * @param new_state New ProcessingState to set
116 *
117 * May trigger registered state change callbacks for event-driven workflows.
118 */
119 virtual void update_processing_state(ProcessingState new_state) = 0;
120
121 /**
122 * @brief Register a callback to be invoked on processing state changes.
123 * @param callback Function to call when state changes (receives container and new state)
124 *
125 * Enables external components to react to lifecycle transitions for orchestration,
126 * resource management, or UI updates.
127 */
129 std::function<void(const std::shared_ptr<SignalSourceContainer>&, ProcessingState)> callback)
130 = 0;
131
132 /**
133 * @brief Unregister the state change callback, if any.
134 */
136
137 /**
138 * @brief Check if the container is ready for processing.
139 * @return true if ready to process, false otherwise
140 *
141 * Used for scheduling and dependency resolution in data-driven pipelines.
142 */
143 virtual bool is_ready_for_processing() const = 0;
144
145 /**
146 * @brief Mark the container as ready or not ready for processing.
147 * @param ready true to mark as ready, false otherwise
148 */
149 virtual void mark_ready_for_processing(bool ready) = 0;
150
151 /**
152 * @brief Create and configure a default processor for this container.
153 *
154 * Instantiates a standard DataProcessor to handle basic processing needs,
155 * such as channel organization or format conversion. Called during initialization
156 * if no custom processor is provided.
157 */
158 virtual void create_default_processor() = 0;
159
160 /**
161 * @brief Process the container's data using the default processor.
162 *
163 * Executes the default processing chain, transforming raw data into a
164 * processable form. This is a convenience wrapper for standard workflows.
165 */
166 virtual void process_default() = 0;
167
168 /**
169 * @brief Set the default data processor for this container.
170 * @param processor Shared pointer to the DataProcessor to use
171 */
172 virtual void set_default_processor(const std::shared_ptr<DataProcessor>& processor) = 0;
173
174 /**
175 * @brief Get the current default data processor.
176 * @return Shared pointer to the current DataProcessor, or nullptr if none
177 */
178 virtual std::shared_ptr<DataProcessor> get_default_processor() const = 0;
179
180 /**
181 * @brief Get the current processing chain for this container.
182 * @return Shared pointer to the DataProcessingChain, or nullptr if none
183 */
184 virtual std::shared_ptr<DataProcessingChain> get_processing_chain() = 0;
185
186 /**
187 * @brief Set the processing chain for this container.
188 * @param chain Shared pointer to the DataProcessingChain to use
189 */
190 virtual void set_processing_chain(const std::shared_ptr<DataProcessingChain>& chain) = 0;
191
192 /**
193 * @brief Register a reader for a specific dimension.
194 * @param dimension_index Index of the dimension being read
195 * @return Reader ID for the registered dimension
196 *
197 * Used for tracking active readers in multi-threaded or streaming scenarios,
198 * enabling safe concurrent access and efficient resource management.
199 */
200 virtual uint32_t register_dimension_reader(uint32_t dimension_index) = 0;
201
202 /**
203 * @brief Unregister a reader for a specific dimension.
204 * @param dimension_index Index of the dimension no longer being read
205 */
206 virtual void unregister_dimension_reader(uint32_t dimension_index) = 0;
207
208 /**
209 * @brief Check if any dimensions currently have active readers.
210 * @return true if any dimension is being read, false otherwise
211 */
212 virtual bool has_active_readers() const = 0;
213
214 /**
215 * @brief Mark a dimension as consumed for the current processing cycle.
216 * @param dimension_index Index of the dimension that was processed
217 * @param reader_id Reader ID for the dimension
218 */
219 virtual void mark_dimension_consumed(uint32_t dimension_index, uint32_t reader_id) = 0;
220
221 /**
222 * @brief Check if all active dimensions have been consumed in this cycle.
223 * @return true if all active dimensions have been processed
224 */
225 virtual bool all_dimensions_consumed() const = 0;
226
227 // ===== Processed Data Access =====
228
229 /**
230 * @brief Get a mutable reference to the processed data buffer.
231 * @return Reference to the processed DataVariant vector
232 *
233 * The structure and type of this data is implementation-specific and may
234 * depend on the processing chain or data source.
235 */
236 virtual std::vector<DataVariant>& get_processed_data() = 0;
237
238 /**
239 * @brief Get a const reference to the processed data buffer.
240 * @return Const reference to the processed DataVariant
241 */
242 virtual const std::vector<DataVariant>& get_processed_data() const = 0;
243
244 /** @brief Get a reference to the raw data stored in the container.
245 * @return Const reference to the vector of DataVariant representing raw data
246 *
247 * This provides access to the unprocessed, original data source managed by the container.
248 */
249 virtual const std::vector<DataVariant>& get_data() = 0;
250
251 // ===== Buffer Integration =====
252
253 /**
254 * @brief Mark associated buffers for processing in the next cycle.
255 * @param should_process true to enable processing, false to disable
256 *
257 * Used to coordinate buffer state with the container's processing lifecycle,
258 * ensuring that buffers are processed only when needed in data-driven flows.
259 */
260 virtual void mark_buffers_for_processing(bool should_process) = 0;
261
262 /**
263 * @brief Mark associated buffers for removal from the system.
264 *
265 * Signals that buffers should be released and references cleared, supporting
266 * efficient resource management in dynamic, digital-first workflows.
267 */
268 virtual void mark_buffers_for_removal() = 0;
269
270 /**
271 * @brief Get channel data with semantic interpretation
272 * @param channel Channel index
273 * @return Type-erased data accessor
274 */
275 virtual DataAccess channel_data(size_t channel_index) = 0;
276
277 /**
278 * @brief Get all channel data as accessors
279 */
280 virtual std::vector<DataAccess> all_channel_data() = 0;
281};
282
283}
Type-erased accessor for NDData with semantic view construction.
Abstract interface for N-dimensional data containers.
virtual std::vector< DataAccess > all_channel_data()=0
Get all channel data as accessors.
virtual void process_default()=0
Process the container's data using the default processor.
virtual bool has_active_readers() const =0
Check if any dimensions currently have active readers.
virtual void mark_dimension_consumed(uint32_t dimension_index, uint32_t reader_id)=0
Mark a dimension as consumed for the current processing cycle.
virtual void mark_buffers_for_processing(bool should_process)=0
Mark associated buffers for processing in the next cycle.
virtual std::shared_ptr< DataProcessor > get_default_processor() const =0
Get the current default data processor.
virtual void update_processing_state(ProcessingState new_state)=0
Update the processing state of the container.
virtual void unregister_state_change_callback()=0
Unregister the state change callback, if any.
virtual std::vector< DataVariant > & get_processed_data()=0
Get a mutable reference to the processed data buffer.
virtual ProcessingState get_processing_state() const =0
Get the current processing state of the container.
virtual void mark_buffers_for_removal()=0
Mark associated buffers for removal from the system.
virtual void set_processing_chain(const std::shared_ptr< DataProcessingChain > &chain)=0
Set the processing chain for this container.
virtual void unregister_dimension_reader(uint32_t dimension_index)=0
Unregister a reader for a specific dimension.
virtual bool all_dimensions_consumed() const =0
Check if all active dimensions have been consumed in this cycle.
virtual void set_default_processor(const std::shared_ptr< DataProcessor > &processor)=0
Set the default data processor for this container.
virtual uint32_t register_dimension_reader(uint32_t dimension_index)=0
Register a reader for a specific dimension.
virtual void register_state_change_callback(std::function< void(const std::shared_ptr< SignalSourceContainer > &, ProcessingState)> callback)=0
Register a callback to be invoked on processing state changes.
virtual std::shared_ptr< DataProcessingChain > get_processing_chain()=0
Get the current processing chain for this container.
virtual bool is_ready_for_processing() const =0
Check if the container is ready for processing.
virtual const std::vector< DataVariant > & get_processed_data() const =0
Get a const reference to the processed data buffer.
virtual void create_default_processor()=0
Create and configure a default processor for this container.
virtual DataAccess channel_data(size_t channel_index)=0
Get channel data with semantic interpretation.
virtual const std::vector< DataVariant > & get_data()=0
Get a reference to the raw data stored in the container.
virtual void mark_ready_for_processing(bool ready)=0
Mark the container as ready or not ready for processing.
Data-driven interface for managing arbitrary processable signal sources.
ProcessingState
Represents the current processing lifecycle state of a container.
@ NEEDS_REMOVAL
Container is marked for removal from the system.
@ ERROR
Container is in an error state and cannot proceed.
@ PROCESSING
Container is actively being processed.
@ PROCESSED
Container has completed processing and results are available.
@ READY
Ready for processing.
@ IDLE
Not being processed.