Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
Tasking::Storage< StorageStruct > Class Template Referencefinal

\inheaderfile solutions/tasking/tasktree.h \inmodule TaskingSolution More...

#include <tasktree.h>

+ Inheritance diagram for Tasking::Storage< StorageStruct >:
+ Collaboration diagram for Tasking::Storage< StorageStruct >:

Public Member Functions

 Storage ()
 Creates a storage for the given StorageStruct type.
 
StorageStruct & operator* () const noexcept
 Returns a reference to the active StorageStruct object, created by the running task tree.
 
StorageStruct * operator-> () const noexcept
 Returns a pointer to the active StorageStruct object, created by the running task tree.
 
StorageStruct * activeStorage () const
 Returns a pointer to the active StorageStruct object, created by the running task tree.
 

Detailed Description

template<typename StorageStruct>
class Tasking::Storage< StorageStruct >

\inheaderfile solutions/tasking/tasktree.h \inmodule TaskingSolution

A class template for custom data exchange in the running task tree. \reentrant

The Storage class template is responsible for dynamically creating and destructing objects of the custom StorageStruct type. The creation and destruction are managed by the running task tree. If a Storage object is placed inside a \l {Tasking::Group} {Group} element, the running task tree creates the StorageStruct object when the group is started and before the group's setup handler is called. Later, whenever any handler inside this group is called, the task tree activates the previously created instance of the StorageStruct object. This includes all tasks' and groups' setup and done handlers inside the group where the Storage object was placed, also within the nested groups. When a copy of the Storage object is passed to the handler via the lambda capture, the handler may access the instance activated by the running task tree via the \l {Tasking::Storage::operator->()} {operator->()}, \l {Tasking::Storage::operator*()} {operator*()}, or activeStorage() method. If two handlers capture the same Storage object, one of them may store a custom data there, and the other may read it afterwards. When the group is finished, the previously created instance of the StorageStruct object is destroyed after the group's done handler is called.

An example of data exchange between tasks:

const Storage<QString> storage;
const auto onFirstDone = [storage](const Task &task) {
// Assings QString, taken from the first task result, to the active QString instance
// of the Storage object.
*storage = task.getResultAsString();
};
const auto onSecondSetup = [storage](Task &task) {
// Reads QString from the active QString instance of the Storage object and use it to
// configure the second task before start.
task.configureWithString(*storage);
};
const Group root {
// The running task tree creates QString instance when root in entered
// The done handler of the first task stores the QString in the storage
TaskItem(..., onFirstDone),
// The setup handler of the second task reads the QString from the storage
TaskItem(onSecondSetup, ...)
};
QStorageInfo storage
[1]

Since the root group executes its tasks sequentially, the onFirstDone handler is always called before the onSecondSetup handler. This means that the QString data, read from the storage inside the onSecondSetup handler's body, has already been set by the onFirstDone handler. You can always rely on it in \l {Tasking::sequential} {sequential} execution mode.

The Storage internals are shared between all of its copies. That is why the copies of the Storage object inside the handlers' lambda captures still refer to the same Storage instance. You may place multiple Storage objects inside one \l {Tasking::Group} {Group} element, provided that they do not include copies of the same Storage object. Otherwise, an assert is triggered at runtime that includes an error message. However, you can place copies of the same Storage object in different \l {Tasking::Group} {Group} elements of the same recipe. In this case, the running task tree will create multiple instances of the StorageStruct objects (one for each copy) and storage shadowing will take place. Storage shadowing works in a similar way to C++ variable shadowing inside the nested blocks of code:

Storage<QString> storage;
const Group root {
storage, // Top copy, 1st instance of StorageStruct
onGroupSetup([storage] { ... }), // Top copy is active
storage, // Nested copy, 2nd instance of StorageStruct,
// shadows Top copy
onGroupSetup([storage] { ... }), // Nested copy is active
},
Group {
onGroupSetup([storage] { ... }), // Top copy is active
}
};
\inheaderfile solutions/tasking/tasktree.h \inmodule TaskingSolution
Definition tasktree.h:327
static GroupItem onGroupSetup(Handler &&handler)
\typealias GroupItem::GroupSetupHandler
Definition tasktree.h:387

The Storage objects may also be used for passing the initial data to the executed task tree, and for reading the final data out of the task tree before it finishes. To do this, use \l {TaskTree::onStorageSetup()} {onStorageSetup()} or \l {TaskTree::onStorageDone()} {onStorageDone()}, respectively.

Note
If you use an unreachable Storage object inside the handler, because you forgot to place the storage in the recipe, or placed it, but not in any handler's ancestor group, you may expect a crash, preceded by the following message: {The referenced storage is not reachable in the running tree. A nullptr will be returned which might lead to a crash in the calling code. It is possible that no storage was added to the tree, or the storage is not reachable from where it is referenced.}

Definition at line 191 of file tasktree.h.

Constructor & Destructor Documentation

◆ Storage()

template<typename StorageStruct >
template< typename StorageStruct > Tasking::Storage< StorageStruct >::Storage< StorageStruct > ( )
inline

Creates a storage for the given StorageStruct type.

Note
All copies of this object are considered to be the same Storage instance.

Definition at line 194 of file tasktree.h.

Member Function Documentation

◆ activeStorage()

template<typename StorageStruct >
template< typename StorageStruct > StorageStruct * Tasking::Storage< StorageStruct >::activeStorage ( ) const
inline

Returns a pointer to the active StorageStruct object, created by the running task tree.

Use this function only from inside the handler body of any GroupItem element placed in the recipe, otherwise you may expect a crash. Make sure that Storage is placed in any group ancestor of the handler's group item.

Note
The returned pointer is valid as long as the group that created this instance is still running.
See also
operator->(), operator*()

Definition at line 197 of file tasktree.h.

Referenced by Tasking::Storage< StorageStruct >::operator*(), and Tasking::Storage< StorageStruct >::operator->().

+ Here is the caller graph for this function:

◆ operator*()

template<typename StorageStruct >
template< typename StorageStruct > StorageStruct & Tasking::Storage< StorageStruct >::operator* ( ) const
inlinenoexcept

Returns a reference to the active StorageStruct object, created by the running task tree.

Use this function only from inside the handler body of any GroupItem element placed in the recipe, otherwise you may expect a crash. Make sure that Storage is placed in any group ancestor of the handler's group item.

Note
The returned reference is valid as long as the group that created this instance is still running.
See also
activeStorage(), operator->()

Definition at line 195 of file tasktree.h.

References Tasking::Storage< StorageStruct >::activeStorage().

+ Here is the call graph for this function:

◆ operator->()

template<typename StorageStruct >
template< typename StorageStruct > StorageStruct * Tasking::Storage< StorageStruct >::operator-> ( ) const
inlinenoexcept

Returns a pointer to the active StorageStruct object, created by the running task tree.

Use this function only from inside the handler body of any GroupItem element placed in the recipe, otherwise you may expect a crash. Make sure that Storage is placed in any group ancestor of the handler's group item.

Note
The returned pointer is valid as long as the group that created this instance is still running.
See also
activeStorage(), operator*()

Definition at line 196 of file tasktree.h.

References Tasking::Storage< StorageStruct >::activeStorage().

+ Here is the call graph for this function:

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