Switch
Inherits from: Task
The Switch
class is a control flow component in the task framework that provides multi-way
conditional task execution. It evaluates a selector function and executes the corresponding case task,
or a default task if no matching case is found. The class supports both string and integer selectors,
making it flexible for various decision-making scenarios.
Features
- Multiple Execution Paths: Support for multiple case branches based on selector values
- Type Flexibility: Works with both string and integer selector values
- Default Handling: Optional default task for when no cases match
- Selector Functions: Customizable functions for determining which case to execute
- Signal-Based Feedback: Emits signals for case selection and execution events
- Asynchronous Execution: Support for non-blocking execution in background threads
- Fluent Interface: Method chaining for readable case definition
Class Interface
Signals
Switch emits the following signals:
Signal |
Type |
Description |
Arguments |
started |
Simple |
Emitted when the Switch begins execution |
None |
finished |
Simple |
Emitted when the Switch completes execution |
None |
caseSelected |
Data |
Emitted when a matching case is found |
String or int (the case value) |
defaultSelected |
Simple |
Emitted when no case matches and default is used |
None |
noMatchFound |
Simple |
Emitted when no case matches and no default exists |
None |
error |
Data |
Reports errors during execution |
std::string (error message) |
Usage Example
Control Flow
The Switch class implements multi-way conditional control flow using the following process:
- Selector Evaluation: The selector function is called with the provided arguments
- Case Matching: The result is compared against the registered cases
- Task Selection: If a match is found, the corresponding task is selected
- Default Handling: If no match is found, the default task is selected (if provided)
- Task Execution: The selected task is executed
Note: Unlike C/C++ switch statements, the Switch class does not support fallthrough
behavior. Only one case is executed per evaluation.
Asynchronous Execution
The executeAsync()
method provides asynchronous execution using C++ futures:
This allows the switch evaluation and subsequent task execution to run in the background without blocking the
main thread.
Lifecycle
A Switch task goes through the following lifecycle:
- Construction: Created with a selector function (string or integer)
- Case Definition: Cases are added via the
case_()
and
default_()
methods
- Execution Start:
execute()
or executeAsync()
called, emits
"started" signal
- Selector Evaluation: The selector function is called to determine which case to execute
- Case Selection: A matching case is found, or the default is used, with appropriate
signals
- Task Execution: The selected task is executed
- Execution End: Switch completes, emits "finished" signal
- Error Handling: If exceptions occur, they are caught and reported via the "error"
signal
The implementation automatically handles the proper emission of signals throughout the lifecycle,
ensuring that components listening to the Switch can track its execution state.
Implementation Details
Here's a closer look at some key implementation details:
Best Practices
- Define a Default Case: Always provide a default case to handle unexpected values
- Task Ownership: Be careful about task ownership when using raw pointers
- Exception Safety: Ensure selector functions handle exceptions gracefully
- Case Ordering: The order of case definitions doesn't affect execution (unlike if-else
chains)
- Signal Connections: Connect to the Switch signals to monitor execution flow
- Selector Purity: Avoid side effects in selector functions for predictable behavior
- Task Independence: Design tasks to be independent and not rely on execution order
Switch works well with other components in the task framework:
- If: For binary conditional execution
- Algorithm: Use algorithms as case tasks
- ThreadPool: Execute multiple switches in parallel
- Logger: Monitor switch execution and case selection
Note: When choosing between If
and Switch
, consider the number of
conditions. Use If
for simple binary decisions and Switch
for multi-way branching.
Additional Examples