File: monitor.hpp

package info (click to toggle)
sight 25.2.0-2
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 42,184 kB
  • sloc: cpp: 289,476; xml: 17,257; ansic: 9,878; python: 1,379; sh: 144; makefile: 33
file content (382 lines) | stat: -rw-r--r-- 12,562 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
/************************************************************************
 *
 * Copyright (C) 2009-2025 IRCAD France
 * Copyright (C) 2012-2017 IHU Strasbourg
 *
 * This file is part of Sight.
 *
 * Sight is free software: you can redistribute it and/or modify it under
 * the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Sight is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with Sight. If not, see <https://www.gnu.org/licenses/>.
 *
 ***********************************************************************/

#pragma once

#include <sight/core/config.hpp>

#include <core/com/signal.hpp>
#include <core/mt/types.hpp>
#include <core/progress/function.hpp>

#include <cstdint>
#include <functional>
#include <future>
#include <string>
#include <vector>

namespace sight::core::progress
{

/**
 * @brief  Represents a monitor class for managing long tasks.
 *
 * The monitor class provides functionality for tracking tasks states, progress,
 * and handling callbacks for various events such as logging, cancellation,
 * progress updates, and state changes. It also allows tasks to be canceled and
 * provides mechanisms to hook custom behaviors through callbacks at different
 * stages of the task lifecycle.
 */
class SIGHT_CORE_CLASS_API monitor : public core::base_object
{
public:

    SIGHT_DECLARE_CLASS(monitor, core::base_object);
    SIGHT_ALLOW_SHARED_FROM_THIS();

    /**
     * @brief monitor's states
     *
     * State :
     * - WAITING : The monitor is ready to be used
     * - RUNNING : The monitor is currently running
     * - CANCELING : The monitor received a cancel request
     * - CANCELED : The monitor is canceled
     * - FINISHED : The monitor have finished to run his task
     */
    enum state
    {
        waiting = 0,
        running,
        canceling,
        canceled,
        finished
    };

    /**
     * @name Typedef used in monitor
     * @{ */
    /// Log callback type for log hook
    using log_hook = std::function<void (monitor&, const std::string&)>;

    /// Done work callback type for done work hook
    using done_work_hook = std::function<void (monitor&, std::uint64_t)>;

    /// Work units callback type for total work unit hook
    using total_work_units_hook = std::function<void (monitor&, std::uint64_t)>;

    /// Cancel callback type for cancel hook
    using cancel_hook = std::function<void ()>;

    /// State callback type for state hook
    using state_hook = std::function<void (state)>;

    /// monitor cancel callback sequence type for cancel hook
    using cancel_hook_seq = std::vector<cancel_hook>;

    /// Done work callback sequence type for done work hook
    using done_work_hook_seq = std::vector<done_work_hook>;

    /// Work units callback sequence type for total work unit hook
    using total_work_units_hook_seq = std::vector<total_work_units_hook>;

    /// Log callback sequence type for log hook
    using log_hook_seq = std::vector<log_hook>;

    /// Log callback sequence type for state hook
    using state_hook_seq = std::vector<state_hook>;

    /// Log container type
    using logs = std::vector<std::string>;

    /// State signal type
    using state_signal = core::com::signal<void ()>;

    /// Cancel request signal type
    using cancel_requested_signal = core::com::signal<void ()>;

    /// Done work signal type
    using done_work_signal = core::com::signal<void (std::uint64_t, std::uint64_t)>;

    /// Log signal type
    using log_signal = core::com::signal<void (std::string)>;

    /// Future type
    using shared_future = std::shared_future<void>;
    /**  @} */

    /**
     * @brief Default constructor.
     *
     * @param _name The name of the monitor.
     */
    SIGHT_CORE_API explicit monitor(std::string _name = "");

    /// Default destructor.
    SIGHT_CORE_API ~monitor() override;

    /**
     * @name Not implemented
     * @{ */
    monitor(monitor&)                      = delete;
    monitor& operator=(const monitor&)     = delete;
    monitor(monitor&&) noexcept            = delete;
    monitor& operator=(monitor&&) noexcept = delete;
    /**  @} */

    /// Getter on the number of done work units.
    SIGHT_CORE_API std::uint64_t get_done_work_units() const;

    /// Getter on the total number of work units.
    SIGHT_CORE_API std::uint64_t get_total_work_units() const;

    /// Getter on the current State. @see State
    SIGHT_CORE_API state get_state() const;

    ///Getter on the name of the monitor.
    SIGHT_CORE_API const std::string& name() const;

    /// Getter on the log container
    SIGHT_CORE_API logs get_logs() const;

    /// Getter on cancelable, returns whether the monitor is cancelable.
    SIGHT_CORE_API bool is_cancelable() const;

    /// Setter on cancelable.
    SIGHT_CORE_API void set_cancelable(bool _cancel);

    /**
     * @brief Returns the monitor canceling status.
     *
     * @return A boolean: true if cancel have been requested.
     */
    SIGHT_CORE_API bool cancel_requested() const;

    /**
     * @brief Returns a callback on monitor canceling status.
     * This callback can only be used if the monitor is still instantiated.
     * @return A callback to check if the monitor have been requested.
     */
    SIGHT_CORE_API cancel_request_callback_t cancel_requested_callback() const;

    /**
     * @brief Cancel the current monitor and call all available cancel callbacks.
     */
    SIGHT_CORE_API virtual void cancel();

    /**
     * @brief Add cancel callback to sequence for cancel hook
     *
     * @param _callback monitor cancel callback
     */
    SIGHT_CORE_API void add_cancel_hook(cancel_hook _callback);

    /**
     * @brief Add monitor done work unit callback to sequence for done work hook
     *
     * @param _callback monitor done work unit callback, taking a monitor as parameter
     */
    SIGHT_CORE_API void add_done_work_hook(done_work_hook _callback);

    /**
     * @brief Add monitor work unit callback to sequence for total work unit hook
     *
     * @param _callback monitor work unit callback, taking a monitor as parameter
     */
    SIGHT_CORE_API void add_total_work_units_hook(total_work_units_hook _callback);

    /**
     * @brief Add monitor log callback to sequence for log hook
     *
     * @param _callback monitor log callback, taking a std::string message as parameter
     */
    SIGHT_CORE_API void add_log_hook(log_hook _callback);

    /**
     * @brief Add monitor state callback to sequence for state hook
     *
     * @param _callback monitor state callback, taking a State as parameter
     */
    SIGHT_CORE_API void add_state_hook(state_hook _callback);

    /**
     * @brief Log a message.
     *
     * Push the message in the log container and emit a logged
     * signal with log as parameter. finally call all log callbacks
     *
     * @param _message the message to log
     */
    SIGHT_CORE_API void log(const std::string& _message);

protected:

    /// Run the monitor: set state to running.
    SIGHT_CORE_API void run();

    /// Finish the monitor: set state to finished or canceled.
    SIGHT_CORE_API virtual void finish();

    /// Finish the monitor without mutex lock: set the state to finished or canceled.
    SIGHT_CORE_API void finish_no_lock();

    /// Getter on the state without mutex lock
    SIGHT_CORE_API state get_state_no_lock() const;

    /// Setter on the state
    SIGHT_CORE_API void set_state(state _state);

    /// Setter on the state without mutex lock
    SIGHT_CORE_API void set_state_no_lock(state _state);

    /// Setter on done work units
    SIGHT_CORE_API void done_work(std::uint64_t _units);

    /**
     * @brief Setter on done work units
     * @warning This method leaves \p lock in an unlocked state
     *
     * @param _units  new done work units
     * @param _lock   mutex to upgrade to write lock
     */
    SIGHT_CORE_API void done_work(std::uint64_t _units, core::mt::read_to_write_lock& _lock);

    /// Set done work units to total work units
    SIGHT_CORE_API void done();

    /**
     * @brief Setter on total work units.
     *
     * @param _units New total for work units.
     */
    SIGHT_CORE_API void set_total_work_units(std::uint64_t _units);

    /**
     * @brief Setter on total work units
     * @warning This method leaves \p lock in an unlocked state
     *
     * @param _units new total work units
     * @param _lock mutex to upgrade to write lock
     */
    SIGHT_CORE_API void set_total_work_units_upgrade_lock(std::uint64_t _units, core::mt::read_to_write_lock& _lock);

    /**
     * @brief Add monitor cancel callback to sequence without mutex lock for cancel hook
     *
     * @param _callback monitor cancel callback, taking a monitor as parameter or not
     */
    SIGHT_CORE_API void add_cancel_hook_no_lock(cancel_hook _callback);

    /**
     * @brief Add monitor done work unit callback to sequence without mutex lock for done work hook
     *
     * @param _callback monitor done work unit callback, taking a monitor as parameter
     */
    SIGHT_CORE_API void add_done_work_hook_no_lock(done_work_hook _callback);

    /**
     * @brief Add monitor work unit callback to sequence without mutex lock for total work unit hook
     *
     * @param _callback monitor work unit callback, taking a monitor as parameter
     */
    SIGHT_CORE_API void add_total_work_units_hook_no_lock(total_work_units_hook _callback);

    /**
     * @brief Add monitor log callback to sequence without mutex lock for log hook
     *
     * @param _callback monitor log callback, taking a std::string message as parameter
     */
    SIGHT_CORE_API void add_log_hook_no_lock(log_hook _callback);

    /**
     * @brief Add cancel callback to sequence without mutex lock for state hook
     *
     * @param _callback cancel callback, taking a State as parameter
     */
    SIGHT_CORE_API void add_state_hook_no_lock(state_hook _callback);

    /**
     * @brief Add a message to the log sequence.
     *
     * @param _message the message to add to the sequence
     */
    SIGHT_CORE_API void log_no_lock(const std::string& _message);

    /// Signal emitted when cancel has been requested
    SPTR(cancel_requested_signal) m_sig_cancel_requested;

    /// Signal emitted when the monitor has been canceled.
    SPTR(state_signal) m_sig_canceled;

    /// Signal emitted when the monitor has been started.
    SPTR(state_signal) m_sig_started;

    /// Signal emitted when the monitor has been finished.
    SPTR(state_signal) m_sig_finished;

    /// Signal emitted when done work units have been changed. Takes a std::uint64_t as parameter.
    SPTR(done_work_signal) m_sig_done_work;

    /// Signal emitted when a message has been added to logs. Takes a std::string as parameter.
    SPTR(log_signal) m_sig_logged;

    /// Mutex to protect object access.
    mutable core::mt::read_write_mutex m_mutex;

    /// monitor's name
    std::string m_name;

    /// Logs container
    logs m_logs;

    /// Number of work units already reached.
    std::uint64_t m_done_work_units {0};

    /// Number of work units to reach to complete the monitor.
    std::uint64_t m_total_work_units {0};

    /// Determines if cancellation has been requested. The monitor is/will be canceling if true.
    bool m_cancel_requested {false};

    /// Determines if the monitor can be cancelled. The monitor is cancelable if true.
    bool m_cancelable {false};

    /// Container of cancel callbacks. Cancel callbacks will be run when monitor is canceling.
    cancel_hook_seq m_cancel_hooks;

    /// Container of done work callbacks. These callbacks take nothing or a monitor as parameter.
    done_work_hook_seq m_done_work_hooks;

    /// Container of total work unit callbacks. These callbacks take a monitor as parameter.
    total_work_units_hook_seq m_total_work_units_hooks;

    /// Container of log callbacks. These callbacks take a std::string as parameter.
    log_hook_seq m_log_hooks;

    /// Container of state callbacks. These callbacks take a State as parameter.
    state_hook_seq m_state_hooks;

    /// monitor's state
    state m_state {waiting};
};

} //namespace sight::core::progress