ImFusion SDK 4.3
NestedProgress Class Reference

#include <ImFusion/Base/NestedProgress.h>

Wrapper class to provide the Progress interface, ensure certain invariants for created tasks and/or optionally forward the progress information to an existing Progress. More...

+ Inheritance diagram for NestedProgress:

Detailed Description

Wrapper class to provide the Progress interface, ensure certain invariants for created tasks and/or optionally forward the progress information to an existing Progress.

The main use case of this class if you have a consumer accepting a Progress and want to achieve one of the following things:

  • You want to perform some custom action every time a progress update is reported, for instance:
    // Forward progress updates to parent Progress instance
    NestedProgress nestedProgress(m_progress);
    // additionally call `refresh()` every time the algorithm reports a progress update
    nestedProgres.signalTaskUpdated.connect([this](auto) { this->refresh(); });
    algorithm.compute(&nestedProgress);
    NestedProgress(Progress *parent=nullptr, Flags< TaskMode > taskFlags=TaskMode::Default)
    Creates a new NestedProgress instance.
  • You have an existing Progress instance that the consumer should report to but you need to ensure additional invariants that the consumer is not aware of. For instance you want to make sure that progress reporting is thread-safe even though the consumer is not.
    // wrapping `m_progress` in a NestedProgress with `ThreadSafe` flag allows for access from other threads
    NestedProgress asyncProgress(m_progress, NestedProgress::ThreadSafe);
    std::thread thread([&asyncProgress]() {
    // access to `asyncProgress` is thread-safe, access to `m_progress` not
    compute(asyncProgress);
    }
    // ensure that `asyncProgress` outlives the lifetime of the thread
    thread.join();
    @ ThreadSafe
    When creating tasks from this reporter it will call Task::requestThreadSafety() on them.
    Definition NestedProgress.h:75
  • You do not want to forward the progress updates to an existing reporter but use the Progress interface as back-channel in order to signal if the consumer should abort execution (cf. Task::wasCanceled()). Often such setups happen in a multi-threaded environment. In this case make sure to pass the ThreadSafe flag.
    void compute() {
    // creating a NestedProgress without parent will not show the progress updates
    // but still provides a back-channel for the cancellation state
    for (auto* element : m_elements)
    threadPool.enqueue([element, &reporter]() { m_algorithm->run(element, reporter); });
    threadPool.join();
    }
    void onCancelRequested() {
    // use Progress interface to notify sub tasks that they shall abort their computation
    if (m_reporter)
    m_reporter->cancelAllTasks();
    }
    Lightweight implementation of a thread pool for distributing work onto a fixed number of threads.
    Definition ThreadPool.h:37
    auto enqueue(Function &&func, Args &&... args) -> std::future< ResultOf< Function, Args... > >
    Enqueue a single task.
    Definition ThreadPool.h:148
    void join()
    Join all worker threads and wait until all enqueued tasks have finished.
    T make_unique(T... args)

Public Types

enum  TaskMode { Default = 0 , ThreadSafe = 1 << 0 , Hidden = 1 << 1 }
 Enumeration of possible invariants that should be ensured by NestedProgress. More...
 

Public Member Functions

 NestedProgress (Progress *parent=nullptr, Flags< TaskMode > taskFlags=TaskMode::Default)
 Creates a new NestedProgress instance.
 
void setParentProgress (Progress *parent)
 Updates the parent Progress instance to which progress updates should be forwarded to.
 
void cancelAllTasks ()
 Will cancel all tasks that were spawned from this NestedProgress instance.
 
- Public Member Functions inherited from Progress
Task addTask (int numSteps, const std::string &description)
 Create a new progress report for an operation with the given number of steps.
 
Task addBusyIndicator (const std::string &description)
 Create a busy indicator for an operation but does not have a predefined number of steps.
 

Public Attributes

ProtectedSignal< Task * > signalTaskAdded
 Signal emitted by the default implementation of NestedProgress::onTaskAdded().
 
ProtectedSignal< const Task * > signalTaskUpdated
 Signal emitted by the default implementation of NestedProgress::onTaskUpdated().
 

Protected Member Functions

void onTaskAdded (Task *task) override
 Function is called whenever a new Task has been created.
 
void onTaskUpdated (const Task *task) override
 Function is called whenever the state of a Task has changed and the reporter should update its UI.
 
bool onTaskRequestsThreadSafety (const Task *task) override
 Function is called by Task::requestThreadSafety() in order to check whether the parent reporter supports concurrent access.
 
void onTaskRemoved (const Task *task) override
 Function is called whenever a Task is about to be destroyed and its pointer will become invalid.
 

Protected Attributes

Progressm_parent
 
const Flags< TaskModem_taskFlags
 
std::unique_ptr< std::mutexm_mutex
 
std::unique_ptr< Taskm_parentThreadSafetyGuard
 
std::vector< Task * > m_tasks
 

Member Enumeration Documentation

◆ TaskMode

enum TaskMode

Enumeration of possible invariants that should be ensured by NestedProgress.

Enumerator
Default 

Tasks created from this reporter are kept as they are.

ThreadSafe 

When creating tasks from this reporter it will call Task::requestThreadSafety() on them.

Hidden 

When creating tasks from this reporter it will call Task::setVisible(false) on them.

Constructor & Destructor Documentation

◆ NestedProgress()

NestedProgress ( Progress * parent = nullptr,
Flags< TaskMode > taskFlags = TaskMode::Default )
explicit

Creates a new NestedProgress instance.

Parameters
parentOptional parent progress instance to which progress updates should be forwarded to.
taskFlagsOptional set of invariants that tasks created by this instance should adhere to.

Member Function Documentation

◆ onTaskAdded()

void onTaskAdded ( Task * task)
overrideprotectedvirtual

Function is called whenever a new Task has been created.

Implements Progress.

◆ onTaskUpdated()

void onTaskUpdated ( const Task * task)
overrideprotectedvirtual

Function is called whenever the state of a Task has changed and the reporter should update its UI.

Implements Progress.

Reimplemented in WatershedComputer.

◆ onTaskRequestsThreadSafety()

bool onTaskRequestsThreadSafety ( const Task * task)
overrideprotectedvirtual

Function is called by Task::requestThreadSafety() in order to check whether the parent reporter supports concurrent access.

Implementations are free to ignore this request and return false. Otherwise they must ensure that subsequent concurrent calls to any of the onTask...() callbacks are handled correctly without race conditions. Implementations are free to return to a unsynchronized implementation as soon as all multi-threaded tasks have been removed from the reporter.

Implements Progress.

◆ onTaskRemoved()

void onTaskRemoved ( const Task * task)
overrideprotectedvirtual

Function is called whenever a Task is about to be destroyed and its pointer will become invalid.

Implements Progress.

Member Data Documentation

◆ signalTaskAdded

ProtectedSignal<Task*> signalTaskAdded

Signal emitted by the default implementation of NestedProgress::onTaskAdded().

Subscription to this signal is useful in case you want to customize progress tasks without inheriting from NestedProgress.

◆ signalTaskUpdated

ProtectedSignal<const Task*> signalTaskUpdated

Signal emitted by the default implementation of NestedProgress::onTaskUpdated().

Subscription to this signal is useful in case you want to perform custom action on progress updates without inheriting from NestedProgress.


The documentation for this class was generated from the following file:
Search Tab / S to search, Esc to close