MayaFlux 1.0.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
Schema.hpp
Go to the documentation of this file.
1#pragma once
2
6
7#include <nlohmann/json.hpp>
8
10
11/**
12 * @brief Current schema version written by StateEncoder and accepted by StateDecoder.
13 *
14 * History:
15 * 1 - initial (positions only)
16 * 2 - added color, size, wiring
17 * 3 - added audio_sinks, render_sinks
18 * 4 - added sink_type pixel row
19 * 5 - added subkind, locus_nav fields, expanses array
20 * 6 - entity position optional, entity orientation; locus_nav mouse_sensitivity,
21 * scroll_speed, aspect (up removed); wiring sources (key, mouse, network,
22 * window_event, factory, bind), scheduler tokens and callable names;
23 * render sink RenderConfig data; Expanse subkind (hull, mantle), collection
24 * and fit; Fabric cell_size
25 */
26inline constexpr uint32_t k_schema_version = 6;
27
28/**
29 * @brief Oldest schema version StateDecoder still reads. Every field added since
30 * is optional or defaulted, so an older file reads with those fields absent.
31 */
32inline constexpr uint32_t k_schema_min_version = 5;
33
34/**
35 * @brief RGBA32F EXR layout constants shared between encoder and decoder.
36 *
37 * Row 0: position.xyz, intensity
38 * Row 1: color.rgb, size
39 * Row 2: radius, query_radius, 0, 0
40 * Row 3: id, entity_type_norm, trigger_kind, time_kind
41 * Row 4: sink_type_bits, first_audio_channel, 0, 0
42 *
43 * The decoder reads rows 0 to 2. Rows 3 and 4 are descriptive only. The file's
44 * channels are named A, B, G, R as EXR requires, so the four values of a pixel
45 * listed above are channels A, B, G, R in that order.
46 */
47inline constexpr uint32_t k_exr_rows = 5;
48inline constexpr uint32_t k_channels = 4;
49
50// =============================================================================
51// Range normalization records
52// =============================================================================
53
54struct Range {
55 float min { 0.0F };
56 float max { 1.0F };
57
58 static constexpr auto describe()
59 {
60 return std::make_tuple(
63 }
64};
65
66struct RangeSet {
73
74 static constexpr auto describe()
75 {
76 return std::make_tuple(
77 Reflect::member("position.x", &RangeSet::pos_x),
78 Reflect::member("position.y", &RangeSet::pos_y),
79 Reflect::member("position.z", &RangeSet::pos_z),
86 Reflect::member("query_radius", &RangeSet::query_radius));
87 }
88};
89
90// =============================================================================
91// Wiring records
92// =============================================================================
93
94/**
95 * @brief Serializable wiring strategies.
96 *
97 * Written as the underlying integer, so new enumerators are only ever
98 * appended. Key, Mouse, Network, WindowEvent, Factory and Bind describe a wiring
99 * whose source is live (a window, a network source, a callable) and is not
100 * encoded; the record keeps what is plain data. Unsupported marks a wiring the
101 * encoder could not describe.
102 */
103enum class WiringKind : uint8_t {
105 Every,
106 MoveTo,
107 Scroll,
109 Key,
110 Mouse,
111 Network,
113 Factory,
114 Bind,
115};
116
118 glm::vec3 position {};
119 double delay_seconds { 0.0 };
120
121 static constexpr auto describe()
122 {
123 return std::make_tuple(
126 }
127};
128
131 std::optional<double> interval;
132 std::optional<double> duration;
133 std::optional<size_t> times;
134 std::optional<std::vector<WiringStep>> steps;
135 std::optional<Vruta::ProcessingToken> interval_token;
136 std::optional<Vruta::ProcessingToken> duration_token;
137 std::optional<IO::Keys> key;
138 std::optional<IO::MouseButtons> button;
139 std::optional<bool> held;
140 std::string position_fn_name;
141 std::string factory_name;
142 std::string attach_fn_name;
143 std::string detach_fn_name;
144
163};
164
165// =============================================================================
166// Sink records
167// =============================================================================
168
170 uint32_t channel {};
171 std::string fn_name;
172
173 static constexpr auto describe()
174 {
175 return std::make_tuple(
178 }
179};
180
181/**
182 * @brief Plain-data part of the sink buffer's RenderConfig. The target window,
183 * additional textures and scissor are live or derived and are not encoded.
184 */
214
215// =============================================================================
216// Locus navigation fields
217// =============================================================================
218
219/**
220 * @brief Serializable subset of Kinesis::NavigationConfig sufficient to seed
221 * a Locus on reconstruct. Dynamic nav state (velocity, yaw accumulation)
222 * is transient and is not encoded.
223 *
224 * @note view_targets are live RenderProcessor pointers and cannot be serialized.
225 * StateDecoder warns on reconstruct; the caller must reconnect them.
226 */
228 glm::vec3 eye {};
229 glm::vec3 target {};
230 float fov { 60.0F };
231 float near_plane { 0.01F };
232 float far_plane { 1000.0F };
233 float speed { 1.0F };
234 float mouse_sensitivity { 0.002F };
235 float scroll_speed { 0.5F };
236 float aspect { 1.0F };
237
238 static constexpr auto describe()
239 {
240 return std::make_tuple(
250 }
251};
252
253// =============================================================================
254// Entity record
255// =============================================================================
256
257/**
258 * @brief Per-entity JSON record.
259 *
260 * `kind` is one of "emitter", "sensor", "agent".
261 * `subkind` is empty for plain Agent, "locus" for Locus, "presence" for Presence.
262 * `locus_nav` is present only when subkind == "locus".
263 * `position` is absent for an entity that has none; its EXR column is zero.
264 * `orientation` is x, y, z, w and is absent for an entity that has none.
265 */
267 uint32_t id {};
268 std::string kind;
269 std::string subkind;
270 std::optional<glm::vec3> position;
271 std::optional<glm::vec4> orientation;
272 float intensity { 0.0F };
273 float radius { 0.0F };
274 float query_radius { 0.0F };
275 std::optional<glm::vec3> color;
276 std::optional<float> size;
277 std::string influence_fn_name;
279 std::string radiate_fn_name;
281 std::vector<AudioSinkRecord> audio_sinks;
282 std::vector<RenderSinkRecord> render_sinks;
283 std::optional<LocusNavRecord> locus_nav;
285 std::optional<float> falloff_radius;
286
310};
311
312// =============================================================================
313// Expanse record
314// =============================================================================
315
316/**
317 * @brief Per-expanse JSON record.
318 *
319 * The containment predicate and crossing callbacks are closures, so only their
320 * names are serializable and they are resolved from the Fabric's function
321 * registry on reconstruct. The box is plain data and is stored as is.
322 *
323 * `subkind` is empty for a plain Expanse, "hull" for a Hull and "mantle" for a
324 * Mantle. A Hull keeps its collection index and a Mantle its fit mode, as the
325 * lowercase FitMode name. The buffer both wrap is live and is not encoded.
326 * `id` is the id the Expanse had when saved and is informational.
327 */
329 uint32_t id {};
330 std::string subkind;
331 std::string fn_name;
332 std::string on_enter_fn_name;
333 std::string on_exit_fn_name;
334 std::optional<glm::vec3> bounds_min;
335 std::optional<glm::vec3> bounds_max;
336 std::optional<uint32_t> collection;
337 std::string fit_name;
338
339 static constexpr auto describe()
340 {
341 return std::make_tuple(
351 }
352};
353
354// =============================================================================
355// Fabric schema
356// =============================================================================
357
360 std::string fabric_name;
361 std::vector<EntityRecord> entities;
362 std::vector<ExpanseRecord> expanses;
364 std::optional<float> cell_size;
365
366 static constexpr auto describe()
367 {
368 return std::make_tuple(
375 }
376};
377
378// =============================================================================
379// Tapestry schema
380// =============================================================================
381
382/**
383 * @brief Entry in the Tapestry envelope pointing to one Fabric's EXR+JSON pair.
384 */
385struct FabricRef {
386 std::string name;
387 std::string base_path;
388
389 static constexpr auto describe()
390 {
391 return std::make_tuple(
394 }
395};
396
397/**
398 * @brief Tapestry-level named Expanse record. Lives in tapestry.json rather
399 * than any individual fabric file because Tapestry-owned Expanses may
400 * be registered on multiple Fabrics.
401 *
402 * `fabric_names` lists the Fabrics that had this Expanse registered at encode
403 * time. On reconstruct the decoder resolves Fabrics by name and calls
404 * Fabric::add_expanse for each. `subkind`, `collection` and `fit` are as in
405 * ExpanseRecord.
406 */
408 std::string name;
409 std::string subkind;
410 std::string fn_name;
411 std::string on_enter_fn_name;
412 std::string on_exit_fn_name;
413 std::optional<glm::vec3> bounds_min;
414 std::optional<glm::vec3> bounds_max;
415 std::optional<uint32_t> collection;
416 std::string fit_name;
417 std::vector<std::string> fabric_names;
418
433};
434
437 std::vector<FabricRef> fabrics;
438 std::vector<TapestryExpanseRecord> expanses;
439 nlohmann::json user_state;
440
441 static constexpr auto describe()
442 {
443 return std::make_tuple(
448 }
449};
450
451// =============================================================================
452// Kind helpers shared between encoder and decoder
453// =============================================================================
454
455/**
456 * @brief Map Fabric::Kind to its lowercase JSON string token via magic_enum.
457 */
458inline std::string kind_to_string(Fabric::Kind k)
459{
461}
462
463/**
464 * @brief Return true if @p s maps to a known Fabric::Kind token.
465 *
466 * Call this as a gate before parse_kind. Unrecognised strings should be
467 * warned and skipped at the call site; parse_kind assumes the string is valid.
468 */
469inline bool kind_known(std::string_view s)
470{
471 return Reflect::string_to_enum_case_insensitive<Fabric::Kind>(s).has_value();
472}
473
474/**
475 * @brief Parse a JSON kind token to Fabric::Kind (case-insensitive).
476 *
477 * Precondition: kind_known(s) is true. Behaviour is undefined for
478 * unrecognised strings; guard with kind_known before calling.
479 */
480inline Fabric::Kind parse_kind(std::string_view s)
481{
482 return *Reflect::string_to_enum_case_insensitive<Fabric::Kind>(s);
483}
484
485} // namespace MayaFlux::Nexus::State
constexpr uint32_t k_schema_version
Current schema version written by StateEncoder and accepted by StateDecoder.
Definition Schema.hpp:26
bool kind_known(std::string_view s)
Return true if s maps to a known Fabric::Kind token.
Definition Schema.hpp:469
Fabric::Kind parse_kind(std::string_view s)
Parse a JSON kind token to Fabric::Kind (case-insensitive).
Definition Schema.hpp:480
constexpr uint32_t k_schema_min_version
Oldest schema version StateDecoder still reads.
Definition Schema.hpp:32
constexpr uint32_t k_exr_rows
RGBA32F EXR layout constants shared between encoder and decoder.
Definition Schema.hpp:47
constexpr uint32_t k_channels
Definition Schema.hpp:48
WiringKind
Serializable wiring strategies.
Definition Schema.hpp:103
std::string kind_to_string(Fabric::Kind k)
Map Fabric::Kind to its lowercase JSON string token via magic_enum.
Definition Schema.hpp:458
PolygonMode
Rasterization polygon mode.
PrimitiveTopology
Vertex assembly primitive topology.
std::string enum_to_lowercase_string(EnumType value) noexcept
Universal enum to lowercase string converter using magic_enum.
constexpr auto opt_member(std::string_view key, std::optional< T > Class::*ptr)
Definition Mirror.hpp:43
constexpr auto member(std::string_view key, T Class::*ptr)
Definition Mirror.hpp:37
static constexpr auto describe()
Definition Schema.hpp:173
std::optional< LocusNavRecord > locus_nav
Definition Schema.hpp:283
static constexpr auto describe()
Definition Schema.hpp:287
std::optional< float > size
Definition Schema.hpp:276
std::optional< glm::vec3 > color
Definition Schema.hpp:275
std::vector< AudioSinkRecord > audio_sinks
Definition Schema.hpp:281
std::optional< float > falloff_radius
Definition Schema.hpp:285
std::optional< glm::vec3 > position
Definition Schema.hpp:270
std::vector< RenderSinkRecord > render_sinks
Definition Schema.hpp:282
std::optional< glm::vec4 > orientation
Definition Schema.hpp:271
Per-entity JSON record.
Definition Schema.hpp:266
std::optional< glm::vec3 > bounds_min
Definition Schema.hpp:334
std::optional< glm::vec3 > bounds_max
Definition Schema.hpp:335
static constexpr auto describe()
Definition Schema.hpp:339
std::optional< uint32_t > collection
Definition Schema.hpp:336
Per-expanse JSON record.
Definition Schema.hpp:328
static constexpr auto describe()
Definition Schema.hpp:389
Entry in the Tapestry envelope pointing to one Fabric's EXR+JSON pair.
Definition Schema.hpp:385
static constexpr auto describe()
Definition Schema.hpp:366
std::vector< EntityRecord > entities
Definition Schema.hpp:361
std::optional< float > cell_size
Definition Schema.hpp:364
std::vector< ExpanseRecord > expanses
Definition Schema.hpp:362
static constexpr auto describe()
Definition Schema.hpp:238
Serializable subset of Kinesis::NavigationConfig sufficient to seed a Locus on reconstruct.
Definition Schema.hpp:227
static constexpr auto describe()
Definition Schema.hpp:74
static constexpr auto describe()
Definition Schema.hpp:58
std::unordered_map< std::string, std::string > extra_string_params
Definition Schema.hpp:196
Portal::Graphics::PrimitiveTopology topology
Definition Schema.hpp:191
static constexpr auto describe()
Definition Schema.hpp:198
Portal::Graphics::PolygonMode polygon_mode
Definition Schema.hpp:192
Portal::Graphics::CullMode cull_mode
Definition Schema.hpp:193
Plain-data part of the sink buffer's RenderConfig.
Definition Schema.hpp:185
std::optional< glm::vec3 > bounds_max
Definition Schema.hpp:414
std::vector< std::string > fabric_names
Definition Schema.hpp:417
std::optional< glm::vec3 > bounds_min
Definition Schema.hpp:413
Tapestry-level named Expanse record.
Definition Schema.hpp:407
std::vector< FabricRef > fabrics
Definition Schema.hpp:437
std::vector< TapestryExpanseRecord > expanses
Definition Schema.hpp:438
static constexpr auto describe()
Definition Schema.hpp:441
std::optional< Vruta::ProcessingToken > interval_token
Definition Schema.hpp:135
std::optional< IO::Keys > key
Definition Schema.hpp:137
std::optional< size_t > times
Definition Schema.hpp:133
std::optional< Vruta::ProcessingToken > duration_token
Definition Schema.hpp:136
std::optional< double > interval
Definition Schema.hpp:131
static constexpr auto describe()
Definition Schema.hpp:145
std::optional< std::vector< WiringStep > > steps
Definition Schema.hpp:134
std::optional< IO::MouseButtons > button
Definition Schema.hpp:138
std::optional< double > duration
Definition Schema.hpp:132
static constexpr auto describe()
Definition Schema.hpp:121