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