Execution Graphs
Graphs are a way for you to orchestrate things in your UI. The primary use case is for sequencing animations but there are plenty of use cases for this if you think outside the box a bit.
If you've used Behavior Trees, this will be quite familiar to you. The basic idea is that you execute a list of actions either sequentially or in parallel.
Here is an example. We have a box that we want to animate to the center of the screen. Wait for half a second, then rotate 180 degress while changing color.
Action<ElementHandle> graphBuilder = (root) => {
// we run a sequence of steps that execute one after the other
sequence(() => { // this isn't actually needed since the default graph root is already a sequence,but its here for illustration purposes
// run the first animation phase,use a parallel() because both animations should run at the same time
parallel(() => {
root.AnimateAlignmentOffsetX(Spring.Default.AnimateTo(new AlignmentOffset(0.5, AlignmentOffsetUnit.ScreenWidth));
root.AnimateAlignmentOffsetY(Spring.Default.AnimateTo(new AlignmentOffset(0.5, AlignmentOffsetUnit.ScreenHeight));
});
log("finished animating phase 0");
// when done animating, wait half a second
pause(500);
log("finished waiting 500 milliseconds");
// now animate rotation and background color at the same time
parallel(() => {
root.AnimateRenderTransform(Tween.LinearTo(new RenderTransform().Rotate(180));
root.AnimateBackgroundColor(Tween.CubicEaseInTo(Color.red));
});
log("finished animating phase 1");
});
}
GraphInstance graph = Graph.CreateGraph(someElement, graphBuilder);
graph.Execute(); // call this to tick the graph every frame
There are lots of baked in graph node types. They all live on the static class Graph
.
It is recommended to use using static EvolveUI.ExecutionGraph.Graph;
statement so you don't need to write Graph.xyz
in front of all your commands.graph
Sequence sequence(Action a)
Runs a set of steps sequentially. Each step will run until it completes, then the next step will run
Parallel parallel(Action a)
Runs a set of steps in parallel. This node completes when all of its children are finished
Log log(string message)
Logs the message and completes immediately
Log log(Func<string> fn)
Logs the result of the function and completes immediately
Pause pause(int milliseconds)
Pauses for the set number of milliseconds and completes when the duration has elapsed
AwaitEvent awaitEvent(string eventName)
Waits until the graph receives an event with the given eventName
EmitEvent emitEvent(string eventName)
Emits an event with eventName
on the graph and completes immediately
WaitFrames waitFrames(int frameCount)
Waits frameCount
frames and then completes
Custom Graph nodes
you can define your own graph actions by extending GraphNode
. You just need to set IsCompleted
at the right time and implement your Update
override
Other Graph Nodes
the ElementHandle
type provides wrappers around other node types like SetAttribute
and Animate..