Skip to main content

Ordering

This library makes no ordering guarantee by default. When a group is ran, its children may run in any arbitrary order.

The library does however provide methods so you can guarantee that a node will run before or after another node.

Before & After

You can use Node:Before() to make a node run before another node.

local scheduler = require(path.to.scheduler)
local function wrapPrint(msg)
return function()
print(msg)
end
end

local root = scheduler.newGroup("root")
local node1 = scheduler.newSystem("node1", wrapPrint("node1 ran!")):In(root)
local node2 = scheduler.newSystem("node2", wrapPrint("node2 ran!")):In(root)

node2:Before(node1)
root:Run(0)
--> node2 ran!
--> node1 ran!

And likewise, you can use Node:After() to make a node run after another one.

local root = scheduler.newGroup("root")
local node1 = scheduler.newSystem("node1", wrapPrint("node1 ran!")):In(root)
local node2 = scheduler.newSystem("node2", wrapPrint("node2 ran!")):In(root)

node2:After(node1)
root:Run(0)
--> node1 ran!
--> node2 ran!
danger

:Before() & :After() require the two nodes to share the same parent.

tip

You can chain :Before() & :After() with :In().

local node2 = scheduler.newSystem(...):In(root):Before(node1)
local node3 = scheduler.newSystem(...):In(root):After(node1)

Implicit parenting

As stated above, in order to use :Before() & :After() between two nodes, they need to be assigned to the same group. However you may find yourself making a system where you don't really care what group it's in, and just want it to run before or after another system.

When you use :Before() or :After() on a node that's missing a parent, it will automatically get assigned to the other node's parent.

local heartbeat = scheduler.newGroup("Heartbeat")

local updatePosition = scheduler.newSystem("updatePosition", ...):In(heartbeat)
local updateVelocity = scheduler.newSystem("updateVelocity", ...):Before(updatePosition)
-- updateVelocity will automatically be assigned to the heartbeat group
warning

In order for implicit parenting to work, the targeted node needs to already have a parent set before calling :Before() / :After().

Support for assigning parent at a later point will be explored in a future version.

Complex graphs


local root = scheduler.newGroup("root")
local node1 = scheduler.newSystem("node1", wrapPrint("node1 ran!")):In(root)
local node2 = scheduler.newSystem("node2", wrapPrint("node2 ran!")):In(root)
local node3 = scheduler.newSystem("node3", wrapPrint("node3 ran!")):In(root)
local node4 = scheduler.newSystem("node4", wrapPrint("node4 ran!")):In(root)

node2:After(node1)
node3:Before(node1):Before(node2):After(node4)

root:Run(0)
--> node4 ran!
--> node3 ran!
--> node1 ran!
--> node2 ran!