MayaFlux 1.0.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
Forma.hpp
Go to the documentation of this file.
1#pragma once
2
4#include "Tend.hpp"
5
6namespace MayaFlux::Vruta {
7class Event;
8}
9
11
12/**
13 * @file Forma.hpp
14 * @brief Factory free functions for the Forma surface system.
15 *
16 * Call initialize() once after engine startup to store BufferManager,
17 * TaskScheduler, and EventManager references. Subsequent factory calls
18 * require only the arguments that legitimately vary per call (Window,
19 * geometry function, initial value). This matches the Portal::Text and
20 * Portal::Graphics initialization contracts.
21 *
22 * Typical sequence:
23 * @code
24 * Portal::Forma::initialize(buffer_manager, scheduler, event_manager);
25 *
26 * auto surface = Forma::create_surface(SurfaceConfig { .window = window, .name = "hud" });
27 *
28 * auto el = Forma::create_element<float>(surface, geom_fn, 0.5f);
29 *
30 * auto bridge = Forma::create_bridge();
31 * bridge.bind(el.state, envelope);
32 * bridge.write(el.state, compute_proc, offsetof(PC, cutoff));
33 *
34 * ctx->on_press(el.element.id, IO::MouseButtons::LEFT,
35 * [](uint32_t, glm::vec2){});
36 * @endcode
37 */
38
39// =============================================================================
40// Lifecycle
41// =============================================================================
42
43/**
44 * @brief Store engine-level references for use by all subsequent Forma calls.
45 *
46 * Must be called before any create_* call. Safe to call multiple times;
47 * subsequent calls are no-ops and log a warning.
48 *
49 * @param node_graph_manager Engine NodeGraphManager. Must outlive all Forma objects.
50 * @param buffer_manager Engine BufferManager. Must outlive all Forma objects.
51 * @param scheduler Engine TaskScheduler. Must outlive all Bridge instances.
52 * @param event_manager Engine EventManager. Must outlive all Context instances.
53 * @param window_manager Engine WindowManager. Must outlive all Surface instances.
54 * @return True on success, false if any argument is null.
55 */
56MAYAFLUX_API bool initialize(
57 std::shared_ptr<Nodes::NodeGraphManager> node_graph_manager,
58 std::shared_ptr<Buffers::BufferManager> buffer_manager,
59 std::shared_ptr<Vruta::TaskScheduler> scheduler,
60 std::shared_ptr<Vruta::EventManager> event_manager,
61 std::shared_ptr<Core::WindowManager> window_manager);
62
63/**
64 * @brief Release stored references. Does not destroy any Forma objects.
65 *
66 * Call after all Forma objects have been destroyed, before engine shutdown.
67 */
68MAYAFLUX_API void shutdown();
69
70/** @brief Whether initialize() has been called successfully. */
71MAYAFLUX_API bool is_initialized();
72
73/**
74 * @brief Return the application-level Bridge instance.
75 *
76 * Valid only after initialize(). Lifetime is tied to the Forma module.
77 */
78[[nodiscard]] MAYAFLUX_API Bridge& bridge();
79
80/**
81 * @brief Access the Forma introspection subsystem.
82 *
83 * Returns the Inspector instance initialized alongside Bridge during
84 * Portal::Forma::initialize(). The Inspector holds no state beyond
85 * references to BufferManager and NodeGraphManager; it is a stable
86 * entry point into the Inspect:: query functions.
87 *
88 * @pre Portal::Forma::initialize() must have been called.
89 * @return Reference to the singleton Inspector. Lifetime is the Forma module lifetime.
90 * @throws std::runtime_error if called before initialize().
91 */
92[[nodiscard]] MAYAFLUX_API Inspector& inspector();
93
94// =============================================================================
95// Layer
96// =============================================================================
97
98/**
99 * @brief Construct a Layer and a Context wired to @p window.
100 *
101 * EventManager is taken from the stored initialize() state.
102 * The caller owns both returned objects. The Context cancels its event
103 * coroutines on destruction.
104 *
105 * @param window Target window surface.
106 * @param name Unique name scoping the Context's event coroutines.
107 * @return Pair of { shared_ptr<Layer>, shared_ptr<Context> }.
108 */
109[[nodiscard]] MAYAFLUX_API
110 std::pair<std::shared_ptr<Layer>, std::shared_ptr<Context>>
112 const std::shared_ptr<Core::Window>& window,
113 std::string name);
114
115// =============================================================================
116// Standalone buffer
117// =============================================================================
118
119/**
120 * @brief Construct and register a FormaBuffer without creating a Mapped<T>.
121 *
122 * The buffer triangulates, so slices of any topology draw together as one
123 * batch. Elements draw into slices of it, made with FormaTarget::slice_of,
124 * each carrying its own topology. BufferManager is taken from the stored
125 * initialize() state.
126 *
127 * With the default multi-texture shader, positive vertex weights select an
128 * image and negative weights select glyph coverage. A custom fragment shader
129 * can use different semantics, as the plot shader does for line and point
130 * geometry mixed with glyphs.
131 *
132 * @param render Render settings; build it with Surface::render_config, which
133 * sets the window. Textures, shaders and the rest are the
134 * caller's.
135 * @return Registered, render-ready FormaBuffer.
136 */
137[[nodiscard]] MAYAFLUX_API
138 std::shared_ptr<Buffers::FormaBuffer>
139 create_buffer(Graphics::RenderConfig render);
140
141// =============================================================================
142// Element
143// =============================================================================
144
145/**
146 * @brief Construct a Surface from a SurfaceConfig.
147 *
148 * When @p config.layer/@p config.ctx are unset, builds a fresh Layer and a
149 * Context wired to @p config.window using the EventManager stored by
150 * Portal::Forma::initialize, from @p config.name. Set @p config.layer/
151 * @p config.ctx yourself for the power-tinkerer case (custom Context
152 * subclass, shared Layer across multiple Contexts, etc.) - @p config.name is
153 * ignored when both are already set.
154 *
155 * @param config Window, name, optional pre-built Layer/Context, and
156 * close-handling behavior.
157 * @pre Portal::Forma::initialize() must have been called.
158 * @return A new Surface owning the window pointer plus the Layer and
159 * Context, built fresh or supplied.
160 */
161[[nodiscard]] MAYAFLUX_API Surface create_surface(SurfaceConfig config);
162
163/**
164 * @brief Tear down an element and everything related to it.
165 *
166 * The symmetric counterpart to create_element/create<T>/create_text_field:
167 * walks surface.layer().closure(id) (id plus every id transitively
168 * related via Layer::relate, e.g. a Collapsible's attached body, a
169 * Scrollable's tracked rows, or a TextField's Scrollable viewport), calls
170 * Context::unbind and Bridge::unbind on each id in that closure, then
171 * Layer::remove(id) - which itself cascades the Layer-side removal
172 * (buffer mark_for_removal, m_elements erase, m_relations cleanup) across
173 * the same closure.
174 *
175 * This is the one call callers should use to tear down a composed Forma
176 * element. Layer::remove(id) alone is still available for callers that
177 * only need the Layer-side cascade with no Context/Bridge involvement.
178 *
179 * @param surface Surface owning the Layer, Context, and (via the module
180 * Bridge) the bindings @p id may participate in.
181 * @param id Element id to remove, as returned by layer().add()/Slot::id().
182 */
183MAYAFLUX_API void destroy(Surface& surface, uint32_t id);
184
185/**
186 * @brief Create a live plot in a new window.
187 *
188 * Creates the window, shows it, constructs the Surface, and places the plot
189 * in a slice of one batch. Background, legend swatches and labels use slices
190 * of that batch; a plot with labels selects the glyph-capable plot shader.
191 * Returns the Mapped<shared_ptr<PlotContainer>> from Plot::place, plus the
192 * Surface owning the window and layer.
193 *
194 * @param title Window title.
195 * @param width Window width in pixels.
196 * @param height Window height in pixels.
197 * @param container Ready PlotContainer from Plot::source().build().
198 * @param spec SeriesSpec from Plot::series()...done().
199 * @return Pair of { Mapped<shared_ptr<PlotContainer>>, Surface } for the created plot.
200 */
201[[nodiscard]] MAYAFLUX_API
202 std::pair<Mapped<std::shared_ptr<Kakshya::PlotContainer>>, Surface>
203 plot(
204 std::string title,
205 uint32_t width,
206 uint32_t height,
207 std::shared_ptr<Kakshya::PlotContainer> container,
208 Plot::SeriesSpec spec);
209
210// =============================================================================
211// Introspection
212// =============================================================================
213
214/**
215 * @brief Open or show the NodeGraphManager inspection window.
216 *
217 * First call creates a dedicated window, builds the InspectResult, and
218 * schedules tap_all() via Bridge. Subsequent calls show() the existing window.
219 */
220MAYAFLUX_API void inspect_node_graph();
221
222/**
223 * @brief Open or show the BufferManager inspection window.
224 *
225 * First call creates a dedicated window, builds the InspectResult, and
226 * schedules tap_all() via Bridge. Subsequent calls show() the existing window.
227 */
228MAYAFLUX_API void inspect_buffers();
229
230/**
231 * @brief Open or show the TaskScheduler inspection window.
232 *
233 * First call creates a dedicated window, builds the InspectResult, and
234 * schedules tap_all() via Bridge. Subsequent calls show() the existing window.
235 */
236MAYAFLUX_API void inspect_scheduler();
237
238/**
239 * @brief Open or show the EventManager inspection window.
240 *
241 * First call creates a dedicated window, builds the InspectResult, and
242 * schedules tap_all() via Bridge. Subsequent calls show() the existing window.
243 */
244MAYAFLUX_API void inspect_events();
245
246/**
247 * @brief Open a dedicated window inspecting a single Node and its modulator tree.
248 */
249MAYAFLUX_API void inspect(const std::shared_ptr<Nodes::Node>& node);
250
251/**
252 * @brief Open a dedicated window inspecting a single Buffer and its processing chain.
253 */
254MAYAFLUX_API void inspect(const std::shared_ptr<Buffers::Buffer>& buf);
255
256/**
257 * @brief Open a dedicated window inspecting a NodeNetwork.
258 */
259MAYAFLUX_API void inspect(const std::shared_ptr<Nodes::Network::NodeNetwork>& net);
260
261/**
262 * @brief Open a dedicated window inspecting a single Event.
263 */
264MAYAFLUX_API void inspect(const std::shared_ptr<Vruta::Event>& ev, std::string_view name = {});
265
266} // namespace MayaFlux::Portal::Forma
std::weak_ptr< Core::Window > window
Definition Picker.cpp:23
std::string name
Definition VKDevice.cpp:123
uint32_t width
uint32_t height
void initialize()
Definition main.cpp:10
std::pair< Mapped< std::shared_ptr< Kakshya::PlotContainer > >, Surface > plot(std::string title, uint32_t width, uint32_t height, std::shared_ptr< Kakshya::PlotContainer > container, Plot::SeriesSpec spec)
Create a live plot in a new window.
Definition Forma.cpp:113
void inspect_buffers()
Open or show the BufferManager inspection window.
Definition Forma.cpp:197
void destroy(Surface &surface, uint32_t id)
Tear down an element and everything related to it.
Definition Forma.cpp:90
void shutdown()
Release stored references.
Definition Forma.cpp:58
std::shared_ptr< Buffers::FormaBuffer > create_buffer(Graphics::RenderConfig render)
Construct and register a FormaBuffer without creating a Mapped<T>.
Definition Forma.cpp:103
void inspect_node_graph()
Open or show the NodeGraphManager inspection window.
Definition Forma.cpp:165
bool is_initialized()
Whether initialize() has been called successfully.
Definition Forma.cpp:69
Inspector & inspector()
Access the Forma introspection subsystem.
Definition Forma.cpp:73
void inspect_scheduler()
Open or show the TaskScheduler inspection window.
Definition Forma.cpp:229
std::pair< std::shared_ptr< Layer >, std::shared_ptr< Context > > create_layer(const std::shared_ptr< Core::Window > &window, std::string name)
Construct a Layer and a Context wired to window.
Definition Forma.cpp:80
Bridge & bridge()
Return the application-level Bridge instance.
Definition Forma.cpp:71
Surface create_surface(SurfaceConfig config)
Construct a Surface from a SurfaceConfig.
Definition Forma.cpp:85
void inspect(const std::shared_ptr< Nodes::Node > &node)
Open a dedicated window inspecting a single Node and its modulator tree.
Definition Forma.cpp:293
void inspect_events()
Open or show the EventManager inspection window.
Definition Forma.cpp:261