Node class

Overview

Nodes are the building block of Ignis. They are organized in a directed, acyclic tree, with children ordered by priority. Nodes may be assembled into subtrees using add and remove any number of times.

Building

Nodes should initialize children, connect signals, and add tick behavior in their build method. build is called every time a node is mounted to a live scene, or as the root of its own scene with mount.

build must be safe to run more than once. It tracks every node added and every signal subscribed inside it. Resources needing disposal go in the trash.

Lastly, a reload reboots the internals of every node: added children are removed, signals unsubscribed, the trash processed, and build run again. What survives is the node itself, and whatever it named with Live.keep.

Do not make build async.

Signals

Nodes communicate time-sensitive events through signals: named, type-safe message emitters. Use one to report an event to consumers, or as an input to react to external events.

Conventionally, signals are prefixed with the word on. For example, the signal a collider emits on contact is named onCollisionStart. This allows consumers to have a natural-reading constructor, e.g. onCollisionStart(/* do stuff */);.

Scenes

Nodes may be mounted to a Scene, which drives them with a game loop. When mounted, the scene will propagate through the entire subtree emitting the onMount signal on each node, from top to bottom. Unmounting does the reverse, emitting the onUnmount signal from the leaves upward.

Tree

Before being mounted, the add, remove, and priority tree operations take effect immediately, allowing a subtree to be freely assembled long before it goes live.

Once mounted, however, the same calls are instead merely enqueued. The scene applies pending changes right before the next update. As a result, operations for live node trees are always delayed a frame. The queue avoids mutation during iteration and batches changes.

Dependency Injection

Nodes come integrated with a type-based dependency injection (DI) system. A node may provide a value to its entire subtree, keyed by its type. read resolves the nearest match, checking the node itself before its ancestors.

Reassembly

When code is reloaded, the scene walks the tree rebuilding every node. Unlike update and render, the walk ignores the enabled flag, so even disabled nodes are rebuilt. It runs whenever the SceneWidget reassembles in the Flutter tree.

By default nothing rebuilds. A Live node rebuilds, keeping only what Live.keep names.

Implementers
Available extensions

Constructors

Node({bool? enabled, int? priority, Iterable<Node> children = const []})
Creates a new node.

Properties

activity ↔ Activity
What this node takes part in: ticking, rendering, and hearing input. Defaults to Activity.all.
getter/setter pair
ancestors → Iterable<Node>
This node's ancestors in the tree.
no setter
children → Iterable<Node>
This node's direct children.
no setter
descendants → Iterable<Node>
This node's descendants in depth-first preorder.
no setter
enabled ↔ bool
Whether this node ticks, renders, and hears input, all three.
getter/setter pair
hashCode → int
The hash code for this object.
no setterinherited
hasParent → bool
True if this node has a non-null parent.
no setter
isMounted → bool
True while this node is part of a mounted tree.
no setter
isRemoving → bool
True while this node awaits removal at the next flush.
no setter
onMount → Signal0
Emitted when this node is added to a scene.
final
onSceneResize → Signal1<Vector2>
Emitted when the scene resizes, and once at mount.
final
onUnmount → Signal0
Emitted when this node is removed from a scene.
final
parent → Node?
The parent that owns this node, or null when it is parentless.
no setter
priority ↔ int
This node's order in updating and rendering in its parent. Defaults to 0.
getter/setter pair
runtimeType → Type
A representation of the runtime type of the object.
no setterinherited
scene → Scene<Node>
This node's owning scene. Only valid while isMounted.
no setter

Methods

add<T extends Node>(T node) → T
Adds node to this node. The node is returned.
addAll(Iterable<Node> nodes) → void
Adds all nodes to this node.
attach(Node node) → void
Adds this node to the target node.
build() → void
Declares this node's children and behavior.
contains(Node other) → bool
Checks if this node contains the other node in its tree.
containsPoint(Vector2 point) → bool
Whether this node's hit area contains point.
cycles(Node node) → bool
True if node is (or soon will be) an ancestor of this node.
debugDraw(DebugDraw draw) → void
Draws to the debug overlay every frame, in the same space as draw.
debugRender(Canvas canvas) → void
Renders the debug overlay for this node and its children to canvas.
debugRenderSelf(Canvas canvas) → void
Runs this node's debugDraw callbacks, in the same space as renderSelf.
detach() → bool
Removes this node from its parent, or from the parent it is on its way to.
disable() → void
Disables this node, so it stops updating, rendering and answering.
draw(Draw draw) → void
Draws to canvas every frame, in this node's own coordinate space.
enable() → void
Enables this node, so it resumes updating, rendering and answering.
hitTest(Vector2 point) → Iterable<Node>
Finds every node in this subtree whose hit area contains point, per containsPoint, topmost first. A node hearing no input hides its whole subtree.
mount() → Scene<T>

Available on T, provided by the Mount extension

Mounts this node as the root of a new Scene and returns it.
noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.
inherited
owns(Node other) → bool
Checks if this node owns the other node.
provide<T>(T value) → void
Provides value as this node's instance of T, overwriting any value previously provided for T.
query<T extends Node>() → Iterable<T>
This node's direct children of type T, in priority order.
read<T>() → T
As readOrNull, but throws a StateError when nothing provided T.
readOrNull<T>() → T?
Reads the nearest instance of T provided by this node or an ancestor, checking this node first. Returns null if none was provided.
remove(Node node) → bool
Removes the child node.
removeAll() → void
Removes all children.
render(Canvas canvas) → void
Renders this node and its children to canvas.
renderChildren(Canvas canvas) → void
Renders this node's enabled children to canvas, in priority order.
renderSelf(Canvas canvas) → void
Runs this node's draw callbacks.
tick(Tick tick) → void
Calls tick with the elapsed seconds on every frame.
toString() → String
A string representation of this object.
inherited
trash(Cleanup cleanup) → void
Defers cleanup until this build stops being current.
traverse({bool prune(Node node)?}) → Iterable<Node>
This node and its subtree, in postorder: every child before its parent, and children in reverse priority order.
update(double dt) → void
Updates this node and its children by dt seconds.

Operators

operator ==(Object other) → bool
The equality operator.
inherited