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