Bifrost SDK
Bifrost SDK documentation
TaskObserver.h
Go to the documentation of this file.
1//-
2//*****************************************************************************
3// Copyright (c) 2025 Autodesk, Inc. All rights reserved.
4//
5// These coded instructions, statements, and computer programs contain
6// unpublished proprietary information written by Autodesk, Inc. and are
7// protected by Federal copyright law. They may not be disclosed to third
8// parties or copied or duplicated in any form, in whole or in part, without
9// the prior written consent of Autodesk, Inc.
10//*****************************************************************************
11//+
12
16
17#ifndef AMINO_CORE_TASK_OBSERVER_H
18#define AMINO_CORE_TASK_OBSERVER_H
19
21
23
24#include <Amino/Core/Message.h>
25#include <Amino/Core/Span.h>
27
28#include <Amino/Core/internal/PImpl.h>
29
30#include <cstdint> // uint8_t
31#include <utility>
32
33#define AMINO_API AMINO_CORE_SHARED_DECL
34
35//==============================================================================
36// NAMESPACE Amino
37//==============================================================================
38
39namespace Amino {
40
41//==============================================================================
42// ENUM TaskStatus
43//==============================================================================
44
47public:
48 /*----- types -----*/
49
50 enum Status : uint8_t {
53
56
59
63 };
64
65 /*----- member functions -----*/
66
68 TaskStatus() = default;
69
71 // NOLINTNEXTLINE(google-explicit-constructor)
72 /*implicit*/ TaskStatus(Status status) noexcept : m_status{status} {}
73
75 // NOLINTNEXTLINE(google-explicit-constructor)
76 /*implicit*/ operator Status() const { return m_status; }
77
79 explicit operator bool() const { return m_status == eSuccess; }
80
81private:
82 /*----- data members -----*/
83
85 Status m_status{eSuccess};
86};
87
88//==============================================================================
89// CLASS ITaskObserver
90//==============================================================================
91
97public:
98 /*----- types -----*/
99
102
103 /*----- member functions -----*/
104
106 ITaskObserver() = default;
107
109 virtual ~ITaskObserver();
110
111protected:
113
114 /*----- member functions -----*/
115
117 virtual void onStart() noexcept;
118
120 virtual void onProgress(
121 StringView const& title, unsigned num, unsigned denum) noexcept;
122
124 virtual void onMessage(Message const& message) noexcept;
125
127 virtual void onDone(TaskStatus status) noexcept = 0;
128};
129
130//==============================================================================
131// CLASS TaskObserver
132//==============================================================================
133
144public:
145 /*----- static member functions -----*/
146
153 // LCOV_EXCL_BR_START
154 template <typename T, typename... Args>
155 static TaskObserverT<T> make(Args&&... args);
156 // LCOV_EXCL_BR_STOP
157
158 /*----- member functions -----*/
159
162
165
170 AMINO_API TaskObserver& operator=(TaskObserver&& o) noexcept;
171
177
181 AMINO_API bool isValid() const;
182
183 inline explicit operator bool() const { return isValid(); }
185
189 TaskNotifier getNotifier() const;
190
194 AMINO_API bool isInUse() const;
195
197 AMINO_API void reset() noexcept;
198
199public:
201 TaskObserver(TaskObserver const&) = delete;
202
204 TaskObserver& operator=(TaskObserver const&) = delete;
205
206protected:
208
209 /*----- member functions -----*/
210
212 AMINO_API explicit TaskObserver(ITaskObserver* observer);
213
216 AMINO_API ITaskObserver const* getInterface() const;
217 AMINO_API ITaskObserver* getInterface();
220
221private:
224 AMINO_API TaskNotifier internal_getNotifier(bool& is_allowed) const;
225
226 friend TaskNotifier;
227 Internal::PImpl<TaskObserver, 2> m_impl;
229};
230
231//==============================================================================
232// CLASS TaskObserverT<T>
233//==============================================================================
234
243template <typename T>
244class TaskObserverT final : public TaskObserver {
245 static_assert(std::is_base_of_v<ITaskObserver, T>);
246
247 template <typename D>
248 using enable_if_derived = std::enable_if_t<std::is_convertible_v<D*, T*>>;
249
250public:
251 /*----- member functions -----*/
252
257 // LCOV_EXCL_BR_START
258 template <
259 typename... Args,
260 typename = std::enable_if_t<std::is_constructible_v<T, Args...>>>
261 explicit TaskObserverT(Args&&... args)
262 : TaskObserver(new T{std::forward<Args>(args)...}) {}
263 // LCOV_EXCL_BR_STOP
264
266 template <typename D, typename = enable_if_derived<D>>
267 // NOLINTNEXTLINE(google-explicit-constructor)
268 /*implicit*/ TaskObserverT(TaskObserverT<D>&& other) noexcept
269 : TaskObserver(std::move(other)) {}
270
272 template <typename D, typename = enable_if_derived<D>>
274 TaskObserver::operator=(std::move(other));
275 return *this;
276 }
277
281 T const& operator*() const { return *get_dereferenceable(); }
282 T& operator*() /* */ { return *get_dereferenceable(); }
283
284 T const* operator->() const { return get_dereferenceable(); }
285 T* operator->() /* */ { return get_dereferenceable(); }
286
287 T const* get() const { return static_cast<T const*>(getInterface()); }
288 T* get() /* */ { return static_cast<T /* */*>(getInterface()); }
290
291private:
293
294 friend TaskObserver;
295
296 /*----- member functions -----*/
297
302 T const* get_dereferenceable() const {
303 auto const* ptr = get();
304 assert(ptr);
305 return ptr;
306 }
307 T* get_dereferenceable() {
308 auto* ptr = get();
309 assert(ptr);
310 return ptr;
311 }
313
315};
316
317//==============================================================================
318// CLASS TaskNotifier
319//==============================================================================
320
326class TaskNotifier final {
327public:
328 /*----- member functions -----*/
329
332
335
337 TaskNotifier(TaskNotifier const&) = delete;
338
340 AMINO_API TaskNotifier& operator=(TaskNotifier&&) noexcept;
341
343 TaskNotifier& operator=(TaskNotifier const&) = delete;
344
347
351 AMINO_API bool isValid() const;
352
353 inline explicit operator bool() const { return isValid(); }
355
357 AMINO_API void notifyStart() const;
358
363 StringView const& title, unsigned num, unsigned denum) const {
364 assert(num <= denum);
365 internal_notifyProgress(title, num, denum);
366 }
367
369 AMINO_API void notifyMessage(Message const& message) const;
370
373 // LCOV_EXCL_BR_START
374 template <typename... Args>
375 AMINO_INTERNAL_FORCEINLINE void notifyMessage(
376 MessageKind kind,
377 Source source,
378 MessageClass cls,
379 MessageText text,
380 Args const&... args) const {
381 internal_notifyMessage(
382 std::move(source), kind, cls, text, Internal::FormatArgs{args...});
383 }
384 template <typename... Args>
385 AMINO_INTERNAL_FORCEINLINE void notifyMessage(
386 MessageKind kind,
387 MessageClass cls,
388 MessageText text,
389 Args const&... args) const {
390 internal_notifyMessage(
391 Source{}, kind, cls, text, Internal::FormatArgs{args...});
392 }
393 template <typename... Args>
394 AMINO_INTERNAL_FORCEINLINE void notifyMessage(
395 MessageKind kind, MessageText text, Args const&... args) const {
396 internal_notifyMessage(
397 Source{}, kind, MessageClass{}, text,
398 Internal::FormatArgs{args...});
399 }
400 template <typename... Args>
401 AMINO_INTERNAL_FORCEINLINE void notifyMessage(
402 MessageKind kind,
403 Source source,
404 MessageText text,
405 Args const&... args) const {
406 internal_notifyMessage(
407 std::move(source), kind, MessageClass{}, text,
408 Internal::FormatArgs{args...});
409 }
411
413 template <typename... Args>
414 AMINO_INTERNAL_FORCEINLINE void notifyDebug(Args&&... args) const {
415 notifyMessage(MessageKind::eDebug, std::forward<Args>(args)...);
416 }
417
419 template <typename... Args>
420 AMINO_INTERNAL_FORCEINLINE void notifyInfo(Args&&... args) const {
421 notifyMessage(MessageKind::eInfo, std::forward<Args>(args)...);
422 }
423
425 template <typename... Args>
426 AMINO_INTERNAL_FORCEINLINE void notifyWarning(Args&&... args) const {
427 notifyMessage(MessageKind::eWarning, std::forward<Args>(args)...);
428 }
429
431 template <typename... Args>
432 AMINO_INTERNAL_FORCEINLINE void notifyError(Args&&... args) const {
433 notifyMessage(MessageKind::eError, std::forward<Args>(args)...);
434 }
435 // LCOV_EXCL_BR_STOP
436
438 AMINO_API void notifyDone(TaskStatus status) const;
439
441 void notifySuccess() const { notifyDone(TaskStatus::eSuccess); }
442
444 void notifyError() const { notifyDone(TaskStatus::eError); }
445
448 void notifyCancelled() const { notifyDone(TaskStatus::eCancelled); }
449
451 void notifyDropped() const { notifyDone(TaskStatus::eDropped); }
452
453private:
455
456 /*----- member functions -----*/
457
459 AMINO_API void internal_notifyProgress(
460 StringView const& title, unsigned num, unsigned denum) const;
461
464 AMINO_API void internal_notifyMessage(
465 Source&& source,
466 MessageKind kind,
467 MessageClass cls,
468 MessageText text,
469 Internal::FormatArgs<0> const&) const;
470
471 AMINO_API void internal_notifyMessage(
472 Source&& source,
473 MessageKind kind,
474 MessageClass cls,
475 MessageText text,
476 SpanParam<Internal::FormatArg const> const& args) const;
478
479 /*----- data member -----*/
480
481 Internal::PImpl<TaskNotifier, 2> m_impl;
483};
484
485//==============================================================================
486// CLASS TaskProgressNotifier
487//==============================================================================
488
496public:
498 template <typename TaskNotifier>
500 TaskNotifier& notifier, StringLiteral title, unsigned denum)
501 : m_notifier{notifier},
502 m_title{title},
503 m_numerator{0},
504 m_denominator{denum} {
505 m_notifier.notifyProgress(m_title, 0, m_denominator);
506 }
507
509 void notify(unsigned n = 1) {
510 m_numerator += n;
511 m_notifier.notifyProgress(m_title, m_numerator, m_denominator);
512 }
513
514private:
516 TaskNotifier const& m_notifier;
517
519 StringLiteral m_title;
520
522 unsigned m_numerator;
523
525 const unsigned m_denominator;
526};
527
528//==============================================================================
529// CLASS TaskObserver
530//==============================================================================
531
532//------------------------------------------------------------------------------
533//
534// LCOV_EXCL_BR_START
535template <typename T, typename... Args>
536inline TaskObserverT<T> TaskObserver::make(Args&&... args) {
537 static_assert(std::is_base_of_v<ITaskObserver, T>);
538 static_assert(!std::is_abstract_v<T>);
539 static_assert(std::is_constructible_v<T, Args...>);
540 return TaskObserverT<T>(std::forward<Args>(args)...);
541}
542// LCOV_EXCL_BR_STOP
543
544//------------------------------------------------------------------------------
545//
547 bool success = true;
548 auto notifier = internal_getNotifier(success);
549 assert(success && "TaskObserver already has a notifier in use.");
550 return notifier;
551}
552
553//==============================================================================
554// CLASS ForwardTaskObserver
555//==============================================================================
556
564protected:
565 /*----- member functions -----*/
566
569 : m_notifier(std::move(notifier)) {}
570
573
575 void onStart() noexcept override;
576
578 void onProgress(
579 StringView const& title,
580 unsigned num,
581 unsigned denum) noexcept override;
582
584 void onMessage(Message const& message) noexcept override;
585
587 void onDone(TaskStatus status) noexcept override;
588
589private:
591 TaskNotifier m_notifier;
592};
593
594} // namespace Amino
595
596#undef AMINO_API
597
598#endif
Definition of macros for symbol visibility.
String view class (similar to std::string_view)
#define AMINO_API
Definition: TaskObserver.h:33
Forward declarations for task observer classes.
Definition: HostData.h:33
MessageKind
The kind of message (error, warning, info, debug).
Definition: Message.h:40
Definition: Ptr.h:2080
The "class" of the message.
Definition: Message.h:83
The text content from which to construct a message (with optional formatting specifiers).
Definition: Message.h:135
A Message object that of a specific MessageKind, optional MessageClass, and a MessageText that relate...
Definition: Message.h:170
Generic opaque handle to a source (provenance).
Definition: Source.h:35
Same as Span but the constructor from a range is implicit, making it more convenient and safe to use ...
Definition: Span.h:178
String view class (similar to std::string_view).
Definition: StringView.h:42
The completion status of a task.
Definition: TaskObserver.h:46
TaskStatus()=default
Default constructor (eSuccess status).
TaskStatus(Status status) noexcept
Constructor.
Definition: TaskObserver.h:72
@ eSuccess
The task completed successfully.
Definition: TaskObserver.h:52
@ eError
The task failed due to an error.
Definition: TaskObserver.h:58
@ eDropped
The task was dropped (because it was destroyed or cancelled before it started).
Definition: TaskObserver.h:62
@ eCancelled
The task was cancelled explicitly by the user.
Definition: TaskObserver.h:55
Abstract interface for observing the progress of a task.
Definition: TaskObserver.h:96
virtual ~ITaskObserver()
Destructor.
ITaskObserver()=default
Constructor.
virtual void onStart() noexcept
Called when the task starts (defaults to noop).
Class managing (with unique ownership) a concrete ITaskObserver.
Definition: TaskObserver.h:143
TaskNotifier getNotifier() const
Create and return a notifier associated with this observer.
Definition: TaskObserver.h:546
AMINO_CORE_SHARED_DECL TaskObserver & operator=(TaskObserver &&o) noexcept
Move assignment operator.
AMINO_CORE_SHARED_DECL void reset() noexcept
Reset the observer to a noop observer.
static TaskObserverT< T > make(Args &&... args)
Create a new concrete task observer of type T.
Definition: TaskObserver.h:536
AMINO_CORE_SHARED_DECL bool isInUse() const
Whether this TaskObserver has a TaskNotifier in use.
AMINO_CORE_SHARED_DECL TaskObserver() noexcept
Default constructor (constructs a noop observer).
Typed-version of TaskObserver.
Definition: TaskObserver.h:244
TaskObserverT(Args &&... args)
Constructs a TaskObserverT managing a concrete Amino::ITaskObserver of derived type T.
Definition: TaskObserver.h:261
T & operator*()
Get the concrete derived Amino::ITaskObserver uniquely managed by this TaskObserverT.
Definition: TaskObserver.h:282
T const * operator->() const
Get the concrete derived Amino::ITaskObserver uniquely managed by this TaskObserverT.
Definition: TaskObserver.h:284
TaskObserverT(TaskObserverT< D > &&other) noexcept
Upcast conversion constructor.
Definition: TaskObserver.h:268
TaskObserverT & operator=(TaskObserverT< D > &&other) noexcept
Upcast conversion assignment.
Definition: TaskObserver.h:273
T const & operator*() const
Get the concrete derived Amino::ITaskObserver uniquely managed by this TaskObserverT.
Definition: TaskObserver.h:281
T * operator->()
Get the concrete derived Amino::ITaskObserver uniquely managed by this TaskObserverT.
Definition: TaskObserver.h:285
T * get()
Get the concrete derived Amino::ITaskObserver uniquely managed by this TaskObserverT.
Definition: TaskObserver.h:288
T const * get() const
Get the concrete derived Amino::ITaskObserver uniquely managed by this TaskObserverT.
Definition: TaskObserver.h:287
Class referencing (non-owning) a concrete ITaskObserver.
Definition: TaskObserver.h:326
AMINO_CORE_SHARED_DECL TaskNotifier() noexcept
Default Constructor (constructs a noop notifier).
void notifySuccess() const
Notify the observer that the task has completed successfully.
Definition: TaskObserver.h:441
AMINO_INTERNAL_FORCEINLINE void notifyMessage(MessageKind kind, MessageText text, Args const &... args) const
Notify the observer that a message was reported.
Definition: TaskObserver.h:394
void notifyProgress(StringView const &title, unsigned num, unsigned denum) const
Notify the observer of the progress of a named task.
Definition: TaskObserver.h:362
AMINO_INTERNAL_FORCEINLINE void notifyWarning(Args &&... args) const
Short-hand for notifying a warning message.
Definition: TaskObserver.h:426
AMINO_CORE_SHARED_DECL void notifyStart() const
Notify the observer that the task has started.
AMINO_INTERNAL_FORCEINLINE void notifyMessage(MessageKind kind, Source source, MessageClass cls, MessageText text, Args const &... args) const
Notify the observer that a message was reported.
Definition: TaskObserver.h:375
void notifyCancelled() const
Notify the observer that the task has completed due to cancellation.
Definition: TaskObserver.h:448
AMINO_INTERNAL_FORCEINLINE void notifyMessage(MessageKind kind, MessageClass cls, MessageText text, Args const &... args) const
Notify the observer that a message was reported.
Definition: TaskObserver.h:385
AMINO_INTERNAL_FORCEINLINE void notifyError(Args &&... args) const
Short-hand for notifying an error message.
Definition: TaskObserver.h:432
void notifyError() const
Notify the observer that the task has completed with errors.
Definition: TaskObserver.h:444
AMINO_INTERNAL_FORCEINLINE void notifyMessage(MessageKind kind, Source source, MessageText text, Args const &... args) const
Notify the observer that a message was reported.
Definition: TaskObserver.h:401
AMINO_INTERNAL_FORCEINLINE void notifyDebug(Args &&... args) const
Short-hand for notifying a debug message.
Definition: TaskObserver.h:414
AMINO_CORE_SHARED_DECL void notifyMessage(Message const &message) const
Notify the observer that a message was reported.
void notifyDropped() const
Notify the observer that the task has been dropped.
Definition: TaskObserver.h:451
AMINO_CORE_SHARED_DECL void notifyDone(TaskStatus status) const
Notify the observer that the task has completed.
AMINO_INTERNAL_FORCEINLINE void notifyInfo(Args &&... args) const
Short-hand for notifying an info message.
Definition: TaskObserver.h:420
RAII-style progress notifier helper.
Definition: TaskObserver.h:495
void notify(unsigned n=1)
Notify the observer of the progress of the task.
Definition: TaskObserver.h:509
TaskProgressNotifier(TaskNotifier &notifier, StringLiteral title, unsigned denum)
Constructor.
Definition: TaskObserver.h:499
Base class for a ITaskObserver that forwards notifications to a given TaskNotifier.
Definition: TaskObserver.h:563
void onStart() noexcept override
Forwards the onStart notification to its notifier.
~ForwardTaskObserver() override
Destructor.
ForwardTaskObserver(TaskNotifier notifier)
Constructor.
Definition: TaskObserver.h:568