template<typename Derived, typename Input, typename Result>
struct mc_rtc::threading::AsyncJob< Derived, Input, Result >
Helper base class for asynchronous jobs using CRTP.
This class provides a generic interface for running asynchronous computations, managing their state, and adding logging and GUI. Child classes must inherit using CRTP and implement required methods.
Upon destruction, any associated GUI elements and log entries are automatically removed.
The input_ member may be modified when the async task is not running (i.e., before calling startAsync or when running() is false). The input should not be modified while the async task is running (running() is true). Use input() to access it. Note that while the input() method implements a safeguard that throws if the job is running, it does not inherently make modifying the input in-place safe, ensure that your code does not start another async job while you are modifying the input.
- Note
- You must call checkResult() at every iteration of your controller loop. This method is responsible for bookkeeping, result retrieval, and deferred GUI/logging actions. It is roughly equivalent to
ros::spinOnce() for ROS nodes.
- Template Parameters
-
| Derived | The child class type (CRTP). |
| Input | The input type for the job. |
| Result | The result type produced by the job. |
Required/Optional Child Class Methods
- Result computeJob()
- Implements the actual computation. Called asynchronously. (Required)
- void addToLoggerImpl()
- Adds job-specific log entries after the first result is available. (Optional)
- Note
- Will only be called if the user has previously called addToLogger().
- void addToGUIImpl()
- Adds job-specific GUI elements after the first result is available. (Optional)
- Note
- Will only be called if the user has previously called addToGUI().
Example Usage
{
MyResult computeJob()
{
MyResult res;
res.value =
input.data * 2;
return res;
}
{
}
{
}
};
MyAsyncJob job;
job.input = ...;
job.startAsync();
if(job.checkResult())
{
auto result = *job.lastResult();
}
job.addToLogger(logger, "prefix");
job.addToGUI(gui, {"Category"});
auto Label(const std::string &name, GetT get_fn)
Definition: Label.h:36
AsyncJob< Derived, Input, Result > MakeAsyncJob
Definition: AsyncJob.h:308
void addLogEntry(const std::string &name, const SourceT *source, CallbackT &&get_fn, bool overwrite=false)
Definition: Logger.h:208
void addElement(const std::vector< std::string > &category, T element)
mc_rtc::Logger * logger_
Definition: AsyncJob.h:284
void addToGUIImpl()
Definition: AsyncJob.h:281
std::vector< std::string > guiCategory_
Definition: AsyncJob.h:287
void addToLoggerImpl()
Definition: AsyncJob.h:280
Input & input()
Access the input data for the job.
Definition: AsyncJob.h:123
std::optional< Result > lastResult_
Definition: AsyncJob.h:263
mc_rtc::gui::StateBuilder * gui_
Definition: AsyncJob.h:286
template<typename Derived , typename Input , typename Result >
Check if the asynchronous job has completed and handle bookkeeping.
This method must be called at every iteration of the controller. It is responsible for all bookkeeping related to the async job:
- Checks if the asynchronous computation has finished.
- Retrieves and stores the result if available.
- Calls deferred GUI and logging methods if enabled.
This is roughly speaking the equivalent to ros::spinOnce() for ROS nodes.
- Returns
- True if the job has completed and a result is available, false otherwise.
template<typename Derived , typename Input , typename Result >
Input data for the asynchronous job.
This member holds the input required for the job computation. It can be modified only when the async job is not running (i.e., before calling startAsync() or when running() is false). Do not modify this while the async job is running. Use the input() accessor to obtain a writable reference, which throws if the job is running.