• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

paulmthompson / WhiskerToolbox / 17733471381

15 Sep 2025 12:43PM UTC coverage: 72.1% (+0.4%) from 71.744%
17733471381

push

github

paulmthompson
fix optional missing include on windows

37727 of 52326 relevant lines covered (72.1%)

1297.48 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

88.0
/src/DataManager/DataManager.hpp
1
#ifndef DATAMANAGER_HPP
2
#define DATAMANAGER_HPP
3

4
#include "DataManagerTypes.hpp"
5

6
#include "TimeFrame/StrongTimeTypes.hpp"
7
#include "TimeFrame/TimeFrame.hpp"
8

9
#include <filesystem>
10
#include <functional>   // std::function
11
#include <memory>       // std::shared_ptr
12
#include <optional>     // std::optional
13
#include <string>       // std::string
14
#include <unordered_map>// std::unordered_map
15
#include <variant>      // std::variant
16
#include <vector>       // std::vector
17

18
#include "nlohmann/json_fwd.hpp"
19

20
// Forward declarations for identity
21
class EntityRegistry;
22
class EntityGroupManager;
23

24
class TableRegistry;
25
struct TableEvent;
26

27
class DataManager {
28

29
public:
30
    DataManager();
31
    ~DataManager();
32
    // ======= Table Registry access =======
33
    /**
34
     * @brief Get the centralized TableRegistry owned by this DataManager
35
     */
36
    TableRegistry * getTableRegistry();
37
    TableRegistry const * getTableRegistry() const;
38

39
    // ======= Table observer channel (separate from data observers) =======
40
    using TableObserver = std::function<void(TableEvent const &)>;
41
    /**
42
     * @brief Subscribe to table events
43
     * @return Subscription id (>=1) or -1 on failure
44
     */
45
    [[nodiscard]] int addTableObserver(TableObserver callback);
46
    /**
47
     * @brief Unsubscribe from table events
48
     */
49
    bool removeTableObserver(int callback_id);
50

51
    /**
52
    * @brief Register a new temporal coordinate system with a unique key
53
    *
54
    * This function stores a TimeFrame object in the DataManager under the provided key.
55
    * The TimeFrame specifies the temporal coordinate system that can be assigned to data objects.
56
    *
57
    * @param key The unique identifier for this TimeFrame
58
    * @param timeframe The TimeFrame object to register
59
    * @return bool True if the TimeFrame was successfully registered, false otherwise
60
    *
61
    * @note If the key already exists or timeframe is nullptr, a warning message will be printed
62
    *       to std::cerr and the function will return false
63
    */
64
    bool setTime(TimeKey const & key, std::shared_ptr<TimeFrame> timeframe, bool overwrite = false);
65

66
    /**
67
    * @brief Get the default time frame object
68
    *
69
    * Returns the TimeFrame associated with the default "time" key.
70
    *
71
    * @return A shared pointer to the default TimeFrame object
72
    * @note This function always returns a valid pointer since the default TimeFrame
73
    *       is created in the constructor
74
    */
75
    [[nodiscard]] std::shared_ptr<TimeFrame> getTime();
76

77
    /**
78
    * @brief Get the time frame object for a specific key
79
    *
80
    * @param key The key to retrieve the TimeFrame for
81
    * @return A shared pointer to the TimeFrame if the key exists, nullptr otherwise
82
     */
83
    [[nodiscard]] std::shared_ptr<TimeFrame> getTime(TimeKey const & key);
84

85
    [[nodiscard]] TimeIndexAndFrame getCurrentIndexAndFrame(TimeKey const & key);
86

87
    bool removeTime(TimeKey const & key);
88

89
    /**
90
    * @brief Set the time key for a specific data key
91
    *
92
    * Associates a data object with a specific temporal coordinate system.
93
    *
94
    * @param data_key The data key to set the time key for
95
    * @param time_key The time key to associate with the data
96
    * @return bool True if the time frame was successfully set, false otherwise
97
    *
98
    * @note If data_key or time_key doesn't exist, an error message will be printed
99
    *       to std::cerr and the function will return false
100
    */
101
    bool setTimeKey(std::string const & data_key, TimeKey const & time_key);
102

103
    /**
104
    * @brief Get the time key for a specific data key
105
    *
106
    * Retrieves the TimeFrame key associated with a particular data object.
107
    *
108
    * @param data_key The data key to get the time frame for
109
    * @return The TimeKey, or empty string if an error occurred
110
    *
111
    * @note If data_key doesn't exist or doesn't have an associated TimeFrame,
112
    *       an error message will be printed to std::cerr and an empty string will be returned
113
    */
114
    [[nodiscard]] TimeKey getTimeKey(std::string const & data_key);
115

116
    /**
117
    * @brief Get all registered TimeFrame keys
118
    *
119
    * Retrieves a vector of all keys used for TimeFrame objects in the DataManager.
120
    *
121
    * @return A vector of strings containing all TimeFrame keys
122
    * @note The default "time" key will always be included in the returned vector
123
    */
124
    [[nodiscard]] std::vector<TimeKey> getTimeFrameKeys();
125

126
    /**
127
    * @brief Clear all data and reset DataManager to initial state
128
    *
129
    * This function removes all loaded data objects, TimeFrame objects (except the default "time" frame),
130
    * and clears all mappings between data keys and time frame keys. This is useful for batch processing
131
    * where you want to load different datasets with the same configuration.
132
    * 
133
    * The function will:
134
    * - Remove all data objects from _data
135
    * - Remove all TimeFrame objects except the default "time" frame
136
    * - Clear all data-to-timeframe mappings
137
    * - Remove all TimeFrameV2 objects and mappings
138
    * - Reset media data to default empty state
139
    * - Notify observers of the state change
140
    *
141
    * @note The default "time" TimeFrame and "media" data key are preserved but reset to empty state
142
    */
143
    void reset();
144

145

146
    int64_t getCurrentTime() { return _current_time; };
×
147
    void setCurrentTime(int64_t time) { _current_time = time; }
×
148

149
    using ObserverCallback = std::function<void()>;
150

151
    /**
152
    * @brief Add a callback function to a specific data object
153
    *
154
    * Registers a callback function that will be invoked when the specified data object changes.
155
    *
156
    * @param key The data key to attach the callback to
157
    * @param callback The function to call when the data changes
158
    * @return int A unique identifier for the callback (>= 0) or -1 if registration failed
159
    *
160
    * @note If the data key doesn't exist, the function returns -1
161
    */
162
    [[nodiscard]] int addCallbackToData(std::string const & key, ObserverCallback callback);
163

164
    /**
165
    * @brief Remove a callback from a specific data object
166
    *
167
    * Removes a previously registered callback using its unique identifier.
168
    *
169
    * @param key The data key from which to remove the callback
170
    * @param callback_id The unique identifier of the callback to remove
171
    * @return bool True if the callback was successfully removed, false if the key doesn't exist
172
    *
173
    * @note If the data key doesn't exist, the function returns false.
174
    *       The underlying removeObserver implementation determines what happens if the callback_id is invalid.
175
    */
176
    bool removeCallbackFromData(std::string const & key, int callback_id);
177

178
    /**
179
    * @brief Register a callback function for DataManager state changes
180
    *
181
    * Adds a callback function that will be invoked when the DataManager's state changes,
182
    * such as when data is added or modified.
183
    *
184
    * @param callback The function to call when the DataManager state changes
185
    *
186
    * @note Unlike addCallbackToData, this function doesn't return an ID,
187
    *       so callbacks cannot be selectively removed later
188
    */
189
    void addObserver(ObserverCallback callback);
190

191
    /**
192
    * @brief Get all registered data keys
193
    *
194
    * Retrieves a vector of all data object keys in the DataManager.
195
    *
196
    * @return A vector of strings containing all data keys
197
    *
198
    * @example
199
    * @code
200
    * DataManager dm;
201
    * dm.setData<PointData>("points1");
202
    * dm.setData<LineData>("line1");
203
    *
204
    * // Get all keys
205
    * auto keys = dm.getAllKeys(); // Returns ["media", "points1", "line1"]
206
    * @endcode
207
    */
208
    [[nodiscard]] std::vector<std::string> getAllKeys();
209

210
    /**
211
    * @brief Get all keys associated with a specific data type
212
    *
213
    * Retrieves a vector of all keys that correspond to data objects
214
    * of the specified template type T.
215
    *
216
    * @tparam T The data type to filter by (e.g., PointData, LineData)
217
    * @return A vector of strings containing all keys with data of type T
218
    *
219
    * @example
220
    * @code
221
    * DataManager dm;
222
    * dm.setData<PointData>("points1");
223
    * dm.setData<PointData>("points2");
224
    * dm.setData<LineData>("line1");
225
    *
226
    * // Get only keys for PointData objects
227
    * auto pointKeys = dm.getKeys<PointData>(); // Returns ["points1", "points2"]
228
    * @endcode
229
    */
230
    template<typename T>
231
    [[nodiscard]] std::vector<std::string> getKeys() {
304✔
232
        std::vector<std::string> keys;
304✔
233
        for (auto const & [key, value]: _data) {
2,125✔
234
            if (std::holds_alternative<std::shared_ptr<T>>(value)) {
1,821✔
235
                keys.push_back(key);
510✔
236
            }
237
        }
238
        return keys;
304✔
239
    }
×
240

241
    /**
242
    * @brief Get data as a variant type
243
    *
244
    * Retrieves data associated with the specified key as a variant wrapper,
245
    * allowing access without knowing the concrete type at compile time.
246
    *
247
    * @param key The key associated with the data to retrieve
248
    * @return An optional containing the data variant if the key exists, empty optional otherwise
249
    *
250
    */
251
    std::optional<DataTypeVariant> getDataVariant(std::string const & key);
252

253
    template<typename T>
254
    std::shared_ptr<T> getData(std::string const & key) {
2,532✔
255
        if (_data.find(key) != _data.end()) {
2,532✔
256
            return std::get<std::shared_ptr<T>>(_data[key]);
2,432✔
257
        }
258
        return nullptr;
100✔
259
    }
260

261
    template<typename T>
262
    void setData(std::string const & key, TimeKey const & time_key) {
34✔
263
        _data[key] = std::make_shared<T>();
34✔
264
        setTimeKey(key, time_key);
34✔
265
        _notifyObservers();
34✔
266
    }
34✔
267

268
    void setData(std::string const & key, DataTypeVariant data, TimeKey const & time_key);
269

270
    template<typename T>
271
    void setData(std::string const & key, std::shared_ptr<T> data, TimeKey const & time_key) {
742✔
272
        _data[key] = data;
742✔
273
        setTimeKey(key, time_key);
742✔
274
        _notifyObservers();
742✔
275
    }
742✔
276

277
    /**
278
     * @brief Delete data associated with the specified key
279
     * 
280
     * Removes the data object and its associated time frame mapping from the DataManager.
281
     * All observers are notified of the change, allowing dependent widgets to clean up.
282
     * 
283
     * @param key The key of the data to delete
284
     * @return bool True if the data was successfully deleted, false if the key doesn't exist
285
     * 
286
     * @note This method will:
287
     *       - Remove the data from the internal storage
288
     *       - Remove the time frame mapping for this data
289
     *       - Notify all observers of the change
290
     *       - The shared_ptr will be automatically cleaned up when no other references exist
291
     */
292
    bool deleteData(std::string const & key);
293

294
    [[nodiscard]] DM_DataType getType(std::string const & key) const;
295

296
    void setOutputPath(std::filesystem::path const & output_path) { _output_path = output_path; };
297

298
    [[nodiscard]] std::filesystem::path getOutputPath() const {
299
        return _output_path;
300
    }
301

302
    void notifyTableObservers(TableEvent const & ev);
303

304
    /**
305
     * @brief Access the session-scoped EntityRegistry.
306
     */
307
    [[nodiscard]] EntityRegistry * getEntityRegistry() const { return _entity_registry.get(); }
17✔
308

309
    /**
310
     * @brief Access the session-scoped EntityGroupManager.
311
     */
312
    [[nodiscard]] EntityGroupManager * getEntityGroupManager() const { return _entity_group_manager.get(); }
12✔
313

314
private:
315
    std::unordered_map<TimeKey, std::shared_ptr<TimeFrame>> _times;
316

317
    std::vector<ObserverCallback> _observers;
318

319
    std::unordered_map<std::string, DataTypeVariant>
320
            _data;
321

322
    std::unordered_map<std::string, TimeKey> _time_frames;
323

324
    std::filesystem::path _output_path;
325

326
    void _notifyObservers();
327

328
    int64_t _current_time{0};
329

330
    // ======= Table Registry and observer internals =======
331
    std::unique_ptr<TableRegistry> _table_registry;
332
    std::unordered_map<int, TableObserver> _table_observers;
333
    int _next_table_observer_id{1};
334

335
    // ======= Identity / Entity registry =======
336
    std::unique_ptr<EntityRegistry> _entity_registry;
337
    std::unique_ptr<EntityGroupManager> _entity_group_manager;
338
};
339

340
std::vector<DataInfo> load_data_from_json_config(DataManager *, std::string const & json_filepath);
341
std::vector<DataInfo> load_data_from_json_config(DataManager * dm, nlohmann::json const & j, std::filesystem::path const & base_path);
342

343
std::string convert_data_type_to_string(DM_DataType type);
344

345

346
extern template std::shared_ptr<AnalogTimeSeries> DataManager::getData<AnalogTimeSeries>(std::string const & key);
347
extern template void DataManager::setData<AnalogTimeSeries>(std::string const & key, TimeKey const & time_key);
348
extern template void DataManager::setData<AnalogTimeSeries>(std::string const & key, std::shared_ptr<AnalogTimeSeries> data, TimeKey const & time_key);
349

350
extern template std::shared_ptr<DigitalEventSeries> DataManager::getData<DigitalEventSeries>(std::string const & key);
351
extern template void DataManager::setData<DigitalEventSeries>(std::string const & key, TimeKey const & time_key);
352
extern template void DataManager::setData<DigitalEventSeries>(std::string const & key, std::shared_ptr<DigitalEventSeries> data, TimeKey const & time_key);
353

354
extern template std::shared_ptr<DigitalIntervalSeries> DataManager::getData<DigitalIntervalSeries>(std::string const & key);
355
extern template void DataManager::setData<DigitalIntervalSeries>(std::string const & key, TimeKey const & time_key);
356
extern template void DataManager::setData<DigitalIntervalSeries>(std::string const & key, std::shared_ptr<DigitalIntervalSeries> data, TimeKey const & time_key);
357

358
extern template std::shared_ptr<LineData> DataManager::getData<LineData>(std::string const & key);
359
extern template void DataManager::setData<LineData>(std::string const & key, TimeKey const & time_key);
360
extern template void DataManager::setData<LineData>(std::string const & key, std::shared_ptr<LineData> data, TimeKey const & time_key);
361

362
extern template std::shared_ptr<MaskData> DataManager::getData<MaskData>(std::string const & key);
363
extern template void DataManager::setData<MaskData>(std::string const & key, TimeKey const & time_key);
364
extern template void DataManager::setData<MaskData>(std::string const & key, std::shared_ptr<MaskData> data, TimeKey const & time_key);
365

366
extern template std::shared_ptr<MediaData> DataManager::getData<MediaData>(std::string const & key);
367

368
extern template std::shared_ptr<PointData> DataManager::getData<PointData>(std::string const & key);
369
extern template void DataManager::setData<PointData>(std::string const & key, TimeKey const & time_key);
370
extern template void DataManager::setData<PointData>(std::string const & key, std::shared_ptr<PointData> data, TimeKey const & time_key);
371

372
extern template std::shared_ptr<TensorData> DataManager::getData<TensorData>(std::string const & key);
373
extern template void DataManager::setData<TensorData>(std::string const & key, TimeKey const & time_key);
374
extern template void DataManager::setData<TensorData>(std::string const & key, std::shared_ptr<TensorData> data, TimeKey const & time_key);
375

376

377
#endif// DATAMANAGER_HPP
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc