20
20
21
21
// Code taken from: https://github.com/hogliux/farbot
22
22
23
- #pragma once
23
+ #ifndef PENDULUM_UTILS__REALTIMEOBJECT_HPP_
24
+ #define PENDULUM_UTILS__REALTIMEOBJECT_HPP_
24
25
25
26
#include < atomic>
26
27
#include < memory>
27
28
#include < mutex>
29
+ #include < utility>
28
30
29
31
#include " pendulum_utils/detail/RealtimeObject.tcc"
30
32
@@ -44,30 +46,37 @@ enum class ThreadType
44
46
};
45
47
46
48
// ==============================================================================
47
- /* * Useful class to synchronise access to an object from multiple threads with the additional feature that one
48
- * designated thread will never wait to get access to the object. */
49
- template <typename T, RealtimeObjectOptions Options>
49
+ /* * Useful class to synchronise access to an object from multiple threads with the additional
50
+ * feature that one designated thread will never wait to get access to the object. */
51
+ template <typename T, RealtimeObjectOptions Options>
50
52
class RealtimeObject
51
53
{
52
54
public:
53
55
/* * Creates a default constructed T */
54
56
RealtimeObject () = default ;
55
57
56
58
/* * Creates a copy of T */
57
- explicit RealtimeObject (const T & obj) : mImpl(obj) {}
59
+ explicit RealtimeObject (const T & obj)
60
+ : mImpl(obj) {}
58
61
59
62
/* * Moves T into this realtime wrapper */
60
- explicit RealtimeObject (T && obj) : mImpl(std::move(obj)) {}
63
+ explicit RealtimeObject (T && obj)
64
+ : mImpl(std::move(obj)) {}
61
65
62
66
~RealtimeObject () = default ;
63
67
64
68
/* * Create T by calling T's constructor which takes args */
65
- template <typename ... Args>
66
- static RealtimeObject create (Args && ... args) { return Impl::create (std::forward<Args>(args)...); }
69
+ template <typename ... Args>
70
+ static RealtimeObject create (Args && ... args)
71
+ {
72
+ return Impl::create (std::forward<Args>(args)...);
73
+ }
67
74
68
75
// ==============================================================================
69
- using RealtimeAcquireReturnType = std::conditional_t <Options == RealtimeObjectOptions::nonRealtimeMutatable, const T, T>;
70
- using NonRealtimeAcquireReturnType = std::conditional_t <Options == RealtimeObjectOptions::realtimeMutatable, const T, T>;
76
+ using RealtimeAcquireReturnType =
77
+ std::conditional_t <Options == RealtimeObjectOptions::nonRealtimeMutatable, const T, T>;
78
+ using NonRealtimeAcquireReturnType =
79
+ std::conditional_t <Options == RealtimeObjectOptions::realtimeMutatable, const T, T>;
71
80
72
81
// ==============================================================================
73
82
/* * Returns a reference to T. Use this method on the real-time thread.
@@ -78,20 +87,23 @@ class RealtimeObject
78
87
*
79
88
* This method is wait- and lock-free.
80
89
*/
81
- RealtimeAcquireReturnType& realtimeAcquire () noexcept { return mImpl .realtimeAcquire (); }
90
+ RealtimeAcquireReturnType & realtimeAcquire () noexcept {return mImpl .realtimeAcquire ();}
82
91
83
92
/* * Releases the lock on T previously acquired by realtimeAcquire.
84
93
*
85
94
* This method is wait- and lock-free.
86
95
*/
87
- void realtimeRelease () noexcept { mImpl .realtimeRelease (); }
96
+ void realtimeRelease () noexcept {mImpl .realtimeRelease ();}
88
97
89
98
/* * Replace the underlying value with a new instance of T by forwarding
90
99
* the method's arguments to T's constructor
91
100
*/
92
- template <RealtimeObjectOptions O = Options, typename ... Args>
101
+ template <RealtimeObjectOptions O = Options, typename ... Args>
93
102
std::enable_if_t <O == RealtimeObjectOptions::realtimeMutatable, std::void_t <Args...>>
94
- realtimeReplace (Args && ... args) noexcept { mImpl .realtimeReplace (std::forward<Args>(args)...); }
103
+ realtimeReplace (Args && ... args) noexcept
104
+ {
105
+ mImpl .realtimeReplace (std::forward<Args>(args)...);
106
+ }
95
107
96
108
// ==============================================================================
97
109
/* * Returns a reference to T. Use this method on the non real-time thread.
@@ -102,60 +114,64 @@ class RealtimeObject
102
114
*
103
115
* This method uses a lock should not be used on a realtime thread.
104
116
*/
105
- NonRealtimeAcquireReturnType& nonRealtimeAcquire () { return mImpl .nonRealtimeAcquire (); }
117
+ NonRealtimeAcquireReturnType & nonRealtimeAcquire () { return mImpl .nonRealtimeAcquire ();}
106
118
107
119
/* * Releases the lock on T previously acquired by nonRealtimeAcquire.
108
120
*
109
121
* This method uses both a lock and a spin loop and should not be used
110
122
* on a realtime thread.
111
123
*/
112
- void nonRealtimeRelease () { mImpl .nonRealtimeRelease (); }
124
+ void nonRealtimeRelease () { mImpl .nonRealtimeRelease ();}
113
125
114
126
/* * Replace the underlying value with a new instance of T by forwarding
115
127
* the method's arguments to T's constructor
116
128
*/
117
- template <RealtimeObjectOptions O = Options, typename ... Args>
129
+ template <RealtimeObjectOptions O = Options, typename ... Args>
118
130
std::enable_if_t <O == RealtimeObjectOptions::nonRealtimeMutatable, std::void_t <Args...>>
119
- nonRealtimeReplace (Args && ... args) { mImpl .nonRealtimeReplace (std::forward<Args>(args)...); }
131
+ nonRealtimeReplace (Args && ... args) { mImpl .nonRealtimeReplace (std::forward<Args>(args)...);}
120
132
121
133
// ==============================================================================
122
134
/* * Instead of calling acquire and release manually, you can also use this RAII
123
135
* version which calls acquire automatically on construction and release when
124
136
* destructed.
125
137
*/
126
- template <ThreadType threadType>
127
- class ScopedAccess : public std ::conditional_t <Options == RealtimeObjectOptions::realtimeMutatable,
138
+ template <ThreadType threadType>
139
+ class ScopedAccess
140
+ : public std::conditional_t <Options == RealtimeObjectOptions::realtimeMutatable,
128
141
detail::RealtimeMutatable<T>,
129
- detail::NonRealtimeMutatable<T>>::template ScopedAccess<threadType == ThreadType::realtime>
142
+ detail::NonRealtimeMutatable<T>>::template ScopedAccess<threadType == ThreadType::realtime>
130
143
{
131
- public:
132
- explicit ScopedAccess (RealtimeObject& parent)
133
- : Impl::template ScopedAccess<threadType == ThreadType::realtime> (parent.mImpl ) {}
144
+ public:
145
+ explicit ScopedAccess (RealtimeObject & parent)
146
+ : Impl::template ScopedAccess<threadType == ThreadType::realtime>(parent.mImpl ) {}
134
147
135
148
#if DOXYGEN
136
149
// Various ways to get access to the underlying object.
137
- // Non-const method are only supported on the realtime
138
- // or non-realtime thread as indicated by the Options
139
- // template argument
140
- T * get () noexcept ;
141
- const T* get () const noexcept ;
142
- T &operator *() noexcept ;
143
- const T &operator *() const noexcept ;
144
- T * operator ->() noexcept ;
145
- const T* operator ->() const noexcept ;
150
+ // Non-const method are only supported on the realtime
151
+ // or non-realtime thread as indicated by the Options
152
+ // template argument
153
+ T * get () noexcept ;
154
+ const T * get () const noexcept ;
155
+ T & operator *() noexcept ;
156
+ const T & operator *() const noexcept ;
157
+ T * operator ->() noexcept ;
158
+ const T * operator ->() const noexcept ;
146
159
#endif
147
160
148
161
// ==============================================================================
149
- ScopedAccess (const ScopedAccess&) = delete ;
162
+ ScopedAccess (const ScopedAccess &) = delete ;
150
163
ScopedAccess (ScopedAccess &&) = delete ;
151
- ScopedAccess& operator =(const ScopedAccess&) = delete ;
152
- ScopedAccess& operator =(ScopedAccess&&) = delete ;
164
+ ScopedAccess & operator =(const ScopedAccess &) = delete ;
165
+ ScopedAccess & operator =(ScopedAccess &&) = delete ;
153
166
};
167
+
154
168
private:
155
169
using Impl = std::conditional_t <Options == RealtimeObjectOptions::realtimeMutatable,
156
170
detail::RealtimeMutatable<T>,
157
- detail::NonRealtimeMutatable<T>>;
171
+ detail::NonRealtimeMutatable<T>>;
158
172
Impl mImpl ;
159
173
};
160
174
161
- }
175
+ } // namespace farbot
176
+
177
+ #endif // PENDULUM_UTILS__REALTIMEOBJECT_HPP_
0 commit comments