Patch Notes 0.3.1 to 0.3.4
MayaFlux 0.3.1
26th April 2026
Targets removal of deprecated creational API and correctness fix in the Lila JIT compiler subsystem.
Fixes
Lila FreeType include path injection
ClangInterpreter was missing the -isystem flag for FreeType headers, causing runtime evaluation of code including <ft2build.h> to fail with unresolved dependencies. The JIT compiler now mirrors the existing Eigen include injection pattern, resolving the path via Config::FREETYPE_HINT (populated at configure time from find_package(Freetype)) with fallback to well-known system paths in HostEnvironment. Live coding workflows using Portal text rendering can now evaluate user code without manual include path specification.
Breaking Changes
Removal of CreationProxy and pipe operator overloads
CreationProxy<T>, PendingChannel<T>, and all operator| overloads for domain binding have been removed. This was announced at 0.3.0 and documented throughout the 0.3 development cycle.
Migrate all call sites from the deprecated bracket-pipe syntax to the committed pipe-bracket syntax:
// Old (removed)
object[ch] | Audio
object[{0,1}] | Audio
// New (required)
object | Audio[ch]
object | Audio[{0,1}]
Creator methods now return std::shared_ptr<T> directly without intermediary proxy objects. The domain binding is resolved at the call site via DomainSpec::operator[].
Removed symbols:
CreationProxy<T>PendingChannel<T>operator|(shared_ptr<Node>, Domain)and typed variantsoperator|(PendingChannel<T>, CreationContext)- All
MAYAFLUX_API Domain operator|declarations
Upgrade Notes
Not a drop-in replacement. Any code using the bracket-pipe syntax ([ch] | Audio) must be migrated to pipe-bracket syntax (| Audio[ch]) before compilation. The upgrade is mechanical: swap the order of the bracket and pipe operators, keeping the channel argument within the brackets.
No functional changes to committed systems. The DomainSpec pipe syntax and channel binding semantics remain stable.
Commit Summary
See full diff: Github
91c96da8b prepare for 0.3.1 release
5962cec00 fix(Lila): inject FreeType include path into JIT compiler flags
e14d29ab2 refactor(API): remove CreationProxy, PendingChannel, and Domain operator| overloads (0.3.1)
MayaFlux 0.3.2
1st May 2026
Targets correctness bugs in mesh loading, engine lifecycle, GLFW platform selection, and Linux shutdown semantics.
Fixes
MeshNetworkBuffer texture binding collision
Per-slot diffuse textures in MeshNetworkBuffer were bound at binding=2+i, colliding with the slotIndices SSBO already occupying binding=2 in set=0. The descriptor set reported a type mismatch (STORAGE_BUFFER vs COMBINED_IMAGE_SAMPLER) and crashed on the first textured model load. Per-slot texture bindings have been moved to binding=3+i, reserving binding=2 exclusively for the slotIndices buffer. set=0, binding=0 remains reserved for the engine-owned ViewTransform UBO.
MeshNetworkProcessor geometry upload on attachment
MeshNetworkProcessor::on_attach called upload_combined against an unsorted sorted_indices vector, cleared all dirty flags, and then never uploaded geometry on subsequent frames because rebuild_sort() was lazy and only fires inside process_batch. Added ensure_sorted() to MeshNetwork and call it at the top of on_attach to guarantee slot order before the first GPU upload.
Engine initialization state conflation
is_engine_initialized tracked two distinct concerns: whether Init() has completed and managers are ready, and whether the engine is actively processing. Split into is_engine_configured (Init() succeeded, managers ready) and the existing is_running() (actively processing). Added Engine::is_configured(), Core::is_configured(), and public API is_engine_configured(). All internal call sites updated to query the appropriate state.
GLFW platform hint resolution
force_x11_on_wayland resolution was a separate pre-pass before platform hint application, leaving the hint unapplied when the sentinel matched. Folded resolution into the existing platform switch in configure(). GLFW_ANY_PLATFORM is now the sentinel for “do not hint”; the hint is only applied when a non-default platform is resolved. Default behaviour (no forced platform) is unchanged.
Linux shutdown gate robustness
The engine shutdown gate on Linux used std::cin.get(), which blocks indefinitely in headless contexts (GUI launchers, capture tools) and returns immediately on EOF (piped input), making graceful shutdown impossible in those environments. Replaced with a sigaction/select loop: TTY contexts block on select and exit on Return or signal; non-TTY contexts block on sigsuspend until SIGINT or SIGTERM. Static atomic reset on entry handles engine recreation in the same process.
Upgrade Notes
No API changes. Drop-in replacement for 0.3.1. The is_engine_initialized query remains available but should be migrated to is_engine_configured() if initialization state distinction is relevant; is_running() covers the active processing case.
Commit Summary
See full diff: Github
946717a81 prepare for 0.3.2 release
7df1cd1d3 fix(engine): robust shutdown gate for Linux across terminal and headless contexts
fe491465d fix(windowing): resolve GLFW platform hint before applying in configure()
1a72d8c4e refactor: separate engine configuration state from runtime state
356a88bc4 fix(MeshNetworkBuffer): move per-slot texture bindings from binding=2 to binding=3
d41eae286 fix(MeshNetworkProcessor): ensure slot sort order before first GPU upload in on_attach
MayaFlux 0.3.3
5th May 2026
Unifies temporal channel binding with DomainSpec and fixes library installation paths on multi-lib systems.
Breaking Changes
Temporal channel binding unified with DomainSpec
Time() now takes duration only. Channel binding moves to the domain site via DomainSpec::operator[], consistent with Creator methods introduced in 0.3.1.
// Old (removed)
node >> Time(2.0, 0) | Audio;
node >> Time(2.0, {0, 1}) | Audio;
buffer >> Time(2.0, 0) | Audio;
// New (required)
node >> Time(2.0) | Audio[0];
node >> Time(2.0) | Audio[{0, 1}];
buffer >> Time(2.0) | Audio[0];
net >> Time(2.0) | Graphics;
Removed symbols:
TimeSpec::channelsfieldTime(double, uint32_t)constructorTime(double, vector<uint32_t>)constructoroperator|overloads takingDomainin Temporal.hpp/cpp
Changed:
operator|overloads in Temporal now takeconst CreationContext&instead ofDomain- Channel extraction moves from
spec.channelstoctx.channel/ctx.channels - Temporal.hpp replaces
#include "Domain.hpp"with#include "Creator.hpp"to gainCreationContext,DomainSpec,Audio, andGraphics
This completes the DomainSpec unification announced at 0.3.0, deprecated in previous versions, and documented in all release notes. Temporal scheduling now aligns with the committed pipe-bracket syntax across all domains.
Fixes
CMake installation paths on multi-lib systems
Hardcoded lib install paths in install.cmake and MayaFluxConfig.cmake.in were incompatible with Fedora and other distributions using lib64 for 64-bit libraries. Replaced with CMAKE_INSTALL_LIBDIR, which resolves correctly across all GNU install directory conventions. Removes the manual mv workaround from packaging specs.
Upgrade Notes
Not a drop-in replacement. Any code using Time(seconds, channel) or Time(seconds, {channels}) must migrate to Time(seconds) | Audio[...] before compilation. The upgrade is mechanical: extract the channel argument, move it after the pipe, and wrap it in brackets with the domain.
Library installation now targets lib64 on 64-bit Fedora/RHEL systems without manual correction.
Commit Summary
See full diff: Github
d5f2f28f7 Prepare for 0.3.3 release.
ee1a8ca75 refactor(api): unify Temporal channel binding with DomainSpec
d267d523b fix(cmake): use GNUInstallDirs for lib directory resolution
MayaFlux 0.3.4
7th May 2026
Targets correctness fixes in operator token release and ResonatorNetwork output, CMake library path resolution, operator shutdown safety, and operator collection access patterns. Adds parameterized path generation and operator accessors for external coroutine integration.
Fixes
PhysicsOperator and TopologyOperator token release
PhysicsOperator::add_collection and TopologyOperator::add_topology acquired m_access_token via CAS spin but never released it, causing subsequent process() calls to spin forever. Added store(0) after each push_back to release the token.
ResonatorNetwork output mode and shadowed buffer
ResonatorNetwork defaulted to OutputMode::NONE at construction, causing Creator::register_network to fire a spurious warning and rely on the forced-AUDIO_SINK path. Set AUDIO_SINK explicitly in both constructors.
ResonatorNetwork declared a duplicate m_last_audio_buffer member shadowing the base class NodeNetwork field in the protected section. The shadow caused apply_output_scale() and get_audio_buffer() to operate on different vectors, producing incorrect output and potential memory corruption at scale. Removed the duplicate declaration.
Operator shutdown hang on access token spin
The CAS spin on m_access_token in PathOperator, TopologyOperator, and PhysicsOperator had no exit path on engine shutdown, causing the graphics thread to hang indefinitely if destruction occurred while a spin was in progress. Added std::atomic<bool> m_shutdown to each operator. The destructor sets it with release ordering; the spin loop checks it with relaxed ordering on each failed CAS and returns immediately if set. The relaxed check is correct because the destructor’s release store establishes the required happens-before relationship.
CMake library path resolution on non-Fedora installs
CMAKE_INSTALL_LIBDIR expands to a relative segment (“lib”) on most platforms and an absolute path ("/usr/lib64") on Fedora only. Relative paths caused IMPORTED_LOCATION to resolve relative to the build directory rather than the install root. Guarded with IS_ABSOLUTE: if relative, prepend PACKAGE_PREFIX_DIR to produce the correct absolute path. Fedora’s absolute path is left unchanged. No platform branching required.
Features
Parameterized path generation
PathOperator::add_path previously hardcoded 1024 max control points and forwarded the operator’s default samples per segment. Callers can now configure per-path capacity and interpolation parameters directly via new optional arguments. initialize and initialize_paths updated to forward m_default_samples_per_segment.
Operator collection accessors
Added get_path and get_topology accessors on operator collections, exposing indexed access to PathGeneratorNode and TopologyGeneratorNode instances. External coroutines can now call add_control_point and set_points directly without routing through the network layer.
TopologyOperator samples-per-segment dispatch
Added typed set_samples_per_segment on TopologyOperator forwarding to all topology nodes. PointCloudNetwork::set_samples_per_segment now dispatches to both PathOperator and TopologyOperator rather than warning on topology mode.
Operator vertex count aggregate
PathOperator, TopologyOperator, and PhysicsOperator were returning the vertex count from collection 0 only in get_vertex_layout. With NetworkGeometryBuffer driving the draw call directly from the layout, the count must reflect the full aggregate across all collections.
Nexus MouseTrigger capture safety
Wiring is a temporary builder destroyed after finalise(). The MouseTrigger lambda previously captured [this, id], leaving a dangling reference to the builder. Snapshot m_fabric and m_entity_id into named locals before the lambda to outlive the builder lifetime.
CompositeGeometryBuffer public registration
Added forward declaration and ALL_BUFFER_REGISTRATION entry for CompositeGeometryBuffer alongside the include in MayaFlux.hpp, enabling proxy-based instantiation.
Upgrade Notes
No API changes. Drop-in replacement for 0.3.3.
New optional parameters on PathOperator::add_path are backward compatible; existing calls without them use operator defaults as before. New accessors and dispatch methods are additive.
Commit Summary
See full diff: Github
e2ad692d5 prepare for 0.3.4 release
777c63b31 fix: operator token release, ResonatorNetwork output mode, shadow buffer
c951d177b fix(cmake): resolve relative CMAKE_INSTALL_LIBDIR for non-Fedora installs
259addd10 fix(operators): add shutdown guard to access token spin in PathOperator, TopologyOperator, PhysicsOperator
b6cf200ff feat(operators): atomic access token for collection mutation in PathOperator, TopologyOperator, PhysicsOperator
68d6aa576 feat(nodes): expose samples_per_segment, max_control_points and tension on add_path
04df085dd fix(nodes): set aggregate vertex_count on get_vertex_layout for collection operators
72309935e fix(nexus): capture Fabric by ref and entity id by value in MouseTrigger lambda
c3af0fb06 feat(nodes): extend set_samples_per_segment to TopologyOperator
35347dbe2 feat(nodes): add get_path and get_topology accessors on operator collections
3ccccfed6 feat(buffers): register CompositeGeometryBuffer in proxy registry and public header