-
Notifications
You must be signed in to change notification settings - Fork 6
Architecture
dynamic-neural-field-composer/
βββ application/ Application entry point and GUI lifecycle
βββ simulation/ Time-stepped simulation engine + JSON persistence
βββ elements/ All element types (neural fields, kernels, couplings, ...)
βββ element_parameters/ Shared parameter structs and element identity types
βββ visualization/ Plot management (line plots, heatmaps)
βββ user_interface/ ImGui windows (node graph, inspector, metrics, ...)
βββ tools/ Logger, math utilities, profiling, file dialogs
βββ exceptions/ Custom exception hierarchy
| Namespace | Contents |
|---|---|
dnf_composer |
Simulation, Visualization, Application, Exception, learning rules |
dnf_composer::element |
All element classes and their parameter structs, ElementFactory
|
dnf_composer::user_interface |
All ImGui window classes |
dnf_composer::tools::logger |
Logging utilities |
dnf_composer::tools |
Math, profiling, utils |
βββββββββββββββββββββββββββββββββββββββββββ
β Application β GUI lifecycle, window management
ββββββββββββββββββββ¬βββββββββββββββββββββββ€
β Visualization β User Interface β Plotting, node graph, inspectors
ββββββββββββββββββββ΄βββββββββββββββββββββββ€
β Simulation β Element management, time loop
βββββββββββββββββββββββββββββββββββββββββββ€
β Elements β Neural fields, kernels, couplings
βββββββββββββββββββββββββββββββββββββββββββ€
β Tools / Exceptions β Logger, math, profiling, errors
βββββββββββββββββββββββββββββββββββββββββββ
Each layer depends only on layers below it. The Application drives both the Simulation and the Visualization; neither of them knows about the other's internals.
-
Setup β create
Simulation,Visualization,Application; add windows; create elements and wire interactions; register plots -
Init β
app.init()initializes the GUI and callsSimulation::init()on all elements -
Loop β
app.step()callsSimulation::step()(advances all elements bydeltaT) andVisualization::render()(updates plots), then renders the ImGui frame -
Shutdown β
app.close()tears down the GUI and frees resources
app.init()
βββΊ simulation.init()
βββΊ element.init() [for each element]
app.step() [called every frame]
βββΊ simulation.step()
β βββΊ element.step(t, deltaT) [for each element]
βββΊ visualization.render()
βββΊ [update each plot from simulation components]
Elements form a directed graph. Each element holds references to its input elements and reads from a named component (e.g. "output") during step(). Interactions are explicit: calling a->addInput(b) registers b as a source for a.
Every element exposes its internal state as named std::vector<double> buffers called components (e.g. "activation", "output", "input", "weights"). The visualization and UI read from these buffers directly, with no coupling to the element's type.
ElementFactory::createElement() is one way to construct elements: it takes an ElementLabel enum and typed parameter structs, decoupling callers from concrete constructors. This is the path used by the JSON loader and wherever the element type is chosen at runtime. Elements can equally be constructed directly with std::make_shared<ConcreteType>(commonParams, specificParams) β the type-safe approach used by the examples and most application code.
SimulationFileManager serializes and deserializes the full element graph to/from JSON. It is invoked via Simulation::save() and Simulation::read(). Each simulation's files are co-located under data/<simulation_name>/:
data/
βββ <simulation_name>/
βββ <simulation_name>.dnf # element graph + parameters
βββ <coupling_name>_weights.txt # FieldCoupling weight matrix (one file per coupling element)
βββ exports/ # snapshot CSV files (one per takeSnapshot() call)
βββ recordings/ # time-series CSV files (one per startRecording() session)
SimulationRecorder (owned by Simulation, accessible via getRecorder()) manages ongoing time-series recordings and one-shot snapshot exports. It is called automatically from Simulation::step() and closed in close() / clean().