21 bool g_initialized {};
22 std::shared_ptr<Nodes::NodeGraphManager> g_node_graph_manager;
23 std::shared_ptr<Buffers::BufferManager> g_buffer_manager;
24 std::shared_ptr<Vruta::TaskScheduler> g_scheduler;
25 std::shared_ptr<Vruta::EventManager> g_event_manager;
26 std::shared_ptr<Core::WindowManager> g_window_manager;
27 std::unique_ptr<Bridge> g_bridge;
28 std::unique_ptr<Inspector> g_inspect;
30 std::shared_ptr<Core::Window> g_inspect_nodes_window;
31 std::shared_ptr<Core::Window> g_inspect_buffers_window;
32 std::shared_ptr<Core::Window> g_inspect_scheduler_window;
33 std::shared_ptr<Core::Window> g_inspect_events_window;
35 constexpr uint32_t k_inspect_w = 480;
36 constexpr uint32_t k_inspect_h = 900;
38 constexpr size_t k_text_label_capacity =
static_cast<size_t>(6) *
sizeof(Kakshya::MeshVertex);
39 constexpr size_t k_rect_capacity =
static_cast<size_t>(4) *
sizeof(Kakshya::Vertex);
41 void place_plot_adornments(
43 const Plot::SeriesSpec& spec,
46 const auto& win = surface.window();
48 for (
const auto& label : spec.labels) {
51 k_text_label_capacity,
54 { {
"text",
nullptr } });
59 for (
const auto& ticks : spec.tick_labels) {
63 k_text_label_capacity,
66 { {
"text",
nullptr } });
75 for (
const auto& swatch : layout.swatches) {
84 for (
const auto& label : layout.labels) {
87 k_text_label_capacity,
90 { {
"text",
nullptr } });
102 std::shared_ptr<Core::Window> window,
105 const std::string& texture_binding,
106 std::vector<std::pair<std::string, std::shared_ptr<Core::VKImage>>> additional_textures)
108 auto buf = std::make_shared<Buffers::FormaBuffer>(capacity, topology);
111 if (!additional_textures.empty()) {
112 buf->setup_rendering({
113 .target_window = std::move(window),
114 .additional_textures = std::move(additional_textures),
116 }
else if (!texture_binding.empty()) {
117 buf->setup_rendering({
118 .target_window = std::move(window),
119 .default_texture_binding = texture_binding,
122 buf->setup_rendering({ .target_window = std::move(window) });
133 std::shared_ptr<Nodes::NodeGraphManager> node_graph_manager,
134 std::shared_ptr<Buffers::BufferManager> buffer_manager,
135 std::shared_ptr<Vruta::TaskScheduler> scheduler,
136 std::shared_ptr<Vruta::EventManager> event_manager,
137 std::shared_ptr<Core::WindowManager> window_manager)
141 "Portal::Forma already initialized");
145 g_node_graph_manager = std::move(node_graph_manager);
146 g_buffer_manager = std::move(buffer_manager);
147 g_scheduler = std::move(scheduler);
148 g_event_manager = std::move(event_manager);
149 g_window_manager = std::move(window_manager);
150 g_bridge = std::make_unique<Bridge>(*g_scheduler, *g_buffer_manager);
151 g_inspect = std::make_unique<Inspector>(*g_node_graph_manager, *g_buffer_manager, *g_scheduler, *g_event_manager);
152 g_initialized =
true;
155 "Portal::Forma initialized");
161 if (!g_initialized) {
163 "Portal::Forma not initialized - cannot get inspector");
170 if (!g_initialized) {
176 g_node_graph_manager =
nullptr;
177 g_buffer_manager =
nullptr;
178 g_scheduler =
nullptr;
179 g_event_manager =
nullptr;
180 g_window_manager =
nullptr;
181 g_initialized =
false;
183 g_inspect_nodes_window.reset();
184 g_inspect_buffers_window.reset();
185 g_inspect_scheduler_window.reset();
186 g_inspect_events_window.reset();
189 "Portal::Forma shutdown");
194 return g_initialized;
201std::pair<std::shared_ptr<Layer>, std::shared_ptr<Context>>
203 const std::shared_ptr<Core::Window>& window,
206 auto layer = std::make_shared<Layer>();
207 auto ctx = std::make_shared<Context>(layer, window, *g_event_manager, std::move(name));
211 return { std::move(layer), std::move(ctx) };
219 std::shared_ptr<Core::Window> window,
221 const std::string& texture_binding)
227 std::shared_ptr<Core::Window> window,
229 std::vector<std::pair<std::string, std::shared_ptr<Core::VKImage>>> additional_textures)
235 std::shared_ptr<Core::Window> window,
238 auto [layer, ctx] =
create_layer(window, std::move(name));
239 return { std::move(window), std::move(layer), std::move(ctx) };
246std::pair<Mapped<std::shared_ptr<Kakshya::PlotContainer>>, Surface>
251 std::shared_ptr<Kakshya::PlotContainer> container,
254 const uint64_t
N = container->series_count() > 0
255 ? container->series_size(0)
258 auto window = g_window_manager->create_window(
262 auto surface =
create_surface(window, window->get_create_info().title);
265 auto bg = create_element<float>(
266 surface.layer(), window,
272 const auto bg_id = bg.element.id;
274 auto mapped =
Plot::place(surface, std::move(buf), spec, std::move(container));
275 surface.layer().relate(mapped.element.id, bg_id);
276 surface.layer().send_to_back(bg_id);
278 place_plot_adornments(surface, spec, mapped.element.id);
280 return { std::move(mapped), std::move(surface) };
284 auto mapped =
Plot::place(surface, std::move(buf), spec, std::move(container));
286 place_plot_adornments(surface, spec, mapped.element.id);
288 return { std::move(mapped), std::move(surface) };
302 if (g_inspect_nodes_window) {
303 g_inspect_nodes_window->show();
306 g_inspect_nodes_window = g_window_manager->create_window(
308 g_inspect_nodes_window->show();
309 auto surface =
create_surface(g_inspect_nodes_window,
"NodeGraphManager");
311 auto& result = g_inspect->node_graph_manager(surface, cursor);
312 g_bridge->spawn_sync(result.group.header.header_id, [&result] { result.tap_all(); });
317 if (g_inspect_buffers_window) {
318 g_inspect_buffers_window->show();
321 g_inspect_buffers_window = g_window_manager->create_window(
323 g_inspect_buffers_window->show();
324 auto surface =
create_surface(g_inspect_buffers_window,
"BufferManager");
326 auto& result = g_inspect->buffer_manager(surface, cursor);
327 g_bridge->spawn_sync(result.group.header.header_id, [&result] { result.tap_all(); });
332 if (g_inspect_scheduler_window) {
333 g_inspect_scheduler_window->show();
336 g_inspect_scheduler_window = g_window_manager->create_window(
338 g_inspect_scheduler_window->show();
339 auto surface =
create_surface(g_inspect_scheduler_window,
"TaskScheduler");
341 auto& result = g_inspect->scheduler(surface, cursor);
342 g_bridge->spawn_sync(result.group.header.header_id, [&result] { result.tap_all(); });
347 if (g_inspect_events_window) {
348 g_inspect_events_window->show();
351 g_inspect_events_window = g_window_manager->create_window(
353 g_inspect_events_window->show();
354 auto surface =
create_surface(g_inspect_events_window,
"EventManager");
356 auto& result = g_inspect->event_manager(surface, cursor);
357 g_bridge->spawn_sync(result.group.header.header_id, [&result] { result.tap_all(); });
360void inspect(
const std::shared_ptr<Nodes::Node>& node)
363 auto window = g_window_manager->create_window(
368 auto result = std::make_shared<InspectResult>(g_inspect->node(node, surface, cursor));
369 g_bridge->spawn_sync(result->group.header.header_id, [result] { result->tap_all(); });
372void inspect(
const std::shared_ptr<Buffers::Buffer>& buf)
375 auto window = g_window_manager->create_window(
380 auto result = std::make_shared<InspectResult>(g_inspect->buffer(buf, surface, cursor));
381 g_bridge->spawn_sync(result->group.header.header_id, [result] { result->tap_all(); });
384void inspect(
const std::shared_ptr<Nodes::Network::NodeNetwork>& net)
386 auto window = g_window_manager->create_window(
391 auto result = std::make_shared<InspectResult>(g_inspect->node_network(net, surface, cursor));
392 g_bridge->spawn_sync(result->group.header.header_id, [result] { result->tap_all(); });
395void inspect(
const std::shared_ptr<Vruta::Event>& ev, std::string_view name)
397 const std::string title = name.empty() ?
"Event" :
"Event: " + std::string(name);
398 auto window = g_window_manager->create_window(
403 auto result = std::make_shared<InspectResult>(g_inspect->event(ev, name, surface, cursor));
404 g_bridge->spawn_sync(result->group.header.header_id, [result] { result->tap_all(); });
#define MF_INFO(comp, ctx,...)
#define MF_WARN(comp, ctx,...)
#define N(method_name, full_type_name)
@ GRAPHICS_BACKEND
Standard graphics processing backend configuration.
@ API
API calls from external code.
@ Portal
High-level user-facing API layer.
PrimitiveTopology
Vertex assembly primitive topology.
std::string short_dynamic_type_name(const T &obj) noexcept
Returns the unqualified dynamic type name of obj.
std::shared_ptr< T > store(std::shared_ptr< T > obj)
Transfer ownership of an existing object to the persistent store for process lifetime.
std::string title
Window title/identifier.
Configuration for creating a single window instance.
uint32_t stride_bytes
Total bytes per vertex (stride in Vulkan terms) e.g., 3 floats (position) + 3 floats (normal) = 24 by...
static VertexLayout for_meshes(uint32_t stride=60)
Factory: layout for MeshVertex (position, color, weight, uv, normal, tangent)