Migrating to the reactive engine

This page is migration-oriented: it maps the APIs of the dependency-graph engine to their reactive replacements, for those maintaining custom simulator extensions written against earlier releases. The current model is described in the metamodel and in the reaction scheduling pages.

Scheduling

  • The engine no longer computes a dependency graph. Reactions own their schedule and publish it through the observable nextOccurrence of Reaction; the engine reindexes a reaction whenever it emits. Context, Dependency, input and output contexts, inbound and outbound dependencies, and Condition.getDependencies() no longer exist: a reaction subscribes to the observable model state it reads.
  • The batch engine, its batched schedulers, and EngineConfiguration were removed: use Engine. Launcher parameter batches are still supported.
  • TimeDistribution only samples delays (sample()) and creates fresh instances for cloned reactions (newInstanceOn); the reaction owns the occurrence time, the rate (TimeDistributedReaction), and the rescheduling policy.
  • Event is now GenericReaction; one-shot behavior is provided by AbsoluteEvent and ConditionalEvent. Environment-wide reactions are ordinary reactions hosted by the environment, which, like nodes, is a ReactionHost.

Reactions, conditions, and actions

  • Reactions expose their fixed host, and hosts register only their own reactions.
  • Conditions and actions expose the reaction owning them instead of their node; the host, and possibly the node, are reached through it. A reaction rejects conditions and actions owned by other reactions.
  • Cloning takes the new owner only: cloneCondition(newReaction) and cloneAction(newReaction).
  • Extend the base class matching what the condition or action works on:
  • Condition validity is the observable isValid property; install it with setValidity from model observables (concentrations, neighborhoods, positions, layers, …). Conditions no longer contribute to propensities: specialized reactions read the typed inputs they need. reactionReady is now beforeReactionFires.
  • Constructors take the owning reaction where they used to take the node. In YAML, the reaction is injected like the environment and the node; in the Kotlin DSL, the generated builders take it from the context.

Model state

  • Node contents, neighborhoods, positions, node counts, range queries, layer values, and host reactions are observable: consumers subscribe to them instead of polling. Environment.nodes is an observable list, read through current.
  • Layers are associated with the environment during setup and cannot be added afterwards; their values may change over time, so read them through Environment.observeLayerValue.
  • Node properties are part of the node setup: they cannot be added once the node is in an environment.
  • Movement: Environment.moveNodeTo moves to an absolute position and EuclideanEnvironment.moveNodeBy by a displacement (formerly moveNodeToPosition and moveNode). Environments constraining movements override moveNodeTo, so their constraints apply to both.
  • Java serialization is no longer supported by the model, the engine, and the loaders.