Taskolib  1.3.3
Public Types | Public Member Functions | Static Public Member Functions | Static Public Attributes | Private Member Functions | Private Attributes | List of all members
task::Sequence Class Reference

Detailed Description

A sequence of steps that can be modified and executed.

A sequence is basically a list of Step objects with some additional functionality and information. For instance, a sequence has a human-readable label, a list of maintainers, a unique ID, a timeout, and a "step setup script" that is executed before each individual step.

A sequence can be executed in the current thread with execute(). The most important member functions for modifying the sequence are the following ones:

  1. push_back(): add a new step at the end
  2. pop_back(): remove a step from the end
  3. insert(): insert a step at an arbitrary position
  4. assign(): assign a new step to an existing element
  5. erase(): remove a step or a range of steps
  6. modify(): modify a step inside the sequence via a function or function object
seq.push_back(Step{Step::type_try});
seq.push_back(Step{Step::type_action});
seq.push_back(Step{Step::type_catch});
seq.push_back(Step{Step::type_action});
seq.push_back(Step{Step::type_end});
// insert an action step at index 1
seq.insert(seq.begin() + 1, Step{Step::type_action});
Context context;
auto maybe_error = seq.execute(context);
Sequence(gul14::string_view label="", SequenceName name=SequenceName{}, UniqueId uid=UniqueId{})
Construct an empty sequence.
Definition: Sequence.cc:67
@ type_end
Definition: Step.h:58
@ type_catch
Definition: Step.h:59
@ type_action
Definition: Step.h:58
@ type_try
Definition: Step.h:58

Additional information

Beside the list of steps, a sequence carries additional information. The following paragraphs give a coarse overview.

Label

A human-readable label that describes the function of the sequence. It may not contain control characters like linebreaks, but can otherwise be chosen freely. The library and user code are free to use the label as a basis for generating file, directory, and similar names, but must take of the necessary character escaping. The label is not unique and it might be empty.

See also
get_label(), set_label()

Name

While the label is meant for humans to read, the sequence name is a more machine-friendly identifier for constrained uses such as filenames. The name may only contain alphanumeric characters, the minus and underscore characters, and periods. It can be up to 64 characters long, but may be empty.

See also
get_name(), set_name()

Unique ID

The unique ID (UID) is a 64-bit integer that is used to identify the sequence, as far as possible, in a unique way. Upon construction of the sequence, a random UID is generated. Although clashes are very unlikely, an external class like the SequenceManager may take additional steps to ensure the uniqueness of the ID.

See also
get_unique_id(), set_unique_id()

Maintainers

The sequence carries a list of maintainers or sequence authors as a string. By default, it is empty, and it can hold whatever information seems useful.

See also
get_maintainers(), set_maintainers()

Step setup script

The sequence contains a common setup script that is shared by all of its steps. It is called automatically before the execution of the script from each step, just after executing the lua_step_setup. It is typically used like a small library for defining common functions or constants. The setup script is only executed for steps that actually execute a script themselves (ACTION, IF, ELSEIF, WHILE).

See also
get_step_setup_script(), set_step_setup_script()

Sequence timeout

The sequence has a global timeout that starts counting down when execute() is called. By default, it is set to infinity (i.e., no timeout).

See also
get_timeout(), set_timeout()

Time of last execution

The sequence stores the timestamp of when it was last executed.

See also
get_time_of_last_execution()

Tags

An arbitrary number of tags can be associated with a sequence. Tags are used to categorize sequences and to make them easier to find. Tags are small pieces of text that may contain only the lowercase letters a-z, digits, or the hyphen ("-"). Their length can range from 1 to 32 characters. Tags are stored in alphabetical order.

See also
get_tags(), set_tags()

#include <Sequence.h>

Public Types

using SizeType = StepIndex
 Alias for step type. More...
 
using Iterator = std::vector< Step >::iterator
 Alias for a vector iterator. More...
 
using ConstIterator = std::vector< Step >::const_iterator
 Alias for a constant vector iterator. More...
 
using ConstReverseIterator = std::vector< Step >::const_reverse_iterator
 Alias for a constant reverse vector iterator. More...
 

Public Member Functions

 Sequence (gul14::string_view label="", SequenceName name=SequenceName{}, UniqueId uid=UniqueId{})
 Construct an empty sequence. More...
 
void assign (ConstIterator iter, const Step &step)
 Assign a Step to the sequence entry at the given position. More...
 
void assign (ConstIterator iter, Step &&step)
 Assign a Step to the sequence entry at the given position. More...
 
ConstIterator begin () const noexcept
 Return a constant iterator to the first Step in the container. More...
 
ConstIterator cbegin () const noexcept
 Return a constant iterator to the first Step in the container. More...
 
ConstIterator cend () const noexcept
 Return a constant iterator pointing past the last Step in the container. More...
 
ConstReverseIterator crbegin () const noexcept
 Return a constant reverse iterator to the last Step in the container. More...
 
ConstReverseIterator crend () const noexcept
 Return a constant reverse iterator pointing before the first Step in the container. More...
 
void check_syntax () const
 Validates if the Step 's token are correctly enclosed in a proper way. More...
 
bool empty () const noexcept
 Determine whether the sequence contains no steps. More...
 
ConstIterator end () const noexcept
 Return a constant iterator pointing past the last Step in the container. More...
 
ConstIterator erase (ConstIterator iter)
 Remove a step from the sequence. More...
 
ConstIterator erase (ConstIterator begin, ConstIterator end)
 Remove a range of steps from the sequence. More...
 
gul14::optional< Errorexecute (Context &context, CommChannel *comm_channel, OptionalStepIndex opt_step_index=gul14::nullopt)
 Execute the sequence (or just one of its steps) within a given context. More...
 
gul14::optional< Errorget_error () const
 Return an optional Error object explaining why the sequence stopped prematurely. More...
 
std::filesystem::path get_folder () const
 Return the (relative) folder name associated with this sequence. More...
 
const std::string & get_indentation_error () const noexcept
 Return an error string if the sequence is not consistently nested, or an empty string if the nesting is correct. More...
 
const std::string & get_label () const noexcept
 Return the human-readable sequence label. More...
 
const std::string & get_maintainers () const noexcept
 Return a string listing the maintainer(s) of the sequence. More...
 
const SequenceNameget_name () const noexcept
 Return the machine-friendly name of the sequence. More...
 
const std::string & get_step_setup_script () const noexcept
 Return the step setup script. More...
 
const std::vector< Tag > & get_tags () const noexcept
 Return the tags associated with this sequence in alphabetical order. More...
 
bool get_autorun () const noexcept
 Return true if an automatic execution can be performed otherwise false. More...
 
bool is_disabled () const noexcept
 Return the disable flag. When set to true it will prohibit any execution. More...
 
TimePoint get_time_of_last_execution () const
 Determine when the sequence was last executed. More...
 
Timeout get_timeout () const
 Return the timeout duration for executing the sequence. More...
 
UniqueId get_unique_id () const noexcept
 Return the unique ID of the sequence. More...
 
template<typename StepType , std::enable_if_t< std::is_same< gul14::remove_cvref_t< StepType >, Step >::value, bool > = true>
ConstIterator insert (ConstIterator iter, StepType step)
 Insert the given Step into the sequence just before the specified iterator. More...
 
bool is_running () const noexcept
 Retrieve if the sequence is executed. More...
 
bool is_timeout_elapsed () const
 Return true if the timeout is elapsed otherwise false. More...
 
template<typename Closure >
void modify (ConstIterator iter, Closure modification_fct)
 Modify a step inside the sequence. More...
 
const Stepoperator[] (SizeType idx) const noexcept
 Access the step at a given index. More...
 
void pop_back ()
 Remove the last element from the sequence. More...
 
void push_back (const Step &step)
 Add a step to the end of the sequence. More...
 
void push_back (Step &&step)
 Add a step to the end of the sequence. More...
 
ConstReverseIterator rbegin () const noexcept
 Return a constant reverse iterator to the last Step in the container. More...
 
ConstReverseIterator rend () const noexcept
 Return a constant reverse iterator pointing before the first Step in the container. More...
 
void set_error (gul14::optional< Error > opt_error)
 Set an optional Error object to describe the outcome of the last sequence execution. More...
 
void set_label (gul14::string_view label)
 Set the human-readable sequence label. More...
 
void set_maintainers (gul14::string_view maintainers)
 Add one or more maintainers to the sequence. More...
 
void set_name (SequenceName name)
 Set the machine-friendly sequence name. More...
 
void set_running (bool running) noexcept
 Set the sequence into the state "is running" (true) or "is not running" (false). More...
 
void set_step_setup_script (gul14::string_view step_setup_script)
 Sets the step setup script. More...
 
void set_tags (const std::vector< Tag > &tags)
 Set the tags associated with this sequence. More...
 
void set_autorun (bool autorun)
 Set the autorun flag. More...
 
void set_disabled (bool disabled=true)
 Set the disable flag. More...
 
void set_timeout (Timeout timeout)
 Set the timeout duration for executing the sequence. More...
 
void set_unique_id (UniqueId uid)
 Set the unique ID of the sequence. More...
 
SizeType size () const noexcept
 Return the number of steps contained in this sequence. More...
 

Static Public Member Functions

static SizeType max_size () noexcept
 Return the maximum number of steps that a sequence can hold. More...
 

Static Public Attributes

static constexpr std::size_t max_label_length = 128
 Maximum number of bytes of a Sequence label. More...
 

Private Member Functions

void check_syntax (ConstIterator begin, ConstIterator end) const
 Check the sequence for syntactic consistency and throw an exception if an error is detected. More...
 
ConstIterator check_syntax_for_if (ConstIterator begin, ConstIterator end) const
 Internal syntax check for if-elseif-else-clauses. More...
 
ConstIterator check_syntax_for_try (ConstIterator begin, ConstIterator end) const
 Internal syntax check for try-catch-clauses. More...
 
ConstIterator check_syntax_for_while (ConstIterator begin, ConstIterator end) const
 Internal syntax check for while-clauses. More...
 
void correct_error_index (std::function< OptionalStepIndex(StepIndex err_idx)> get_new_index)
 If the sequence has a stored error with step index information, call the given function and replace the error step index with the return value. More...
 
void enforce_consistency_of_disabled_flags () noexcept
 Update the disabled flag of all steps to ensure that control structures are not partially disabled. More...
 
void enforce_invariants ()
 Make sure that all class invariants are upheld. More...
 
Iterator execute_else_block (Iterator begin, Iterator end, Context &context, CommChannel *comm)
 Execute an ELSE block. More...
 
Iterator execute_if_or_elseif_block (Iterator begin, Iterator end, Context &context, CommChannel *comm)
 Execute an IF or ELSEIF block. More...
 
Iterator execute_range (Iterator step_begin, Iterator step_end, Context &context, CommChannel *comm)
 Execute a range of steps. More...
 
Iterator execute_try_block (Iterator begin, Iterator end, Context &context, CommChannel *comm)
 Execute a TRY block. More...
 
Iterator execute_while_block (Iterator begin, Iterator end, Context &context, CommChannel *comm)
 Execute a WHILE block. More...
 
Iterator find_end_of_continuation (Iterator block_start)
 Return an iterator past the END step that ends the block-with-continuation starting at a given iterator. More...
 
ConstIterator find_end_of_continuation (ConstIterator block_start) const
 
gul14::optional< Errorhandle_execution (Context &context, CommChannel *comm_channel, gul14::string_view exec_block_name, std::function< void(Context &, CommChannel *)> runner)
 Run a given execution function on the sequence, taking care of exception handling and messaging. More...
 
void indent ()
 Assign indentation levels to all steps according to their logical nesting. More...
 
void throw_if_full () const
 Throw an Error if no further steps can be inserted into the sequence. More...
 
void throw_if_running () const
 When the sequence is executed it rejects with an Error exception. More...
 
void throw_if_disabled () const
 When the sequence is disabled it rejects with an Error exception. More...
 
void throw_syntax_error_for_step (ConstIterator it, gul14::string_view msg) const
 Throw a syntax error for the specified step. More...
 

Private Attributes

gul14::optional< Errorerror_
 An optional Error object describing why the Sequence stopped prematurely (if it has a value) or that it finished normally (if it is nullopt). More...
 
std::string indentation_error_
 Empty if indentation is correct and complete, error message otherwise. More...
 
UniqueId unique_id_
 Unique ID. More...
 
SequenceName name_
 Machine-readable name. More...
 
std::string label_
 Human-readable sequence label. More...
 
std::string maintainers_
 One or more maintainers. More...
 
std::string step_setup_script_
 Step setup script. More...
 
std::vector< Tagtags_
 Tags for categorizing the sequence. More...
 
bool autorun_ { false }
 Flag for automatic execution. More...
 
bool is_disabled_ { false }
 Disabled sequence. Used for execution control. More...
 
std::vector< Stepsteps_
 Collection of steps. More...
 
bool is_running_ { false }
 Flag to determine if the sequence is running. More...
 
TimeoutTrigger timeout_trigger_
 Logic to check for elapsed sequence timeout. More...
 

Member Typedef Documentation

◆ ConstIterator

using task::Sequence::ConstIterator = std::vector<Step>::const_iterator

Alias for a constant vector iterator.

◆ ConstReverseIterator

using task::Sequence::ConstReverseIterator = std::vector<Step>::const_reverse_iterator

Alias for a constant reverse vector iterator.

◆ Iterator

using task::Sequence::Iterator = std::vector<Step>::iterator

Alias for a vector iterator.

◆ SizeType

Alias for step type.

Constructor & Destructor Documentation

◆ Sequence()

task::Sequence::Sequence ( gul14::string_view  label = "",
SequenceName  name = SequenceName{},
UniqueId  uid = UniqueId{} 
)

Construct an empty sequence.

Parameters
labelHuman-readable label for the sequence. It should describe the function of the sequence clearly and concisely. The label may not contain any control characters like linebreaks and it may not exceed max_label_length bytes. Leading and trailing whitespace is trimmed.
nameMachine-friendly name for the sequence.
uidUnique ID for the sequence.
Exceptions
Erroris thrown if the label is too long or if it contains at least one control character.

References set_label().

Member Function Documentation

◆ assign() [1/2]

void task::Sequence::assign ( Sequence::ConstIterator  iter,
const Step step 
)

Assign a Step to the sequence entry at the given position.

Parameters
iterPosition to which the Step should be assigned
stepNew step to be assigned to the sequence entry
Exceptions
Erroris thrown if the sequence is currently running.

References enforce_invariants(), steps_, and throw_if_running().

◆ assign() [2/2]

void task::Sequence::assign ( Sequence::ConstIterator  iter,
Step &&  step 
)

Assign a Step to the sequence entry at the given position.

Parameters
iterPosition to which the Step should be assigned
stepNew step to be assigned to the sequence entry
Exceptions
Erroris thrown if the sequence is currently running.

References enforce_invariants(), steps_, and throw_if_running().

◆ begin()

ConstIterator task::Sequence::begin ( ) const
inlinenoexcept

Return a constant iterator to the first Step in the container.

Non-const iterators are not available because Sequence has to maintain invariants such as the correct indentation whenever steps are modified.

References steps_.

Referenced by check_syntax(), check_syntax_for_if(), check_syntax_for_try(), check_syntax_for_while(), erase(), execute_else_block(), execute_if_or_elseif_block(), execute_try_block(), execute_while_block(), and task::Executor::update().

◆ cbegin()

ConstIterator task::Sequence::cbegin ( ) const
inlinenoexcept

Return a constant iterator to the first Step in the container.

Non-const iterators are not available because Sequence has to maintain invariants such as the correct indentation whenever steps are modified.

References steps_.

Referenced by erase(), and insert().

◆ cend()

ConstIterator task::Sequence::cend ( ) const
inlinenoexcept

Return a constant iterator pointing past the last Step in the container.

Non-const iterators are not available because Sequence has to maintain invariants such as the correct indentation whenever steps are modified.

References steps_.

◆ check_syntax() [1/2]

void task::Sequence::check_syntax ( ) const

Validates if the Step 's token are correctly enclosed in a proper way.

It is done by validating the step types where each must fit to one of the following conditions:

  1. each type Step::type_try must have the corresponding Step::type_catch and Step::type_end
  2. each type Step::type_if must have n-times Step::type_elseif and/or Step::type_else with a tailing Step::type_end, n >= 0.
  3. each type Step::while must have the corresponding Step::type_end

As a body of each surrounding token must have at least one Step::type_action token.

If one of those is ill-formed an Error exception is thrown.

References indentation_error_, and steps_.

Referenced by check_syntax_for_if(), check_syntax_for_try(), check_syntax_for_while(), and execute().

◆ check_syntax() [2/2]

void task::Sequence::check_syntax ( Sequence::ConstIterator  begin,
Sequence::ConstIterator  end 
) const
private

Check the sequence for syntactic consistency and throw an exception if an error is detected.

That means that one or all of the following conditions must be satisfied:

  1. each TRY step must have a corresponding CATCH and END step
  2. each IF step must have m ELSEIF steps followed by n ELSE steps and one END step with m >= 0 and (n == 0 or n == 1).
  3. each WHILE must have a matching END
Parameters
beginIterator pointing to the first step to be checked
endIterator pointing past the last step to be checked
Exceptions
Erroris thrown if a syntax error is found.
See also
check_syntax()

References begin(), check_syntax_for_if(), check_syntax_for_try(), check_syntax_for_while(), end(), throw_syntax_error_for_step(), task::Step::type_action, task::Step::type_catch, task::Step::type_else, task::Step::type_elseif, task::Step::type_end, task::Step::type_if, task::Step::type_try, and task::Step::type_while.

◆ check_syntax_for_if()

Sequence::ConstIterator task::Sequence::check_syntax_for_if ( Sequence::ConstIterator  begin,
Sequence::ConstIterator  end 
) const
private

Internal syntax check for if-elseif-else-clauses.

Invoked by check_syntax(ConstIterator, ConstIterator).

Parameters
beginIterator pointing to the IF step; must be dereferenceable.
endIterator pointing past the last step to be checked
Returns
an iterator pointing to the first step after the IF..(ELSEIF)..(ELSE)..END construct.
Exceptions
Erroris thrown if an ill-formed 'if-elseif-else' token is found.

References begin(), check_syntax(), end(), throw_syntax_error_for_step(), task::Step::type_else, task::Step::type_elseif, and task::Step::type_end.

Referenced by check_syntax().

◆ check_syntax_for_try()

Sequence::ConstIterator task::Sequence::check_syntax_for_try ( Sequence::ConstIterator  begin,
Sequence::ConstIterator  end 
) const
private

Internal syntax check for try-catch-clauses.

Invoked by check_syntax(ConstIterator, ConstIterator).

Parameters
beginIterator pointing to the TRY step; must be dereferenceable.
endIterator pointing past the last step to be checked
Returns
an iterator pointing to the first step after the TRY..CATCH..END construct.
Exceptions
Erroris thrown if a syntax error is found.

References begin(), check_syntax(), end(), throw_syntax_error_for_step(), task::Step::type_catch, and task::Step::type_end.

Referenced by check_syntax().

◆ check_syntax_for_while()

Sequence::ConstIterator task::Sequence::check_syntax_for_while ( Sequence::ConstIterator  begin,
Sequence::ConstIterator  end 
) const
private

Internal syntax check for while-clauses.

Invoked by check_syntax(ConstIterator, ConstIterator).

Parameters
beginIterator pointing to the WHILE step; must be dereferenceable.
endIterator pointing past the last step to be checked
Returns
an iterator pointing to the first step after the WHILE..END construct.
Exceptions
Erroris thrown if a syntax error is found.

References begin(), check_syntax(), end(), throw_syntax_error_for_step(), and task::Step::type_end.

Referenced by check_syntax().

◆ correct_error_index()

void task::Sequence::correct_error_index ( std::function< OptionalStepIndex(StepIndex err_idx)>  get_new_index)
private

If the sequence has a stored error with step index information, call the given function and replace the error step index with the return value.

The function is only called if the sequence has a stored error (get_error() != nullopt) and the stored error has a step index (get_error()->get_step_index() != nullopt). Otherwise, correct_error_index() does nothing.

References error_.

Referenced by erase(), insert(), and pop_back().

◆ crbegin()

ConstReverseIterator task::Sequence::crbegin ( ) const
inlinenoexcept

Return a constant reverse iterator to the last Step in the container.

Non-const iterators are not available because Sequence has to maintain invariants such as the correct indentation whenever steps are modified.

References steps_.

◆ crend()

ConstReverseIterator task::Sequence::crend ( ) const
inlinenoexcept

Return a constant reverse iterator pointing before the first Step in the container.

Non-const iterators are not available because Sequence has to maintain invariants such as the correct indentation whenever steps are modified.

References steps_.

◆ empty()

bool task::Sequence::empty ( ) const
inlinenoexcept

Determine whether the sequence contains no steps.

References steps_.

◆ end()

ConstIterator task::Sequence::end ( ) const
inlinenoexcept

Return a constant iterator pointing past the last Step in the container.

Non-const iterators are not available because Sequence has to maintain invariants such as the correct indentation whenever steps are modified.

References steps_.

Referenced by check_syntax(), check_syntax_for_if(), check_syntax_for_try(), check_syntax_for_while(), erase(), execute_else_block(), execute_if_or_elseif_block(), execute_try_block(), and execute_while_block().

◆ enforce_consistency_of_disabled_flags()

void task::Sequence::enforce_consistency_of_disabled_flags ( )
privatenoexcept

Update the disabled flag of all steps to ensure that control structures are not partially disabled.

In particular, if the starting step of a control structure is disabled, all steps contained within it as well as the final end are disabled. If the starting step of a control structure is enabled, all associated control steps (else, elseif, catch, end) are enabled as well.

Precondition
The steps must be correctly indented as per calling indent().

References find_end_of_continuation(), task::Step::get_indentation_level(), task::Step::set_disabled(), steps_, task::Step::type_action, task::Step::type_catch, task::Step::type_else, task::Step::type_elseif, task::Step::type_end, task::Step::type_if, task::Step::type_try, and task::Step::type_while.

Referenced by enforce_invariants().

◆ enforce_invariants()

void task::Sequence::enforce_invariants ( )
private

Make sure that all class invariants are upheld.

This call updates the indentation and the "disabled" flags. It does not throw exceptions except for, possibly, std::bad_alloc.

References enforce_consistency_of_disabled_flags(), and indent().

Referenced by assign(), erase(), insert(), pop_back(), and push_back().

◆ erase() [1/2]

Sequence::ConstIterator task::Sequence::erase ( Sequence::ConstIterator  begin,
Sequence::ConstIterator  end 
)

Remove a range of steps from the sequence.

The removed range includes the begin iterator and excludes the end iterator:

it0: ACTION
it1: WHILE
it2: ACTION
it3: END
it4: ACTION

After erase(it1, it4):

it0: ACTION
it1a: ACTION

The begin iterator and all iterators to elements following it are invalidated by this operation, including the end() iterator.

Parameters
beginIterator to the first Step to be removed
endIterator past the last Step to be removed
Returns
an iterator to the first step after the deleted range.
Exceptions
Erroris thrown if the sequence is currently running or if begin > end.

References begin(), cbegin(), correct_error_index(), end(), enforce_invariants(), steps_, and throw_if_running().

◆ erase() [2/2]

Sequence::ConstIterator task::Sequence::erase ( Sequence::ConstIterator  iter)

Remove a step from the sequence.

This operation invalidates all iterators to the removed step and following ones, including the end() iterator.

Parameters
iterIterator to the step that should be removed
Returns
the iterator of the step after the removed one.
Exceptions
Erroris thrown if the sequence is currently running.

References cbegin(), correct_error_index(), enforce_invariants(), steps_, and throw_if_running().

◆ execute()

gul14::optional< Error > task::Sequence::execute ( Context context,
CommChannel comm_channel,
OptionalStepIndex  opt_step_index = gul14::nullopt 
)

Execute the sequence (or just one of its steps) within a given context.

Depending on the value of the opt_step_index parameter, this function either runs the entire sequence or just one of its steps:

  • If opt_step_index == nullopt, the function first performs a syntax check and throws an Error exception if it fails. Then, it executes the sequence step by step, following the control flow given by steps such as WHILE, IF, TRY, and so on. Disabled steps are ignored. The function returns when the sequence has finished or has stopped with an error.
  • If opt_step_index contains a step index, this function executes the single step identified by the index. As usual, both the step setup function (from the context) and the step setup script (from the sequence) are run before the step script. No verification of the entire sequence takes place, so that a single step can even be run if the logical structure of the sequence is faulty. For most other intents and purposes, running a single step behaves like running the entire sequence.

During execute(), is_running() returns true to internal functions or Lua callbacks.

Parameters
contextA Context for storing variables, step setup information and other data relevant for the execution. The step_setup_script member is overwritten with the step setup script of the executed sequence.
comm_channelPointer to a communication channel. If this is a null pointer, no messages are sent and no external interaction with the running sequence is possible. Otherwise, messages for starting/stopping steps and the sequence itself are sent and termination requests are honored.
opt_step_indexIndex of the step to be executed
Returns
nullopt if the execution finished successfully, or an Error object if the script cannot be executed due to a syntax error or if it raises an error during execution. The return value is also stored in the Sequence object and can be retrieved with get_error().

References check_syntax(), execute_range(), handle_execution(), task::TimeoutTrigger::reset(), size(), steps_, timeout_trigger_, and task::to_string().

◆ execute_else_block()

Sequence::Iterator task::Sequence::execute_else_block ( Iterator  begin,
Iterator  end,
Context context,
CommChannel comm 
)
private

Execute an ELSE block.

Parameters
beginIterator to an ELSE step
endIterator past the last step to be scanned for matching indentation (may simply be end())
contextExecution context
commPointer to a communication channel; if null, messaging and cross-thread interaction are disabled.
Returns
an iterator to the first step after the matching END step.

References begin(), end(), and execute_range().

Referenced by execute_range().

◆ execute_if_or_elseif_block()

Sequence::Iterator task::Sequence::execute_if_or_elseif_block ( Iterator  begin,
Iterator  end,
Context context,
CommChannel comm 
)
private

Execute an IF or ELSEIF block.

Parameters
beginIterator to an IF or ELSEIF step
endIterator past the last step to be scanned for matching indentation (may simply be end())
contextExecution context
commPointer to a communication channel; if null, messaging and cross-thread interaction are disabled.
Returns
an iterator to the step to be executed next: If the IF/ELSEIF evaluated as true, this is the first step after the matching END. Otherwise, it is the next step after skipping the current IF/ELSEIF block.

References begin(), end(), execute_range(), steps_, and timeout_trigger_.

Referenced by execute_range().

◆ execute_range()

Sequence::Iterator task::Sequence::execute_range ( Iterator  step_begin,
Iterator  step_end,
Context context,
CommChannel comm 
)
private

Execute a range of steps.

Parameters
step_beginIterator to the first step that should be executed
step_endIterator past the last step that should be executed
contextContext for executing the steps
commPointer to a communication channel; if null, messaging and cross-thread interaction are disabled.
Exceptions
Erroris thrown if the execution fails at some point.

References task::abort_marker, execute_else_block(), execute_if_or_elseif_block(), execute_try_block(), execute_while_block(), task::CommChannel::immediate_termination_requested_, steps_, timeout_trigger_, task::Step::type_action, task::Step::type_else, task::Step::type_elseif, task::Step::type_end, task::Step::type_if, task::Step::type_try, and task::Step::type_while.

Referenced by execute(), execute_else_block(), execute_if_or_elseif_block(), execute_try_block(), and execute_while_block().

◆ execute_try_block()

Sequence::Iterator task::Sequence::execute_try_block ( Iterator  begin,
Iterator  end,
Context context,
CommChannel comm 
)
private

Execute a TRY block.

Parameters
beginIterator to the TRY step
endIterator past the last step to be scanned for matching indentation (may simply be end())
contextExecution context
commPointer to a communication channel; if null, messaging and cross-thread interaction are disabled.
Returns
an iterator to the first step after the matching END step.

References task::abort_marker, begin(), end(), execute_range(), and task::Step::type_catch.

Referenced by execute_range().

◆ execute_while_block()

Sequence::Iterator task::Sequence::execute_while_block ( Iterator  begin,
Iterator  end,
Context context,
CommChannel comm 
)
private

Execute a WHILE block.

Parameters
beginIterator to the WHILE step
endIterator past the last step to be scanned for matching indentation (may simply be end())
contextExecution context
commPointer to a communication channel; if null, messaging and cross-thread interaction are disabled.
Returns
an iterator to the first step after the matching END step.

References begin(), end(), execute_range(), steps_, and timeout_trigger_.

Referenced by execute_range().

◆ find_end_of_continuation() [1/2]

Sequence::ConstIterator task::Sequence::find_end_of_continuation ( Sequence::ConstIterator  block_start) const
private

References steps_.

◆ find_end_of_continuation() [2/2]

Sequence::Iterator task::Sequence::find_end_of_continuation ( Sequence::Iterator  block_start)
private

Return an iterator past the END step that ends the block-with-continuation starting at a given iterator.

WHILE <- block_start
ACTION
END
ACTION <- find_end_of_continuation(block_start)
Iterator find_end_of_continuation(Iterator block_start)
Return an iterator past the END step that ends the block-with-continuation starting at a given iterat...
Definition: Sequence.cc:574
Returns
an iterator past the matching END step or steps_.end() if there is no matching END step.

References steps_.

Referenced by enforce_consistency_of_disabled_flags().

◆ get_autorun()

bool task::Sequence::get_autorun ( ) const
inlinenoexcept

Return true if an automatic execution can be performed otherwise false.

References autorun_.

◆ get_error()

gul14::optional<Error> task::Sequence::get_error ( ) const
inline

Return an optional Error object explaining why the sequence stopped prematurely.

If the sequence finished normally, nullopt is returned.

References error_.

◆ get_folder()

std::filesystem::path task::Sequence::get_folder ( ) const

Return the (relative) folder name associated with this sequence.

The folder name is derived from the machine-friendly sequence name and the unique ID (e.g. "MY_SEQUENCE[08159e372cbf1d4e]"). There is no guarantee that the folder exists. The SequenceManager class deals with stored sequences.

References get_name(), get_unique_id(), and task::make_sequence_filename().

Referenced by task::SequenceManager::write_sequence_to_disk().

◆ get_indentation_error()

const std::string& task::Sequence::get_indentation_error ( ) const
inlinenoexcept

Return an error string if the sequence is not consistently nested, or an empty string if the nesting is correct.

References indentation_error_.

◆ get_label()

const std::string& task::Sequence::get_label ( ) const
inlinenoexcept

Return the human-readable sequence label.

References label_.

◆ get_maintainers()

const std::string& task::Sequence::get_maintainers ( ) const
inlinenoexcept

Return a string listing the maintainer(s) of the sequence.

References maintainers_.

◆ get_name()

const SequenceName& task::Sequence::get_name ( ) const
inlinenoexcept

Return the machine-friendly name of the sequence.

References name_.

Referenced by get_folder().

◆ get_step_setup_script()

const std::string& task::Sequence::get_step_setup_script ( ) const
inlinenoexcept

Return the step setup script.

References step_setup_script_.

Referenced by task::operator<<().

◆ get_tags()

const std::vector<Tag>& task::Sequence::get_tags ( ) const
inlinenoexcept

Return the tags associated with this sequence in alphabetical order.

References tags_.

◆ get_time_of_last_execution()

TimePoint task::Sequence::get_time_of_last_execution ( ) const
inline

Determine when the sequence was last executed.

For a sequence that was never run, TimePoint{} is returned.

References task::TimeoutTrigger::get_start_time(), and timeout_trigger_.

◆ get_timeout()

Timeout task::Sequence::get_timeout ( ) const
inline

Return the timeout duration for executing the sequence.

References task::TimeoutTrigger::get_timeout(), and timeout_trigger_.

◆ get_unique_id()

UniqueId task::Sequence::get_unique_id ( ) const
inlinenoexcept

Return the unique ID of the sequence.

References unique_id_.

Referenced by get_folder(), and task::SequenceManager::rename_sequence().

◆ handle_execution()

gul14::optional< Error > task::Sequence::handle_execution ( Context context,
CommChannel comm_channel,
gul14::string_view  exec_block_name,
std::function< void(Context &, CommChannel *)>  runner 
)
private

Run a given execution function on the sequence, taking care of exception handling and messaging.

Parameters
contextExecution context
comm_channelPointer to a communication channel; if null, messaging and cross-thread interaction are disabled.
exec_block_nameName of the execution block, preferably starting with a capital letter (e.g. "Sequence", "Single-step execution")
runnerFunction to be executed
Returns
nullopt if the execution function finished successfully, or an Error object if anything went wrong.

References task::aborted, is_running_, task::remove_abort_markers(), task::send_message(), task::Message::sequence_started, task::Message::sequence_stopped, task::Message::sequence_stopped_with_error, set_error(), task::Context::step_setup_script, step_setup_script_, task::terminated_by_script, throw_if_disabled(), and task::uncaught_error.

Referenced by execute().

◆ indent()

void task::Sequence::indent ( )
private

Assign indentation levels to all steps according to their logical nesting.

If errors in the logical nesting are found, an approximate indentation is assigned and the member string indentation_error_ is filled with an error message. If the nesting is correct and complete, indentation_error_ is set to an empty string.

This function does not throw exceptions except for, possibly, std::bad_alloc.

References indentation_error_, task::Step::max_indentation_level, steps_, task::Step::type_action, task::Step::type_catch, task::Step::type_else, task::Step::type_elseif, task::Step::type_end, task::Step::type_if, task::Step::type_try, and task::Step::type_while.

Referenced by enforce_invariants().

◆ insert()

template<typename StepType , std::enable_if_t< std::is_same< gul14::remove_cvref_t< StepType >, Step >::value, bool > = true>
ConstIterator task::Sequence::insert ( ConstIterator  iter,
StepType  step 
)
inline

Insert the given Step into the sequence just before the specified iterator.

This can trigger a reallocation that invalidates all iterators.

Parameters
iteran iterator indicating the position before which the new step should be inserted
stepthe Step to be inserted
Returns
an iterator to the newly inserted Step
Exceptions
Erroris thrown if the sequence has no capacity for additional entries or if it is currently running.

References cbegin(), correct_error_index(), enforce_invariants(), steps_, throw_if_full(), and throw_if_running().

◆ is_disabled()

bool task::Sequence::is_disabled ( ) const
inlinenoexcept

Return the disable flag. When set to true it will prohibit any execution.

References is_disabled_.

Referenced by set_disabled().

◆ is_running()

bool task::Sequence::is_running ( ) const
inlinenoexcept

Retrieve if the sequence is executed.

Returns
true on executing otherwise false.

References is_running_.

Referenced by task::Executor::update().

◆ is_timeout_elapsed()

bool task::Sequence::is_timeout_elapsed ( ) const
inline

Return true if the timeout is elapsed otherwise false.

References task::TimeoutTrigger::is_elapsed(), and timeout_trigger_.

◆ max_size()

static SizeType task::Sequence::max_size ( )
inlinestaticnoexcept

Return the maximum number of steps that a sequence can hold.

Referenced by throw_if_full().

◆ modify()

template<typename Closure >
void task::Sequence::modify ( ConstIterator  iter,
Closure  modification_fct 
)
inline

Modify a step inside the sequence.

This function modifies one of the sequence steps in place. The modification is done by a user-supplied function that receives a mutable reference to the Step indicated via an iterator:

Sequence seq = get_sequence_from_somewhere();
auto it = seq.begin(); // get an iterator to the Step that should be modified
seq.modify(it, [](Step& step) { step.set_label("Modified step"); });

Background: A Sequence does not allow its steps to be modified directly from the outside via references or iterators because it has to uphold certain class invariants (like "all steps are always correctly indented"). A call to modify(), however, reestablishes these invariants after the modification if necessary.

Parameters
iterAn iterator to the Step that should be modified. The step must be part of this sequence.
modification_fctA function or function object with the signature void fct(Step&) that applies the desired modifications on a Step. The step reference becomes invalid after the call.
Exceptions
Erroris thrown if the sequence is currently running or if the modification function throws. In the latter case, the step may only be partially modified, but the invariants of the sequence are maintained (basic exception guarantee).

References steps_, and throw_if_running().

Referenced by task::Executor::update().

◆ operator[]()

const Step& task::Sequence::operator[] ( SizeType  idx) const
inlinenoexcept

Access the step at a given index.

The index operator can only be used for read access to the sequence steps. This is because Sequence has to maintain invariants such as the correct indentation whenever steps are modified.

◆ pop_back()

void task::Sequence::pop_back ( )

Remove the last element from the sequence.

Calling pop_back() on an empty Sequence returns silently. Iterators and references to the last element and the end() iterator are invalidated.

Exceptions
Erroris thrown if the sequence is currently running.

References correct_error_index(), enforce_invariants(), size(), steps_, and throw_if_running().

◆ push_back() [1/2]

void task::Sequence::push_back ( const Step step)

Add a step to the end of the sequence.

Parameters
stepThe Step to be appended to the sequence
Exceptions
Erroris thrown if the sequence has no capacity for additional entries or if it is currently running.

References enforce_invariants(), steps_, throw_if_full(), and throw_if_running().

◆ push_back() [2/2]

void task::Sequence::push_back ( Step &&  step)

Add a step to the end of the sequence.

Parameters
stepThe Step to be appended to the sequence by moving
Exceptions
Erroris thrown if the sequence has no capacity for additional entries or if it is currently running.

References enforce_invariants(), steps_, throw_if_full(), and throw_if_running().

◆ rbegin()

ConstReverseIterator task::Sequence::rbegin ( ) const
inlinenoexcept

Return a constant reverse iterator to the last Step in the container.

Non-const iterators are not available because Sequence has to maintain invariants such as the correct indentation whenever steps are modified.

◆ rend()

ConstReverseIterator task::Sequence::rend ( ) const
inlinenoexcept

Return a constant reverse iterator pointing before the first Step in the container.

Non-const iterators are not available because Sequence has to maintain invariants such as the correct indentation whenever steps are modified.

◆ set_autorun()

void task::Sequence::set_autorun ( bool  autorun)

Set the autorun flag.

This flag is only informative but it can be used by third party code to decide when the autorun happens and when.

References autorun_.

Referenced by task::load_sequence_parameters().

◆ set_disabled()

void task::Sequence::set_disabled ( bool  disabled = true)

Set the disable flag.

References is_disabled(), and is_disabled_.

Referenced by task::load_sequence_parameters().

◆ set_error()

void task::Sequence::set_error ( gul14::optional< Error opt_error)

Set an optional Error object to describe the outcome of the last sequence execution.

Parameters
opt_errorThis should be set to nullopt to indicate that the sequence finished normally, or to an Error object describing why and where it stopped prematurely.
Note
This is usually not a useful call for end users of the library. It is used by the Executor class and by unit tests.
See also
get_error()

References error_.

Referenced by handle_execution(), task::Executor::launch_async_execution(), and task::Executor::update().

◆ set_label()

void task::Sequence::set_label ( gul14::string_view  label)

Set the human-readable sequence label.

Leading and trailing whitespace is trimmed, and the resulting label must not exceed a length of max_label_length bytes. Moreover, it should not contain any control characters.

Parameters
labeldescriptive and expressive label.
Exceptions
Erroris thrown if the label is empty, its length exceeds max_label_length bytes or has some control characters.

References task::check_for_control_characters(), label_, and max_label_length.

Referenced by task::load_sequence_parameters(), and Sequence().

◆ set_maintainers()

void task::Sequence::set_maintainers ( gul14::string_view  maintainers)

Add one or more maintainers to the sequence.

You are free to choose what ever you can use to identify the maintainer. You can also type more than one maintainer where they can be separated with comma or semicolon. For example:

 "John Doe john.doe@universe.org; Bob Smith boby@milkyway.edu"
Parameters
maintainersOne ore more maintainers of the sequence.
Exceptions
Erroris thrown if control characters are detected.

References task::check_for_control_characters(), and maintainers_.

Referenced by task::load_sequence_parameters().

◆ set_name()

void task::Sequence::set_name ( SequenceName  name)
inline

Set the machine-friendly sequence name.

Parameters
namenew sequence name

Referenced by task::SequenceManager::rename_sequence().

◆ set_running()

void task::Sequence::set_running ( bool  running)
inlinenoexcept

Set the sequence into the state "is running" (true) or "is not running" (false).

Note
This is usually not a useful call for end users of the library. It is used by the Executor class and by unit tests.

Referenced by task::Executor::launch_async_execution(), and task::Executor::update().

◆ set_step_setup_script()

void task::Sequence::set_step_setup_script ( gul14::string_view  step_setup_script)

Sets the step setup script.

The step setup script is executed before the script of each individual Step.

Parameters
step_setup_scriptThe new step setup script
Exceptions
Erroris thrown if the sequence is currently running.

References step_setup_script_, and throw_if_running().

Referenced by task::load_sequence_parameters().

◆ set_tags()

void task::Sequence::set_tags ( const std::vector< Tag > &  tags)

Set the tags associated with this sequence.

Duplicate tags are removed silently.

References tags_.

Referenced by task::load_sequence_parameters().

◆ set_timeout()

void task::Sequence::set_timeout ( Timeout  timeout)
inline

Set the timeout duration for executing the sequence.

Referenced by task::load_sequence_parameters().

◆ set_unique_id()

void task::Sequence::set_unique_id ( UniqueId  uid)
inline

Set the unique ID of the sequence.

The unique ID is assigned upon construction and should ideally not be changed afterwards.

◆ size()

SizeType task::Sequence::size ( ) const
inlinenoexcept

Return the number of steps contained in this sequence.

Referenced by execute(), pop_back(), task::Executor::run_single_step_asynchronously(), and task::SequenceManager::write_sequence_to_disk().

◆ throw_if_disabled()

void task::Sequence::throw_if_disabled ( ) const
private

When the sequence is disabled it rejects with an Error exception.

References is_disabled_.

Referenced by handle_execution().

◆ throw_if_full()

void task::Sequence::throw_if_full ( ) const
private

Throw an Error if no further steps can be inserted into the sequence.

References max_size(), and steps_.

Referenced by insert(), and push_back().

◆ throw_if_running()

void task::Sequence::throw_if_running ( ) const
private

When the sequence is executed it rejects with an Error exception.

References is_running_.

Referenced by assign(), erase(), insert(), modify(), pop_back(), push_back(), and set_step_setup_script().

◆ throw_syntax_error_for_step()

void task::Sequence::throw_syntax_error_for_step ( Sequence::ConstIterator  it,
gul14::string_view  msg 
) const
private

Throw a syntax error for the specified step.

The error message reports the step number.

Referenced by check_syntax(), check_syntax_for_if(), check_syntax_for_try(), and check_syntax_for_while().

Member Data Documentation

◆ autorun_

bool task::Sequence::autorun_ { false }
private

Flag for automatic execution.

Referenced by get_autorun(), and set_autorun().

◆ error_

gul14::optional<Error> task::Sequence::error_
private

An optional Error object describing why the Sequence stopped prematurely (if it has a value) or that it finished normally (if it is nullopt).

Referenced by correct_error_index(), get_error(), and set_error().

◆ indentation_error_

std::string task::Sequence::indentation_error_
private

Empty if indentation is correct and complete, error message otherwise.

Referenced by check_syntax(), get_indentation_error(), and indent().

◆ is_disabled_

bool task::Sequence::is_disabled_ { false }
private

Disabled sequence. Used for execution control.

Referenced by is_disabled(), set_disabled(), and throw_if_disabled().

◆ is_running_

bool task::Sequence::is_running_ { false }
private

Flag to determine if the sequence is running.

Referenced by handle_execution(), is_running(), and throw_if_running().

◆ label_

std::string task::Sequence::label_
private

Human-readable sequence label.

Referenced by get_label(), and set_label().

◆ maintainers_

std::string task::Sequence::maintainers_
private

One or more maintainers.

Referenced by get_maintainers(), and set_maintainers().

◆ max_label_length

constexpr std::size_t task::Sequence::max_label_length = 128
staticconstexpr

Maximum number of bytes of a Sequence label.

Referenced by set_label().

◆ name_

SequenceName task::Sequence::name_
private

Machine-readable name.

Referenced by get_name().

◆ step_setup_script_

std::string task::Sequence::step_setup_script_
private

◆ steps_

std::vector<Step> task::Sequence::steps_
private

◆ tags_

std::vector<Tag> task::Sequence::tags_
private

Tags for categorizing the sequence.

Referenced by get_tags(), and set_tags().

◆ timeout_trigger_

TimeoutTrigger task::Sequence::timeout_trigger_
private

◆ unique_id_

UniqueId task::Sequence::unique_id_
private

Unique ID.

Referenced by get_unique_id().


The documentation for this class was generated from the following files: