Skip to content

AutoRun pipelines and live updates

An Algorithm with AutoRun set runs by itself when:

  • the object on its (object) input emits Updated();
  • an object on one of its output ports emits UpdateRequested() (see Plots for the histogram that does this);
  • for a Recipe, an object on one of its declared input ports emits Updated(). Wiring probe.Events → recipe.Events is therefore enough; no separate (object) wire is needed. Other algorithms opt in through FollowsInputPorts(). A Scene doesn't, because several of its "inputs" are things a run writes into.

Switching AutoRun on, or wiring a new object to one of the ports it follows, runs the algorithm once, so it starts from what is there.

When a run starts, the algorithm emits RefillStarted() on each of its output objects. A Histogram or PointSet with ResetOnRefill (the default) empties itself there, so a re-run replaces its contents. When a run finishes, the algorithm emits Updated() on each of its output objects and then on itself. Anything following them reacts next, which is how a chain carries a change from one end to the other.

Live, but not once per mouse move

Dragging an object in a viewport emits Updated() on every mouse move. Running a pipeline on each of those would stall the interface. Running it only when the drag stops would make it anything but live.

So, when the application defers work (gcompose does; tests and batch runs do not), an AutoRun algorithm reacting to an edit is throttled:

  • the edit returns at once; the algorithm runs from the event loop;
  • while edits keep coming, it runs at most once per interval, each time on the state as it is at that moment;
  • after the last edit, it runs once more, so the final state is always the one on screen;
  • an update that arrives while the algorithm is already running (in the background, say) queues exactly one more run after it;
  • updates raised by a run (the rest of a chain) run synchronously behind the chain's head, as before, so a loop still stops at the algorithm that started it;
  • a scheduled run for an algorithm that has been destroyed, or whose AutoRun was switched off, does nothing.

The same throttle is available to anything else as uLib::CoalescedCall (src/Core/UpdateScheduler.h). A PlaneProbe uses it for its replays (see A plane probe). The node graph refreshes its nodes at most every 50 ms. A ROOT canvas redraws once per pass of the event loop, however many of its plots changed.

Configuring it

  • In gcompose: Preferences ▸ General ▸ AutoRun interval (default 50 ms). Raise it if a heavy pipeline makes dragging stutter.
  • In code: uLib::UpdateScheduler.
  • SetPoster() installs the function that hands a task to the event loop. gcompose's is in app/gcompose/src/DeferredUpdates.h.
  • SetAutoRunInterval() sets the interval.
  • With no poster installed, everything runs synchronously.
  • Console and batch sessions (gcompose --console, --recipe … --batch) do not defer. A script there reads the result of an edit on its next line.