MayaFlux 0.1.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
Buffer.hpp
Go to the documentation of this file.
1#pragma once
2
3namespace MayaFlux::Buffers {
4
5class BufferProcessor;
6class BufferProcessingChain;
7
8/**
9 * @class Buffer
10 * @brief Backend-agnostic interface for sequential data storage and transformation
11 *
12 * Buffer provides a unified interface for all buffer types in the MayaFlux engine,
13 * supporting multiple data types and processing backends. Buffers store sequential
14 * data samples and provide mechanisms for transforming that data through attached
15 * processors. Unlike nodes which operate on individual values, buffers process
16 * blocks of data, enabling efficient batch operations and transformations.
17 *
18 * The Buffer interface is designed to be backend-agnostic and data-type agnostic,
19 * allowing for concrete implementations like AudioBuffer, VideoBuffer, TextureBuffer,
20 * and other specialized buffer types. This mirrors the processing token architecture
21 * used in the node system, where different backends handle different types of data
22 * processing.
23 *
24 * Buffers can:
25 * - Store and provide access to sequential data of various types (audio, video, texture, etc.)
26 * - Be transformed by one or more BufferProcessor objects
27 * - Be arranged in processing networks via BufferProcessingChain
28 * - Bridge between continuous (node) and discrete (buffer) computational domains
29 * - Support different processing backends through concrete implementations
30 *
31 * The buffer system complements the node system by providing block-based processing
32 * capabilities, which are more efficient for certain operations and essential for
33 * interfacing with hardware and external systems that operate on data blocks.
34 * Different buffer types can be managed centrally while maintaining type-specific
35 * processing capabilities through their concrete implementations.
36 */
37class MAYAFLUX_API Buffer : public std::enable_shared_from_this<Buffer> {
38public:
39 /**
40 * @brief Virtual destructor for proper resource management
41 *
42 * Ensures proper cleanup of resources in derived buffer implementations
43 * across different data types and processing backends.
44 */
45 virtual ~Buffer() = default;
46
47 /**
48 * @brief Resets all data values in the buffer
49 *
50 * Initializes all data elements to their default/zero state without
51 * changing the buffer capacity. The specific behavior depends on the
52 * concrete buffer implementation and data type.
53 */
54 virtual void clear() = 0;
55
56 /**
57 * @brief Applies the default transformation to the buffer's data
58 *
59 * Executes the default processing algorithm on the buffer's data.
60 * The specific transformation depends on the buffer type, data format,
61 * and its configured default processor. This enables backend-specific
62 * default processing while maintaining a unified interface.
63 */
64 virtual void process_default() = 0;
65
66 /**
67 * @brief Sets the default transformation processor for this buffer
68 * @param processor Processor to use as default transformation
69 *
70 * The default processor is used when process_default() is called.
71 * Different buffer types may accept different processor types depending
72 * on their data format and processing requirements.
73 */
74 virtual void set_default_processor(std::shared_ptr<BufferProcessor> processor) = 0;
75
76 /**
77 * @brief Gets the current default transformation processor
78 * @return Shared pointer to the default processor, or nullptr if none set
79 *
80 * Returns the processor that will be used for default transformations.
81 * The specific processor type depends on the concrete buffer implementation.
82 */
83 virtual std::shared_ptr<BufferProcessor> get_default_processor() const = 0;
84
85 /**
86 * @brief Gets the transformation chain attached to this buffer
87 * @return Shared pointer to the buffer processing chain
88 *
89 * The processing chain contains multiple transformations that are
90 * applied in sequence when the buffer is processed. Chain composition
91 * may vary based on the buffer type and backend capabilities.
92 */
93 virtual std::shared_ptr<BufferProcessingChain> get_processing_chain() = 0;
94
95 /**
96 * @brief Sets the transformation chain for this buffer
97 * @param chain New processing chain for sequential transformations
98 * @param force If true, forces the replacement of the current chain even if incompatible
99 *
100 * Replaces the current processing chain with the provided one if force is true.
101 * else merges the new chain only if compatible.
102 * The chain should be compatible with the buffer's data type and
103 * processing backend.
104 */
105 virtual void set_processing_chain(std::shared_ptr<BufferProcessingChain> chain, bool force = false) = 0;
106
107 /**
108 * @brief Checks if the buffer has data for the current processing cycle
109 * @return True if the buffer has data available for processing, false otherwise
110 *
111 * This method is particularly relevant for dynamic buffer management systems
112 * like SignalSourceContainers, where buffers may not always contain valid data.
113 * The interpretation and behavior may vary based on the buffer type:
114 * - Audio buffers typically return true unless specifically marked otherwise
115 * - Video buffers may return false if no frame is available
116 * - Texture buffers may return false if textures are not loaded
117 */
118 virtual bool has_data_for_cycle() const = 0;
119
120 /**
121 * @brief Checks if the buffer should be removed from processing chains
122 * @return True if the buffer should be removed, false otherwise
123 *
124 * This method enables dynamic buffer lifecycle management. Different buffer
125 * types may have different removal criteria:
126 * - Audio buffers typically return false unless explicitly marked for removal
127 * - Video buffers may return true when a stream ends
128 * - Texture buffers may return true when resources are freed
129 */
130 virtual bool needs_removal() const = 0;
131
132 /**
133 * @brief Marks the buffer's data availability for the current processing cycle
134 * @param has_data True if the buffer has valid data to process, false otherwise
135 *
136 * This method allows external systems to control whether the buffer should
137 * be considered for processing in the current cycle. Behavior varies by buffer type:
138 * - Audio buffers are typically always marked as having data
139 * - Video buffers may be marked based on frame availability
140 * - Texture buffers may be marked based on resource loading state
141 */
142 virtual void mark_for_processing(bool has_data) = 0;
143
144 /**
145 * @brief Marks the buffer for removal from processing chains
146 *
147 * Sets the buffer's removal flag, indicating it should be removed from
148 * any processing chains or management systems. The specific removal behavior
149 * depends on the buffer type and the systems managing it:
150 * - Audio buffers rarely need removal unless explicitly requested
151 * - Video buffers may be removed when streams end or switch
152 * - Texture buffers may be removed when resources are deallocated
153 */
154 virtual void mark_for_removal() = 0;
155
156 /**
157 * @brief Controls whether the buffer should use default processing
158 * @param should_process True if default processing should be applied, false otherwise
159 *
160 * This method allows fine-grained control over when the buffer's default
161 * processor is applied. Different buffer types may have different default
162 * processing requirements:
163 * - Audio buffers typically always use default processing
164 * - Video buffers may skip processing for certain frame types
165 * - Texture buffers may skip processing when not actively displayed
166 */
167 virtual void enforce_default_processing(bool should_process) = 0;
168
169 /**
170 * @brief Checks if the buffer should undergo default processing
171 * @return True if default processing should be applied, false otherwise
172 *
173 * Determines whether the buffer's default processor should be executed
174 * during the current processing cycle. The decision criteria may vary
175 * based on buffer type and current state:
176 * - Audio buffers typically always need default processing
177 * - Video buffers may skip processing for duplicate frames
178 * - Texture buffers may skip processing when not visible
179 */
180 virtual bool needs_default_processing() = 0;
181
182 /**
183 * @brief Attempts to acquire processing rights for the buffer
184 * @return True if processing rights were successfully acquired, false otherwise
185 *
186 * This method is used to control access to the buffer's data during processing.
187 * It allows the buffer to manage concurrent access and ensure that only one
188 * processing operation occurs at a time. The specific implementation may vary
189 * based on the buffer type and its processing backend.
190 */
191 bool virtual try_acquire_processing() = 0;
192
193 /**
194 * @brief Releases processing rights for the buffer
195 *
196 * This method is called to release the processing rights acquired by
197 * try_acquire_processing(). It allows other processing operations to
198 * access the buffer's data once the current operation is complete.
199 * The specific implementation may vary based on the buffer type and
200 * its processing backend.
201 */
202 virtual void release_processing() = 0;
203
204 /**
205 * @brief Checks if the buffer is currently being processed
206 * @return True if the buffer is in a processing state, false otherwise
207 *
208 * This method indicates whether the buffer is currently undergoing
209 * a processing operation. It is used to manage concurrent access and
210 * ensure that processing operations do not interfere with each other.
211 * The specific implementation may vary based on the buffer type and
212 * its processing backend.
213 */
214 virtual bool is_processing() const = 0;
215
216 /**
217 * @brief Creates a clone of this buffer for a specific channel or usage enum
218 * @param dest_desc Destination channel identifier or usage descriptor for the cloned buffer
219 * @return Shared pointer to the cloned buffer
220 *
221 * This method creates a new instance of the buffer with the same
222 * data and properties, but assigned to a different channel. The
223 * cloned buffer can be used independently in processing chains.
224 *
225 * NOTE: The moment of cloning is the divergence point between the original
226 * and the cloned. While they both will follow the same processing chain or have the same
227 * default procesor, any changes made to one buffer after cloning will not affect the other.
228 */
229 virtual std::shared_ptr<Buffer> clone_to(uint8_t dest_desc) = 0;
230
231 /**
232 * @brief Marks the buffer as internal-only, preventing root aggregation
233 * @param internal True to mark as internal-only, false to allow root aggregation
234 *
235 * Internal-only buffers are excluded from root-level aggregation and
236 * processing. This is typically used for buffers that are processed
237 * entirely within a specific backend or domain (e.g., GPU-only buffers).
238 */
239 virtual void force_internal_usage(bool internal) = 0;
240
241 /**
242 * @brief Checks if the buffer is marked as internal-only
243 * @return True if the buffer is internal-only, false otherwise
244 *
245 * Indicates whether the buffer is excluded from root-level aggregation
246 * and processing. Internal-only buffers are typically processed entirely
247 * within a specific backend or domain.
248 */
249 virtual bool is_internal_only() const = 0;
250};
251
252}
virtual void process_default()=0
Applies the default transformation to the buffer's data.
virtual bool has_data_for_cycle() const =0
Checks if the buffer has data for the current processing cycle.
virtual void enforce_default_processing(bool should_process)=0
Controls whether the buffer should use default processing.
virtual bool try_acquire_processing()=0
Attempts to acquire processing rights for the buffer.
virtual ~Buffer()=default
Virtual destructor for proper resource management.
virtual void release_processing()=0
Releases processing rights for the buffer.
virtual void set_default_processor(std::shared_ptr< BufferProcessor > processor)=0
Sets the default transformation processor for this buffer.
virtual std::shared_ptr< BufferProcessor > get_default_processor() const =0
Gets the current default transformation processor.
virtual void mark_for_processing(bool has_data)=0
Marks the buffer's data availability for the current processing cycle.
virtual bool needs_default_processing()=0
Checks if the buffer should undergo default processing.
virtual std::shared_ptr< BufferProcessingChain > get_processing_chain()=0
Gets the transformation chain attached to this buffer.
virtual void set_processing_chain(std::shared_ptr< BufferProcessingChain > chain, bool force=false)=0
Sets the transformation chain for this buffer.
virtual std::shared_ptr< Buffer > clone_to(uint8_t dest_desc)=0
Creates a clone of this buffer for a specific channel or usage enum.
virtual void force_internal_usage(bool internal)=0
Marks the buffer as internal-only, preventing root aggregation.
virtual bool needs_removal() const =0
Checks if the buffer should be removed from processing chains.
virtual bool is_processing() const =0
Checks if the buffer is currently being processed.
virtual void mark_for_removal()=0
Marks the buffer for removal from processing chains.
virtual void clear()=0
Resets all data values in the buffer.
virtual bool is_internal_only() const =0
Checks if the buffer is marked as internal-only.
Backend-agnostic interface for sequential data storage and transformation.
Definition Buffer.hpp:37