mc_rtc  2.14.0
mc_rtc::threading::AsyncJob< Derived, Input, Result > Struct Template Reference

Helper base class for asynchronous jobs using CRTP. More...

#include <mc_rtc/threading/AsyncJob.h>

Collaboration diagram for mc_rtc::threading::AsyncJob< Derived, Input, Result >:

Classes

struct  Timers
 

Public Member Functions

 AsyncJob ()=default
 
 AsyncJob (const AsyncJob &)=delete
 
AsyncJoboperator= (const AsyncJob &)=delete
 
 AsyncJob (AsyncJob &&)=delete
 
AsyncJoboperator= (AsyncJob &&)=delete
 
 ~AsyncJob ()
 
Input & input ()
 Access the input data for the job. More...
 
void startAsync ()
 
bool running () const noexcept
 
bool startedOnce () const noexcept
 
bool checkResult ()
 Check if the asynchronous job has completed and handle bookkeeping. More...
 
const std::optional< Result > & lastResult () const noexcept
 
void addToLogger (mc_rtc::Logger &logger, const std::string &prefix)
 
void addToGUI (mc_rtc::gui::StateBuilder &gui, const std::vector< std::string > &category)
 
void removeFromLogger ()
 
void removeFromGUI ()
 
std::string name () const
 

Protected Member Functions

void addToLoggerImpl ()
 
void addToGUIImpl ()
 
Derived & derived ()
 
void addToLogger_ ()
 
void addToGUI_ ()
 

Protected Attributes

std::atomic< bool > running_ = false
 
bool inLogger_ = false
 
bool inGUI_ = false
 
bool startedOnce_ = false
 
std::future< Result > futureResult_
 
bool canGetSharedState_ = false
 
std::optional< Result > lastResult_
 
Timers timers_
 
Input input_
 Input data for the asynchronous job. More...
 
mc_rtc::Loggerlogger_ = nullptr
 
std::string loggerPrefix_ = ""
 
mc_rtc::gui::StateBuildergui_ = nullptr
 
std::vector< std::string > guiCategory_
 

Detailed Description

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
DerivedThe child class type (CRTP).
InputThe input type for the job.
ResultThe 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

struct MyAsyncJob : public mc_rtc::MakeAsyncJob<MyAsyncJob, MyInput, MyResult>
{
MyResult computeJob()
{
MyResult res;
res.value = input.data * 2;
return res;
}
// Optional: add logging
{
logger_->addLogEntry("my_job_value", this, [this]() { return lastResult_->value; });
}
// Optional: add GUI
void addToGUIImpl()
{
gui_->addElement(this, guiCategory_, mc_rtc::gui::Label("Result", [this]() { return lastResult_->value; }));
}
};
// Usage:
MyAsyncJob job;
job.input = ...;
job.startAsync();
// Later, check for completion:
if(job.checkResult())
{
auto result = *job.lastResult();
}
// To enable deferred logger/GUI calls:
job.addToLogger(logger, "prefix");
job.addToGUI(gui, {"Category"});
// Upon destruction, GUI and logging entries are automatically removed.
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

Constructor & Destructor Documentation

◆ AsyncJob() [1/3]

template<typename Derived , typename Input , typename Result >
mc_rtc::threading::AsyncJob< Derived, Input, Result >::AsyncJob ( )
default

◆ AsyncJob() [2/3]

template<typename Derived , typename Input , typename Result >
mc_rtc::threading::AsyncJob< Derived, Input, Result >::AsyncJob ( const AsyncJob< Derived, Input, Result > &  )
delete

◆ AsyncJob() [3/3]

template<typename Derived , typename Input , typename Result >
mc_rtc::threading::AsyncJob< Derived, Input, Result >::AsyncJob ( AsyncJob< Derived, Input, Result > &&  )
delete

◆ ~AsyncJob()

template<typename Derived , typename Input , typename Result >
mc_rtc::threading::AsyncJob< Derived, Input, Result >::~AsyncJob ( )
inline

Member Function Documentation

◆ addToGUI()

template<typename Derived , typename Input , typename Result >
void mc_rtc::threading::AsyncJob< Derived, Input, Result >::addToGUI ( mc_rtc::gui::StateBuilder gui,
const std::vector< std::string > &  category 
)
inline

◆ addToGUI_()

template<typename Derived , typename Input , typename Result >
void mc_rtc::threading::AsyncJob< Derived, Input, Result >::addToGUI_ ( )
inlineprotected

◆ addToGUIImpl()

template<typename Derived , typename Input , typename Result >
void mc_rtc::threading::AsyncJob< Derived, Input, Result >::addToGUIImpl ( )
inlineprotected

◆ addToLogger()

template<typename Derived , typename Input , typename Result >
void mc_rtc::threading::AsyncJob< Derived, Input, Result >::addToLogger ( mc_rtc::Logger logger,
const std::string &  prefix 
)
inline

◆ addToLogger_()

template<typename Derived , typename Input , typename Result >
void mc_rtc::threading::AsyncJob< Derived, Input, Result >::addToLogger_ ( )
inlineprotected

◆ addToLoggerImpl()

template<typename Derived , typename Input , typename Result >
void mc_rtc::threading::AsyncJob< Derived, Input, Result >::addToLoggerImpl ( )
inlineprotected

◆ checkResult()

template<typename Derived , typename Input , typename Result >
bool mc_rtc::threading::AsyncJob< Derived, Input, Result >::checkResult ( )
inline

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.

◆ derived()

template<typename Derived , typename Input , typename Result >
Derived& mc_rtc::threading::AsyncJob< Derived, Input, Result >::derived ( )
inlineprotected

◆ input()

template<typename Derived , typename Input , typename Result >
Input& mc_rtc::threading::AsyncJob< Derived, Input, Result >::input ( )
inline

Access the input data for the job.

Returns a writable reference to the input. Throws std::runtime_error if the async job is running. Only modify the input when running() is false.

Returns
Reference to the input data.
Exceptions
std::runtime_errorif the job is running.

◆ lastResult()

template<typename Derived , typename Input , typename Result >
const std::optional<Result>& mc_rtc::threading::AsyncJob< Derived, Input, Result >::lastResult ( ) const
inlinenoexcept

◆ name()

template<typename Derived , typename Input , typename Result >
std::string mc_rtc::threading::AsyncJob< Derived, Input, Result >::name ( ) const
inline

◆ operator=() [1/2]

template<typename Derived , typename Input , typename Result >
AsyncJob& mc_rtc::threading::AsyncJob< Derived, Input, Result >::operator= ( AsyncJob< Derived, Input, Result > &&  )
delete

◆ operator=() [2/2]

template<typename Derived , typename Input , typename Result >
AsyncJob& mc_rtc::threading::AsyncJob< Derived, Input, Result >::operator= ( const AsyncJob< Derived, Input, Result > &  )
delete

◆ removeFromGUI()

template<typename Derived , typename Input , typename Result >
void mc_rtc::threading::AsyncJob< Derived, Input, Result >::removeFromGUI ( )
inline

◆ removeFromLogger()

template<typename Derived , typename Input , typename Result >
void mc_rtc::threading::AsyncJob< Derived, Input, Result >::removeFromLogger ( )
inline

◆ running()

template<typename Derived , typename Input , typename Result >
bool mc_rtc::threading::AsyncJob< Derived, Input, Result >::running ( ) const
inlinenoexcept

◆ startAsync()

template<typename Derived , typename Input , typename Result >
void mc_rtc::threading::AsyncJob< Derived, Input, Result >::startAsync ( )
inline

◆ startedOnce()

template<typename Derived , typename Input , typename Result >
bool mc_rtc::threading::AsyncJob< Derived, Input, Result >::startedOnce ( ) const
inlinenoexcept
Returns
True if the job has been started at least once.

Member Data Documentation

◆ canGetSharedState_

template<typename Derived , typename Input , typename Result >
bool mc_rtc::threading::AsyncJob< Derived, Input, Result >::canGetSharedState_ = false
protected

◆ futureResult_

template<typename Derived , typename Input , typename Result >
std::future<Result> mc_rtc::threading::AsyncJob< Derived, Input, Result >::futureResult_
protected

◆ gui_

template<typename Derived , typename Input , typename Result >
mc_rtc::gui::StateBuilder* mc_rtc::threading::AsyncJob< Derived, Input, Result >::gui_ = nullptr
protected

◆ guiCategory_

template<typename Derived , typename Input , typename Result >
std::vector<std::string> mc_rtc::threading::AsyncJob< Derived, Input, Result >::guiCategory_
protected

◆ inGUI_

template<typename Derived , typename Input , typename Result >
bool mc_rtc::threading::AsyncJob< Derived, Input, Result >::inGUI_ = false
protected

◆ inLogger_

template<typename Derived , typename Input , typename Result >
bool mc_rtc::threading::AsyncJob< Derived, Input, Result >::inLogger_ = false
protected

◆ input_

template<typename Derived , typename Input , typename Result >
Input mc_rtc::threading::AsyncJob< Derived, Input, Result >::input_
protected

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.

◆ lastResult_

template<typename Derived , typename Input , typename Result >
std::optional<Result> mc_rtc::threading::AsyncJob< Derived, Input, Result >::lastResult_
protected

◆ logger_

template<typename Derived , typename Input , typename Result >
mc_rtc::Logger* mc_rtc::threading::AsyncJob< Derived, Input, Result >::logger_ = nullptr
protected

◆ loggerPrefix_

template<typename Derived , typename Input , typename Result >
std::string mc_rtc::threading::AsyncJob< Derived, Input, Result >::loggerPrefix_ = ""
protected

◆ running_

template<typename Derived , typename Input , typename Result >
std::atomic<bool> mc_rtc::threading::AsyncJob< Derived, Input, Result >::running_ = false
protected

◆ startedOnce_

template<typename Derived , typename Input , typename Result >
bool mc_rtc::threading::AsyncJob< Derived, Input, Result >::startedOnce_ = false
protected

◆ timers_

template<typename Derived , typename Input , typename Result >
Timers mc_rtc::threading::AsyncJob< Derived, Input, Result >::timers_
protected

The documentation for this struct was generated from the following file: