Skip to content
Archevolt
Esc
↑↓navigate↵open⌘Jpreview
On this page

Schedules and conditions

Order systems with Run declarations, stages, sets, and run conditions.

public static partial class Conditions
{
    [RunCondition]
    public static bool Enabled(scoped OptionalRes<FrameTime> time) => time.HasValue;
}

[Schedule]
[Run(typeof(Motion), nameof(Motion.Move), Order = 0,
    ConditionOwner = typeof(Conditions), Condition = nameof(Conditions.Enabled))]
public sealed partial class Simulation;

Simulation.Create(world) returns a BoundSchedule.

Run declarations

Every Run declaration requires a unique Order and instance key. The default key is the qualified owner and method name. Repeated registrations use distinct Instance values.

Order breaks ties among ready nodes. It does not replace an explicit semantic dependency.

Property Meaning
Order Tie-breaker among ready nodes.
Instance Distinguishes repeated registrations of one method.
Before / After Dependency on an instance key or an unambiguous method name.
BeforeOwner / AfterOwner Qualifies the method reference.
Stage / Set Group membership.
Condition / ConditionOwner Run condition. ConditionOwner defaults to the run’s owner.

Stages and sets

[Stage("name", Order = n)] and [SystemSet("name", Order = n)] define ordered groups. Names and orders must be unique within each group kind.

  • Declaring stages requires every run to name a known stage. Set membership is optional.
  • Earlier groups precede later groups through dependency edges.
  • Contradictory group and explicit dependencies are cycles (AV007).

Conflicts

When two systems conflict and have no explicit dependency, the planner supplies a conservative order and reports the warning AV008. Add Before or After to make the order intentional.

Run conditions

A [RunCondition] method is synchronous, static, and returns bool. It may read queries, unmanaged resources, messages, and removal records, and mutate its own locals. Writable world access, managed resources, and commands are rejected. The condition’s required types must be included in the world’s module registrations.

The condition evaluates once when its node is ready, after predecessor barriers. A false result completes dependency ordering without running the body or advancing the body’s change cursor. Successful false evaluations advance the condition’s own cursor. A partitioned body still evaluates its condition only once.

Runtime composition

The runtime exposes the same planner:

using var schedule = BoundSchedule.Bind(world,
    [Motion.Move_Descriptor, MotionKernel.Move_Descriptor],
    [new Archevolt.Scheduling.EdgeInput(0, 1)],
    instanceKeys: ["motion", "kernel"],
    orders: [0, 1],
    conditions: [Conditions.Enabled_Descriptor, null]);

Edge endpoints index the supplied system array. Optional keys, orders, and conditions arrays must match its length. Omitting orders uses array order. Build a runtime condition descriptor with AsCondition() and a factory returning ConditionBody.

Inspecting the plan

BoundSchedule.Plan exposes immutable node order, edges with reasons, batch membership, barriers, and diagnostics. Both serial and parallel execution follow this plan.

Timing

schedule.EnableTiming() enables preallocated inspection metrics. schedule.Timings returns a readonly span of immutable SystemTiming entries in input-system order. Both operations require an idle world and its owner thread. Calling EnableTiming clears previous measurements, including when timing is disabled with EnableTiming(false).

Metrics describe the most recent run:

Metric Meaning
BodyInvocations Executed callbacks. A partitioned invocation contributes one per dispatched partition.
BodyFailures Callbacks that threw.
SkippedByCondition Whether a false condition skipped the body.
ConditionEvaluations, ConditionFailures Describe the node’s separate condition instance.
BodyElapsedTicks, BodyElapsed Sum of callback durations across partitions, excluding time waiting for dispatch. This is combined execution time, not wall-clock latency.
ConditionElapsedTicks, ConditionElapsed Condition evaluation time.

Raw ticks use System.Diagnostics.Stopwatch.Frequency, and the TimeSpan properties expose the same values.

Measurements are available after joined failures as well as successful runs. A copied SystemTiming is a value snapshot. The returned span is a view that changes after the next measured run or timing configuration change. Disabled timing reports zero counters and durations, takes no timestamps, and allocates no measurement objects during execution.

Was this page helpful?