Runner

The Runner class represents a component that aggregates a Procedure and a UserInterface, allowing the execution of the procedure with input/output directed from/to the concrete user interface class and the ability to set breakpoints for debugging purposes. The class provides methods to control the execution of the procedure, handle breakpoints, and execute the procedure step by step.

Usage

Creating a Runner

To use the Runner, you need to create an instance of this class, passing a reference to a UserInterface object in its constructor.

UserInterface my_user_interface;
Runner my_runner(my_user_interface);

Setting the Procedure

Use the SetProcedure method to set the procedure that will be executed by the runner. Pass a pointer to the Procedure object that you want to execute.

Procedure my_procedure;
my_runner.SetProcedure(&my_procedure);

Setting a Tick Callback

The SetTickCallback method allows you to set a callback function that will be called after each execution step. The callback function should have the signature void(const Procedure&). The callback can be used to query procedure status, the list of next instructions t execute, etc.

void MyTickCallback(const Procedure& procedure) {
    // Implement logic for actions to perform after each execution step
}

my_runner.SetTickCallback(MyTickCallback);

Managing Breakpoints

Use the methods SetBreakpoint, RemoveBreakpoint and GetBreakpoints to manage breakpoints within the procedure. Breakpoints are points in the instruction tree where the execution will pause to allow procedures to be verified and tested at the set breakpoints. It is important to note that these methods should not be called during execution. They are intended to be used when the procedure is paused, before/after a single execution step, or after a breakpoint has been triggered.

const Instruction* instruction_to_break = my_procedure.RootInstruction();
my_runner.SetBreakpoint(instruction_to_break);

std::vector<breakpoint> breaks = my_runner.GetBreakpoints();

my_runner.RemoveBreakpoint(instruction_to_break);

Executing the Procedure

To execute the entire procedure, use the ExecuteProcedure method. The procedure will run until it finishes or encounters a breakpoint.

my_runner.ExecuteProcedure();

Executing Single Instruction

Use the ExecuteSingle method to execute a single instruction within the procedure. This method allows you to step through the procedure execution, particularly useful for debugging.

my_runner.ExecuteSingle();

Pausing and Halting Execution

You can pause the procedure execution using the Pause method, and you can halt the procedure using the Halt method.

my_runner.Pause();
// To resume, call ExecuteProcedure again.
my_runner.Halt();

Checking Execution Status

The IsFinished and IsRunning methods allow you to check the current execution status of the procedure.

bool finished = my_runner.IsFinished();
bool running = my_runner.IsRunning();

Note that IsRunning has a very specific meaning in the context of the oac-tree: this member function returns true only when parts of the executing instruction tree are being run in a separate thread. This function is used to distinguish between instructions waiting to be ticked again and instructions that may require some time to finish before they can proceed. In this way, busy loops can be avoided, i.e. continuously ticking an instruction tree that is being run in a separate thread.

Additional Notes

  • The Runner class includes the TickCallback type, which represents a function that will be called after each execution step. You can set this callback using the SetTickCallback method. The callback function takes a const Procedure& parameter, allowing you to access information about the procedure’s state after each step.

  • The TimeoutWhenRunning class is provided as a standard callback for in-between ticks. It performs a fixed timeout when the procedure reports a running status during asynchronous operations.

Class definition

Next is presented the definition of the Runner class and its main methods.

class Runner

The Runner class aggregates a Procedure and a UserInterface. It allows to synchronously execute a procedure and get feedback or user input/output on the UserInterface.

Public Functions

explicit Runner(UserInterface &ui)

Constructor.

Parameters:

ui – User interface object.

void SetProcedure(Procedure *procedure)

Set the procedure.

Note

The passed procedure will be setup during this function call, so it is assumed that the procedure was not previously setup.

Parameters:

procedure – Pointer to procedure.

void SetTickCallback(TickCallback cb = {})

Set the callback function to be called after each execution step.

Parameters:

cb – Callback function.

bool SetBreakpoint(const Instruction *instruction)

Set a breakpoint at the given instruction.

Note

This member function should not be called during execution, but only when it is paused, before/after a single execution step or after a breakpoint was triggered.

Parameters:

instruction – Pointer to instruction for breakpoint location.

Throws:

InvalidOperationException – when instruction is unknown.

bool RemoveBreakpoint(const Instruction *instruction)

Remove a breakpoint at the given instruction (if it exists).

Note

This member function should not be called during execution, but only when it is paused, before/after a single execution step or after a breakpoint was triggered.

Parameters:

instruction – Pointer to instruction for breakpoint location.

std::vector<Breakpoint> GetBreakpoints() const

Get a list of breakpoints.

This member function returns a copy of the breakpoint list. Manipulation of breakpoint statuses is handled only internally or through dedicated member functions like DisableBreakpoint().

Note

This member function should not be called during execution, but only when it is paused, before/after a single execution step or after a breakpoint was triggered.

Returns:

List of breakpoints.

void ExecuteProcedure()

Execute the procedure.

void ExecuteSingle()

Execute single procedure instruction.

void Halt()

Halts the procedure execution.

void Pause()

Pauses the procedure execution.

Note

Resuming the execution is done by calling ExecuteProcedure() again.

bool IsFinished() const

Query if procedure has finished.

Returns:

True if procedure has finished.

bool IsRunning() const

Query if procedure is running in seperate threads.

Returns:

True if procedure has seperate threads executing.

class TimeoutWhenRunning

Class that can be used as a callback in between ticks. It will perform a fixed timeout when the procedure reports a running status (async operation).