Article Logo
Systems

Systems are the core unit of the engine that is responsible for invoking engine logic. All of the systems are organised in a schedule, which itself is split into stages. Stages run sequentially in the order that is specified during app building stage.

  1. Stage
  2. System.
  3. Condition.
  4. Threading.

Stage

To simiplify logic organisation of the app, it is possible to split logic onto stages which will be independent from each other. Meaning that they do not share any state or could run in parallel. Stages can be added to the app using Bvr::App::AddStage to just add a stage, Bvr::App::AddStageBefore or Bvr::App::AddStageAfter to add a stage at a specific position relative to some other stage. Aa menitoned, Beaver is fully build using this workflow, so it exposes a set of stages for core engine modules and general components. It is totally normal to add new stages and move component updates there.

namespace Bvr::DefaultStages

A set of labels for stages that are needed for the engine to function correctly Added to the app when default app is constructed using Bvr::App::Default.

Variables

constexpr const char* Bvr::DefaultStages::FIRST

First executed stage, used for event handling.

constexpr const char* Bvr::DefaultStages::PRE_UPDATE

Update engine before components.

constexpr const char* Bvr::DefaultStages::UPDATE

Core component update.

constexpr const char* Bvr::DefaultStages::POST_UPDATE

Update engine after components.

constexpr const char* Bvr::DefaultStages::LAST

End of frame clean up.

Additionally renderer is using its own set of stages:

namespace Bvr::Renderer::Stages

Variables

constexpr const char* Bvr::Renderer::Stages::EXTRACT

Process modified app resources, copy components that need to be rendered.

constexpr const char* Bvr::Renderer::Stages::PREPARE

Prepare extracted resources and components.

constexpr const char* Bvr::Renderer::Stages::RECORD

Build frame graphcs and record them to command lists Present.

constexpr const char* Bvr::Renderer::Stages::CLEAN_UP

Clean up allocators, resources, etc.

System

Systems directly map to functions in c++ and can be added to stage along with system dependencies to other stages. To add a system to the app, it is possible to call App::AddSystem with the stage name and function pointer that needs to be executed. Note that also lambdas can be passed. To specify order dependencies between systems, Bvr::SystemDesc should be passed to Bvr::SystemDesc with function labels of dependent systems passed into Bvr::SystemDesc::Before to execute this system before specified systems and Bvr::SystemDesc::After to execute after specified systems. For example:

1
2
3
4
5
6
    // In the stage "Update", execute "Count" before "Print"
    app.AddSystem("Update", SystemDesc{&Count}.Before(AsLabel(&Print)));

    // Alternatively same logic could be expressed in reverse
    // In the stage "Update", execute "Print" after "Count"
    app.AddSystem("Update", SystemDesc{&Print}.After(AsLabel(&Count)));

For all registered systems, scheduler also acts as an argument provider, which is able to figure out the scope of execution: app or simulation, fetch all required resources from their owner, whcich are resoures or components respectively for app and simulation scope.

Condition

Due to the fact that engine schedule is mainly statically build ruring startup poses a limitation on how dynamic the engine could be. To overcome this limit and schedule all functions in advance during the build scope, but then conditionally execute them when needed, Bvr::ConditionDesc . A condition is a regular system that is returning Bvr::EShouldRun enum.

enum Bvr::EShouldRun

Return type for a function that will be treated as ConditionDesc.

Name Description
No Do not run this frame.
Yes Run this frame once.
NoAndCheckAgain Do not run the system, but evaluate the condition at the end of the stage and rerun if positive result is returned.
YesAndCheckAgain Run the system and test again at the end ofthe stage and rerun if positive result is returned.

All systems that are returning Bvr::EShouldRun are automatically converted to conditons and could be referenced by other systems. It is possible to execute the system several times per stage using EShouldRun::<Yes/No>AndCheckAgain values. The stage will run utill all systes are done executing and not returning any AndCheckAgain conditions. As mentioned previously, conditions are basically regular systems, so they should be registered same way as regular systems and then referenced in Bvr::SystemDesc::WithCondition .

For example:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
    // Counter resurce
    struct Counter { int i = 0; };
    app.CreateResource<Counter>();
    // Register the condition to the "Update" stage and name it "Cond"
    // Which would only be satisfied on even frames
    app.AddSystem("Update", SystemDesc{[](Counter& cnd) -> EShouldRun {
        return (cnd.i++) % 2 == 0 ? EShouldRun::Yes : EShouldRun::No;
        }}.Label("IsEven"));

    // In the stage "Update", execute "Print" every other frame
    app.AddSystem("Update", SystemDesc{&Print}
        .WithCondition(AsLabel("IsEven")));

Threading

The main reason for such design is scalability and potential for threading. Now that all functions and their inputs are all exposed, it is possible to figure out all dependencies and schedule everything as jobs respecting initially specified order and avoiding systems that could race on resources at the same time. Threading is controlled by Bvr::EStageFlags which could be passed to stage registration. Threading is done using engine’s job system Bvr::MT::CThreadPool .

class Bvr::CSchedule

Scheduler of the App.

Functions

Bvr::CSchedule::CSchedule()=default

Bvr::CSchedule::~CSchedule()=default

CSchedule::Stage & Bvr::CSchedule::AddStage(const char *name, EStageFlags eFlags)

Add new stage to the app.

Adds a stage if it wasn’t found, otherwise does nothing

Parameters:

Name Description
name stage name
eFlags flags that the stage will be construcyted with

Returns: added or discovered stage

CSchedule::Stage & Bvr::CSchedule::AddStageAfter(const char *name, const char *pAfterName, EStageFlags eFlags)

Add new stage to the app after specified stage.

Adds a stage after specified place if it wasn’t found, otherwise does nothing

Parameters:

Name Description
name stage name
pAfterName stage name after which new stage will be added
eFlags flags that the stage will be construcyted with

Returns: added or discovered stage

CSchedule::Stage & Bvr::CSchedule::AddStageBefore(const char *name, const char *pBeforeName, EStageFlags eFlags)

Add new stage to the app before specified stage.

Adds a stage before specified place if it wasn’t found, otherwise does nothing

Parameters:

Name Description
name stage name
pBeforeName stage name before which new stage will be added
eFlags flags that the stage will be construcyted with

Returns: added or discovered stage

CSchedule::Stage * Bvr::CSchedule::GetStage(const char *name)

Returns a stage of specified name.

Parameters:

Name Description
name names of the stage to be found

Returns: found stage or nullptr if it doesn’t exist

void Bvr::CSchedule::AddSystemToStage(const char *stageName, SystemDesc &&desc)

Adds a system to specified stage.

Parameters:

Name Description
stageName name of a stage to which system will be added
desc stage description

void Bvr::CSchedule::Run(App &app)

Invoke the schedule.

Parameters:

Name Description
app application from which resources are extracted

void Bvr::CSchedule::RemoveSystemFromStage(const char *stageName, const TSystemLabel sys)

Delete a system from stage if it exists.

Parameters:

Name Description
stageName name of the stage from which the system should be removed
sys system label to remove from the stage

CSchedule::TStageContainer::iterator Bvr::CSchedule::FindStage(const char *name)

Variables

TStageContainer Bvr::CSchedule::m_stages

struct Bvr::SystemDesc

Description for application scheduleable function.

Functions

constexpr Bvr::SystemDesc::SystemDesc(T &&fn) noexcept

Constructor that takes a conditional invokable.

Parameters:

Name Description
fn system function returning EShouldRun

Bvr::SystemDesc::SystemDesc(T &&fn) noexcept

Constructor that takes an invokable.

Parameters:

Name Description
fn system function

Bvr::SystemDesc::SystemDesc(ConditionDesc &&cond)

Move construct from ConditionDesc.

Bvr::SystemDesc::SystemDesc(const ConditionDesc &cond)

Copy construct from ConditionDesc.

Bvr::SystemDesc::SystemDesc(SystemDesc &&rhs) noexcept=default

Bvr::SystemDesc::SystemDesc(const SystemDesc &rhs) noexcept=default

SystemDesc & Bvr::SystemDesc::operator=(SystemDesc &&rhs) noexcept=default

SystemDesc & Bvr::SystemDesc::operator=(const SystemDesc &rhs) noexcept=default

Bvr::SystemDesc::~SystemDesc()=default

EShouldRun Bvr::SystemDesc::Run(App &app)

Execute the system function.

Parameters:

Name Description
app the application from which system is executed

constexpr SystemDesc & Bvr::SystemDesc::Label(LabelT name)

Set a system label.

Parameters:

Name Description
name label

constexpr SystemDesc & Bvr::SystemDesc::Before(const LabelT next)

Adds a reference to a system before which this system is executed.

Parameters:

Name Description
next label of the system

constexpr SystemDesc & Bvr::SystemDesc::After(const LabelT prev)

Adds a reference to a system after which this system is executed.

Parameters:

Name Description
prev label of the system

constexpr SystemDesc & Bvr::SystemDesc::WithCondition(const CondT &cond)

Adds a reference to a condition Conditions are executed before all systems.

Parameters:

Name Description
cond label or description of the condition

constexpr SystemDesc & Bvr::SystemDesc::WithCondition(CondT &&cond)

Adds a reference to a condition Conditions are executed before all systems.

Parameters:

Name Description
cond label or description of the condition

constexpr bool Bvr::SystemDesc::IsCondition() const

Tells weather this system is a condition system.

Returns: weather this system is condition

constexpr ConditionT & Bvr::SystemDesc::RunCondition()

Get the run condition.

Returns: either label or a description of a condition

constexpr LabelT Bvr::SystemDesc::RunConditionLabel()

Get the run condition label.

Returns: label of a condition

constexpr SystemDesc & Bvr::SystemDesc::Flags(const ESystemFlags flags)

Set system execution flags.

Parameters:

Name Description
flags to set

ESystemFlags Bvr::SystemDesc::Flags() const

Get system execution flags.

Returns: execution flags

constexpr std::span< LabelT const > Bvr::SystemDesc::Labels() const final

constexpr std::span< LabelT const > Bvr::SystemDesc::Before() const final

constexpr std::span< LabelT const > Bvr::SystemDesc::After() const final

constexpr std::string_view Bvr::SystemDesc::Name() const final

std::span< ResourceAccess const > Bvr::SystemDesc::GetAccessedResources() const

Variables

LabelT Bvr::SystemDesc::m_label

std::span Bvr::SystemDesc::m_accessedResources

std::vector Bvr::SystemDesc::m_before

std::vector Bvr::SystemDesc::m_after

InvokableT Bvr::SystemDesc::m_runFn

ConditionT Bvr::SystemDesc::m_condition

ESystemFlags Bvr::SystemDesc::m_eFlags

struct Bvr::ConditionDesc

Description for a condition under which system is executed.

Functions

Bvr::ConditionDesc::ConditionDesc(T &&fn) noexcept

Bvr::ConditionDesc::ConditionDesc(ConditionDesc &&rhs) noexcept=default

Bvr::ConditionDesc::ConditionDesc(const ConditionDesc &rhs) noexcept=default

ConditionDesc & Bvr::ConditionDesc::operator=(ConditionDesc &&rhs) noexcept=default

ConditionDesc & Bvr::ConditionDesc::operator=(const ConditionDesc &rhs) noexcept=default

Bvr::ConditionDesc::~ConditionDesc()=default

EShouldRun Bvr::ConditionDesc::Run(App &app)

constexpr ConditionDesc & Bvr::ConditionDesc::Label(LabelT name)

constexpr ConditionDesc & Bvr::ConditionDesc::Before(LabelT label)

constexpr ConditionDesc & Bvr::ConditionDesc::After(const LabelT label)

constexpr std::span< LabelT const > Bvr::ConditionDesc::Labels() const final

constexpr std::span< LabelT const > Bvr::ConditionDesc::Before() const final

constexpr std::span< LabelT const > Bvr::ConditionDesc::After() const final

constexpr std::string_view Bvr::ConditionDesc::Name() const final

RunFnT Bvr::ConditionDesc::GetFunction() const

Variables

LabelT Bvr::ConditionDesc::m_label

std::vector Bvr::ConditionDesc::m_before

std::vector Bvr::ConditionDesc::m_after

RunFnT Bvr::ConditionDesc::m_runFn