MayaFlux 0.4.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
Creator.hpp
Go to the documentation of this file.
1#pragma once
2
3#include "Domain.hpp"
4#include "Registry.hpp"
5
7
9
10namespace MayaFlux {
11
12namespace Core {
13 class VKImage;
14}
15
16namespace IO {
17 using TextureResolver = std::function<std::shared_ptr<Core::VKImage>(const std::string& path)>;
18}
19
21 std::optional<Domain> domain;
22 std::optional<uint32_t> channel;
23 std::optional<std::vector<uint32_t>> channels;
24
25 CreationContext() = default;
27 : domain(d)
28 {
29 }
30 CreationContext(Domain d, uint32_t ch)
31 : domain(d)
32 , channel(ch)
33 {
34 }
35 CreationContext(Domain d, std::vector<uint32_t> ch)
36 : domain(d)
37 , channels(std::move(ch))
38 {
39 }
40 CreationContext(uint32_t ch)
41 : channel(ch)
42 {
43 }
44 CreationContext(std::vector<uint32_t> ch)
45 : channels(std::move(ch))
46 {
47 }
48};
49
50MAYAFLUX_API void register_node(const std::shared_ptr<Nodes::Node>& node, const CreationContext& ctx);
51MAYAFLUX_API void register_network(const std::shared_ptr<Nodes::Network::NodeNetwork>& network, const CreationContext& ctx);
52MAYAFLUX_API void register_buffer(const std::shared_ptr<Buffers::Buffer>& buffer, const CreationContext& ctx);
53MAYAFLUX_API void register_container(const std::shared_ptr<Kakshya::SoundFileContainer>& container, const Domain& domain);
54
55/**
56 * @brief Thin domain wrapper that adds subscript channel-binding syntax.
57 *
58 * Audio[0] and Audio[{0,1}] produce a CreationContext consumed immediately
59 * by operator|. Implicit conversion to Domain keeps all existing call sites
60 * that accept a plain Domain parameter working without change.
61 */
62struct DomainSpec {
64
65 /** @brief Bind a single channel to this domain. */
66 [[nodiscard]] CreationContext operator[](uint32_t ch) const
67 {
68 return { value, ch };
69 }
70
71 /** @brief Bind multiple channels to this domain. */
72 [[nodiscard]] CreationContext operator[](std::initializer_list<uint32_t> chs) const
73 {
74 return { value, std::vector<uint32_t>(chs) };
75 }
76
77 /** @brief Implicit decay to Domain for call sites that accept Domain directly. */
78 operator Domain() const { return value; }
79
80 /** @brief Implicit decay to CreationContext for bare ptr | Audio usage. */
81 operator CreationContext() const { return { value }; }
82};
83
84class MAYAFLUX_API MeshGroupHandle {
85public:
86 explicit MeshGroupHandle(std::vector<std::shared_ptr<Buffers::MeshBuffer>> buffers);
88
90
91 auto begin() { return m_buffers.begin(); }
92 auto end() { return m_buffers.end(); }
93 [[nodiscard]] auto begin() const { return m_buffers.begin(); }
94 [[nodiscard]] auto end() const { return m_buffers.end(); }
95
96 [[nodiscard]] bool empty() const { return m_buffers.empty(); }
97 [[nodiscard]] size_t size() const { return m_buffers.size(); }
98
99 std::shared_ptr<Buffers::MeshBuffer>& operator[](size_t i) { return m_buffers[i]; }
100
101private:
102 std::vector<std::shared_ptr<Buffers::MeshBuffer>> m_buffers;
103};
104
105class MAYAFLUX_API Creator {
106public:
107#define N(method_name, full_type_name) \
108 template <typename... Args> \
109 requires std::constructible_from<full_type_name, Args...> \
110 auto method_name(Args&&... args) -> std::shared_ptr<full_type_name> \
111 { \
112 auto obj = std::make_shared<full_type_name>(std::forward<Args>(args)...); \
113 MF_LIVE_EXPOSE_NAMED(#method_name, obj); \
114 return obj; \
115 }
117#undef N
118
119#define W(method_name, full_type_name) \
120 template <typename... Args> \
121 requires std::constructible_from<full_type_name, Args...> \
122 auto method_name(Args&&... args) -> std::shared_ptr<full_type_name> \
123 { \
124 auto obj = std::make_shared<full_type_name>(std::forward<Args>(args)...); \
125 MF_LIVE_EXPOSE_NAMED(#method_name, obj); \
126 return obj; \
127 }
129#undef W
130
131#define B(method_name, full_type_name) \
132 template <typename... Args> \
133 requires std::constructible_from<full_type_name, Args...> \
134 auto method_name(Args&&... args) -> std::shared_ptr<full_type_name> \
135 { \
136 auto obj = std::make_shared<full_type_name>(std::forward<Args>(args)...); \
137 MF_LIVE_EXPOSE_NAMED(#method_name, obj); \
138 return obj; \
139 }
141#undef B
142
143 auto read_audio(const std::string& filepath) -> std::shared_ptr<Kakshya::SoundFileContainer>
144 {
145 auto container = load_sound_container(filepath);
146 MF_LIVE_EXPOSE_AUTO(container);
147 return container;
148 }
149
150 auto read_image(const std::string& filepath) -> std::shared_ptr<Buffers::TextureBuffer>
151 {
152 auto buffer = load_image_buffer(filepath);
153 MF_LIVE_EXPOSE_AUTO(buffer);
154 return buffer;
155 }
156
157 auto read_mesh(const std::string& filepath) -> MeshGroupHandle
158 {
159 return MeshGroupHandle(load_mesh_buffers(filepath));
160 }
161
163 const std::string& filepath,
164 IO::TextureResolver resolver = nullptr)
165 -> std::shared_ptr<Nodes::Network::MeshNetwork>
166 {
167 auto network = load_mesh_network(filepath, std::move(resolver));
168 MF_LIVE_EXPOSE_AUTO(network);
169 return network;
170 }
171
172 // ═══════════════════════════════════════════════════════════════
173 // Input Node Creation (Special - defined in Creator.cpp)
174 // ═══════════════════════════════════════════════════════════════
175
176 /**
177 * @brief Create and register HID input node.
178 * @param config HID input configuration.
179 * @param binding HID input binding.
180 * @return Shared pointer to HIDNode (already registered).
181 */
182 std::shared_ptr<Nodes::Input::HIDNode> read_hid(
183 const Nodes::Input::HIDConfig& config,
184 const Core::InputBinding& binding);
185
186 /**
187 * @brief Create and register MIDI input node.
188 * @param config MIDI input configuration.
189 * @param binding MIDI input binding.
190 * @return Shared pointer to MIDINode (already registered).
191 */
192 std::shared_ptr<Nodes::Input::MIDINode> read_midi(
193 const Nodes::Input::MIDIConfig& config,
194 const Core::InputBinding& binding);
195
196 /**
197 * @brief Create and register OSC input node.
198 * @param config OSC input configuration.
199 * @param binding OSC input binding (use InputBinding::osc("/address")).
200 * @return Shared pointer to OSCNode (already registered).
201 */
202 std::shared_ptr<Nodes::Input::OSCNode> read_osc(
203 const Nodes::Input::OSCConfig& config,
204 const Core::InputBinding& binding);
205
206 /**
207 * @brief Create and register generic input node.
208 * @param config Generic input configuration.
209 * @param binding Generic input binding.
210 * @return Shared pointer to InputNode (already registered).
211 */
212 std::shared_ptr<Nodes::Input::InputNode> read_input(
213 const Nodes::Input::InputConfig& config,
214 const Core::InputBinding& binding);
215
216private:
217 std::shared_ptr<Kakshya::SoundFileContainer> load_sound_container(const std::string& filepath);
218 std::shared_ptr<Buffers::TextureBuffer> load_image_buffer(const std::string& filepath);
219 std::vector<std::shared_ptr<Buffers::MeshBuffer>> load_mesh_buffers(const std::string& filepath);
220 std::shared_ptr<Nodes::Network::MeshNetwork> load_mesh_network(const std::string& filepath, IO::TextureResolver resolver);
221};
222
223// ═══════════════════════════════════════════════════════════════
224// New pipe operators -- shared_ptr<T> | CreationContext
225// DomainSpec converts implicitly to CreationContext so
226// | Audio, | Audio[0], | Audio[{0,1}], | Graphics all route here.
227// ═══════════════════════════════════════════════════════════════
228
229template <typename T>
230 requires std::is_base_of_v<Nodes::Node, T>
231std::shared_ptr<T> operator|(std::shared_ptr<T> obj, const CreationContext& ctx)
232{
233 register_node(std::static_pointer_cast<Nodes::Node>(obj), ctx);
234 return obj;
235}
236
237template <typename T>
238 requires std::is_base_of_v<Nodes::Network::NodeNetwork, T>
239std::shared_ptr<T> operator|(std::shared_ptr<T> obj, const CreationContext& ctx)
240{
241 register_network(std::static_pointer_cast<Nodes::Network::NodeNetwork>(obj), ctx);
242 return obj;
243}
244
245template <typename T>
246 requires std::is_base_of_v<Buffers::Buffer, T>
247std::shared_ptr<T> operator|(std::shared_ptr<T> obj, const CreationContext& ctx)
248{
249 register_buffer(std::static_pointer_cast<Buffers::Buffer>(obj), ctx);
250 return obj;
251}
252
253inline std::shared_ptr<Kakshya::SoundFileContainer> operator|(
254 std::shared_ptr<Kakshya::SoundFileContainer> obj,
255 const CreationContext& ctx)
256{
257 if (ctx.domain)
258 register_container(obj, ctx.domain.value());
259 return obj;
260}
261
262/**
263 * @brief Domain constant for Audio domain.
264 *
265 * Supports subscript syntax for channel binding:
266 * @code
267 * auto wave = vega.Sine(440.f) | Audio[0];
268 * auto net = vega.ModalNetwork(16, 220.0) | Audio[{0, 1}];
269 * @endcode
270 */
271static constexpr DomainSpec Audio { .value = Domain::AUDIO };
272
273/**
274 * @brief Domain constant for Graphics domain.
275 *
276 * @code
277 * auto tex = vega.TextureBuffer(...) | Graphics;
278 * @endcode
279 */
281
282/**
283 * @brief Global Creator instance.
284 *
285 * @code
286 * auto wave = vega.Sine(440.f) | Audio[0];
287 * auto buf = vega.AudioBuffer(0, 512) | Audio[0];
288 * auto net = vega.ModalNetwork(16, 220.0) | Audio[{0, 1}];
289 * auto tex = vega.TextureBuffer(...) | Graphics;
290 * auto sfx = vega.read_audio("x.wav") | Audio;
291 * @endcode
292 */
293extern MAYAFLUX_API Creator vega;
294
295} // namespace MayaFlux
#define MF_LIVE_EXPOSE_AUTO(ptr)
Auto-expose variant that deduces the key prefix from the shared_ptr element type.
#define ALL_NODE_NETWORK_REGISTRATIONS
Definition Registry.hpp:111
#define ALL_NODE_REGISTRATIONS
Definition Registry.hpp:89
#define ALL_BUFFER_REGISTRATION
Definition Registry.hpp:119
auto read_audio(const std::string &filepath) -> std::shared_ptr< Kakshya::SoundFileContainer >
Definition Creator.hpp:143
auto read_mesh_network(const std::string &filepath, IO::TextureResolver resolver=nullptr) -> std::shared_ptr< Nodes::Network::MeshNetwork >
Definition Creator.hpp:162
auto read_image(const std::string &filepath) -> std::shared_ptr< Buffers::TextureBuffer >
Definition Creator.hpp:150
auto read_mesh(const std::string &filepath) -> MeshGroupHandle
Definition Creator.hpp:157
std::vector< std::shared_ptr< Buffers::MeshBuffer > > m_buffers
Definition Creator.hpp:102
std::shared_ptr< Buffers::MeshBuffer > & operator[](size_t i)
Definition Creator.hpp:99
size_t size() const
Definition Creator.hpp:97
std::function< std::shared_ptr< Core::VKImage >(const std::string &path)> TextureResolver
Callable that maps a raw material texture path to a GPU image.
Definition Creator.hpp:17
@ Core
Core engine, backend, subsystems.
@ IO
Networking, file handling, streaming.
Creator vega
Global Creator instance.
Definition Creator.cpp:20
void register_node(const std::shared_ptr< Nodes::Node > &node, const Nodes::ProcessingToken &token, uint32_t channel)
Definition Graph.cpp:124
void register_buffer(const std::shared_ptr< Buffers::Buffer > &buffer, const CreationContext &ctx)
Definition Creator.cpp:73
void register_container(const std::shared_ptr< Kakshya::SoundFileContainer > &container, const Domain &domain)
Definition Creator.cpp:97
Domain
Unified domain enum combining all three ProcessingToken subsystems.
Definition Domain.hpp:22
@ AUDIO
Standard real-time audio processing domain.
Definition Domain.hpp:33
@ GRAPHICS
Standard real-time graphics processing domain.
Definition Domain.hpp:55
static constexpr DomainSpec Audio
Domain constant for Audio domain.
Definition Creator.hpp:271
static constexpr DomainSpec Graphics
Domain constant for Graphics domain.
Definition Creator.hpp:280
void register_network(const std::shared_ptr< Nodes::Network::NodeNetwork > &network, const CreationContext &ctx)
Definition Creator.cpp:43
std::shared_ptr< T > operator|(std::shared_ptr< T > obj, const CreationContext &ctx)
Definition Creator.hpp:231
Main namespace for the Maya Flux audio engine.
Definition Runtime.cpp:12
Specifies what input an InputNode wants to receive.
CreationContext(std::vector< uint32_t > ch)
Definition Creator.hpp:44
std::optional< uint32_t > channel
Definition Creator.hpp:22
CreationContext(Domain d, std::vector< uint32_t > ch)
Definition Creator.hpp:35
CreationContext(uint32_t ch)
Definition Creator.hpp:40
CreationContext(Domain d, uint32_t ch)
Definition Creator.hpp:30
std::optional< std::vector< uint32_t > > channels
Definition Creator.hpp:23
std::optional< Domain > domain
Definition Creator.hpp:21
CreationContext operator[](uint32_t ch) const
Bind a single channel to this domain.
Definition Creator.hpp:66
CreationContext operator[](std::initializer_list< uint32_t > chs) const
Bind multiple channels to this domain.
Definition Creator.hpp:72
Thin domain wrapper that adds subscript channel-binding syntax.
Definition Creator.hpp:62
Unified configuration for all HID input types.
Definition HIDNode.hpp:21
Configuration for InputNode behavior.
Definition InputNode.hpp:79
MIDI input node configuration.
Definition MIDINode.hpp:10
Configuration for OSC input node argument extraction.
Definition OSCNode.hpp:16