Zrythm v2.0.0-DEV
a highly automated and intuitive digital audio workstation
Loading...
Searching...
No Matches
iobject_registry.h
1// SPDX-FileCopyrightText: © 2026 Alexandros Theodotou <alex@zrythm.org>
2// SPDX-License-Identifier: LicenseRef-ZrythmLicense
3#pragma once
4
5#include <functional>
6
7#include "utils/rt_thread_id.h"
8#include "utils/uuid_identifiable.h"
9
10#include <QMetaObject>
11#include <QUuid>
12
13inline std::size_t
14hash_value (const QUuid &id)
15{
16 return qHash (id);
17}
18
19namespace zrythm::utils
20{
21
34class IObjectRegistry
35{
36public:
37 virtual ~IObjectRegistry () = default;
38
39 void register_object (UuidIdentifiableBase &obj)
40 {
41 assert_main_thread ();
42 register_object_impl (obj);
43 }
44
45 void acquire_reference (const QUuid &id)
46 {
47 assert_main_thread ();
48 acquire_reference_impl (id);
49 }
50
51 void release_reference (const QUuid &id)
52 {
53 assert_main_thread ();
54 release_reference_impl (id);
55 }
56
57 [[gnu::hot]] UuidIdentifiableBase * find_by_raw_uuid (const QUuid &id) const
58 {
59 // Lookups are read-only and safe from the Qt render sync thread (which
60 // runs while the main thread is blocked), so no thread assertion here.
61 // Mutating operations (register, acquire, release) still assert main thread.
62 return find_by_raw_uuid_impl (id);
63 }
64
65 bool contains (const QUuid &id) const
66 {
67 assert_main_thread ();
68 return contains_impl (id);
69 }
70
71 // ============================================================================
72 // Type-filtered iteration (NVI pattern)
73 //
74 // Public templated API delegates to private virtual _impl methods.
75 // ProjectRegistry optimizes via internal type buckets.
76 // ObjectRegistry falls back to iterating all objects with a type check.
77 // ============================================================================
78
79 template <typename T>
80 void for_each_matching (std::function<void (T &)> visitor) const
81 {
82 for_each_matching_impl (T::staticMetaObject, [&] (UuidIdentifiableBase &obj) {
83 auto * casted = qobject_cast<T *> (&obj);
84 assert (casted != nullptr);
85 visitor (*casted);
86 });
87 }
88
89 template <typename T> [[nodiscard]] size_t count_matching () const
90 {
91 size_t count = 0;
92 for_each_matching_impl (T::staticMetaObject, [&] (UuidIdentifiableBase &obj) {
93 assert (qobject_cast<T *> (&obj) != nullptr);
94 ++count;
95 });
96 return count;
97 }
98
99protected:
100 IObjectRegistry () : creation_thread_id_ (current_thread_id) { }
101
102private:
103 void assert_main_thread () const
104 {
105 assert (creation_thread_id_ == current_thread_id);
106 }
107
108protected:
109 virtual void register_object_impl (UuidIdentifiableBase &obj) = 0;
110 virtual void acquire_reference_impl (const QUuid &id) = 0;
111 virtual void release_reference_impl (const QUuid &id) = 0;
112 [[gnu::hot]] virtual UuidIdentifiableBase *
113 find_by_raw_uuid_impl (const QUuid &id) const = 0;
114 virtual bool contains_impl (const QUuid &id) const = 0;
115
116 using ObjectVisitor = std::function<void (UuidIdentifiableBase &)>;
117 virtual void
118 for_each_matching_impl (const QMetaObject &meta_type, ObjectVisitor visitor)
119 const = 0;
120
121private:
122 RTThreadId creation_thread_id_;
123};
124
125} // namespace zrythm::utils
Real-time safe thread identifier.
QObject-based base for all UUID-identifiable objects.
String utilities.