Ocean
Loading...
Searching...
No Matches
MessageHandler.h
Go to the documentation of this file.
1/*
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 */
7
8#ifndef META_OCEAN_PLATFORM_META_QUEST_PLATFORMSDK_MESSAGE_HANDLER_H
9#define META_OCEAN_PLATFORM_META_QUEST_PLATFORMSDK_MESSAGE_HANDLER_H
10
12
14
15#include <OVR_Platform.h>
16
17#include <future>
18
19namespace Ocean
20{
21
22namespace Platform
23{
24
25namespace Meta
26{
27
28namespace Quest
29{
30
31namespace PlatformSDK
32{
33
34/**
35 * This class is the base class for all objects needing to handle with messages.
36 * The class is mainly forwarding all calls of invokeRequest() to Manager::get().invokeRequest().
37 * @ingroup platformmetaquestplatformsdk
38 */
39class OCEAN_PLATFORM_META_QUEST_PLATFORMSDK_EXPORT MessageHandler
40{
41 friend class Manager;
42
43 public:
44
45 /**
46 * This class implements a scoped handle for options.
47 * The class is a helper class to ensure that options are always destroyed after usage.
48 * @tparam T The data type of the option
49 */
50 template <typename T>
52 {
53 public:
54
55 /**
56 * Definition of a function pointer to a function destroying the object.
57 */
58 using DestroyFunction = void(*)(T object);
59
60 public:
61
62 /**
63 * Creates a new scoped options object.
64 * @param options The actual options which will be destroyed once this object is disposed, must be valid
65 * @param destoryFunction The destroy function for the given options, must be valid
66 */
67 inline ScopedOptions(const T& options, const DestroyFunction& destoryFunction);
68
69 /**
70 * Destructs the object and destroys the options.
71 */
72 inline ~ScopedOptions();
73
74 /**
75 * Returns the actual options.
76 * @return The options of this object
77 */
78 inline operator T() const;
79
80 protected:
81
82 /**
83 * Disabled copy constructor.
84 */
85 ScopedOptions(const ScopedOptions&) = delete;
86
87 /**
88 * Disabled move constructor.
89 */
91
92 /**
93 * Disabled assign operator.
94 */
96
97 /**
98 * Disabled move operator.
99 */
101
102 protected:
103
104 /// The actual options.
105 T options_ = nullptr;
106
107 /// The destroy function.
108 DestroyFunction destroyFunction_ = nullptr;
109 };
110
111 /**
112 * This class implements a helper object allowing to store responses for requests.
113 * @tparam T the data type of the response
114 */
115 template <typename T>
117 {
118 public:
119
120 /**
121 * Default constructor creating a new object without response.
122 */
123 RequestObject() = default;
124
125 /**
126 * Sets the latest response.
127 * @param response The response to set
128 */
129 void setResponse(T&& response);
130
131 /**
132 * Sets the latest response.
133 * @param response The response to set
134 */
135 void setResponse(const T& response);
136
137 /**
138 * Returns whether this object holds a latest response.
139 * In case a latest response was available, the object is reset so that no latest response is available anymore.
140 * @param response The resulting latest response, if any
141 * @return True, if a latest response was available
142 */
143 bool latestResponse(T& response);
144
145 protected:
146
147 /// The latest response.
149
150 /// True, if this object holds a latest response.
151 bool hasLatestResponse_ = false;
152
153 /// The object's lock.
154 mutable Lock lock_;
155 };
156
157 /**
158 * This class implements a helper object allowing to queue responses of requests.
159 */
160 template <typename T>
161 class RequestQueue : public RequestObject<T>
162 {
163 public:
164
165 /**
166 * Default constructor.
167 */
168 RequestQueue() = default;
169
170 /**
171 * Adds a new request and returns the corresponding future.
172 * @return The future of the new request
173 */
174 std::future<T> addRequest();
175
176 /**
177 * Sets the latest response.
178 * The response will be forwarded to the oldest queued future as well.
179 * @param response The response to set
180 */
181 void setResponse(T&& response);
182
183 /**
184 * Sets the latest response.
185 * The response will be forwarded to the oldest queued future as well.
186 * @param response The response to set
187 */
188 void setResponse(const T& response);
189
190 protected:
191
192 /// The queue holding all active promises for the futures of all requests.
193 std::queue<std::promise<T>> promises_;
194 };
195
196 /**
197 * Definition of a callback function for message responses.
198 * @param message The response message, must be valid
199 * @param succeeded True, if the message succeeded; False, if an error happened
200 */
201 using ResponseCallback = std::function<void(ovrMessage* message, bool succeeded)>;
202
203 /**
204 * Definition of a member callback function for message responses.
205 * @param message The response message, must be valid
206 * @param succeeded True, if the message succeeded; False, if an error happened
207 * @tparam T The data type of the class of the callback function
208 */
209 template <typename T>
210 using ResponseCallbackFunctionT = void (T::*)(ovrMessage* message, const bool succeeded);
211
212 /**
213 * Definition of a scoped subscription object for messages.
214 */
216
217 /**
218 * Definition of a vector holding MessageScopedSubscription objects.
219 */
220 using MessageScopedSubscriptions = std::vector<MessageScopedSubscription>;
221
222 public:
223
224 /**
225 * Invokes a new request.
226 * @param requestId The id of the new request
227 * @param responseCallback The callback member function which will be called once the response has arrived
228 * @return True, if succeeded
229 * @tparam T The data type of the class of the callback function
230 */
231 template <typename T>
232 bool invokeRequest(const ovrRequest requestId, const ResponseCallbackFunctionT<T>& responseCallback);
233
234 /**
235 * Subscribes a callback function for response messages with specific type.
236 * @param messageType The type of the message for wich the callback function will be subscibed, ovrMessage_Unknown to subscribe to all messages
237 * @param responseCallback The callback member function which will be called whenever a response message with the specified type arrives
238 * @return The subscription object, the subscription is active as long as the subscription object exists
239 * @see unsubscribeForMessageResponse().
240 */
241 template <typename T>
242 [[nodiscard]] MessageScopedSubscription subscribeForMessageResponse(const ovrMessageType& messageType, const ResponseCallbackFunctionT<T>& responseCallback);
243
244 /**
245 * Invokes a new request.
246 * @param requestId The id of the new request
247 * @param responseCallback The callback function which will be called once the response has arrived
248 * @return True, if succeeded
249 */
250 static bool invokeRequest(const ovrRequest requestId, ResponseCallback responseCallback);
251
252 /**
253 * Subscribes a callback function for response messages with specific type.
254 * @param messageType The type of the message for wich the callback function will be subscibed, ovrMessage_Unknown to subscribe to all messages
255 * @param responseCallback The callback function which will be called whenever a response message with the specified type arrives
256 * @return The subscription object, the subscription is active as long as the subscription object exists
257 * @see unsubscribeForMessageResponse().
258 */
259 [[nodiscard]] static MessageScopedSubscription subscribeForMessageResponse(const ovrMessageType& messageType, ResponseCallback responseCallback);
260
261 /**
262 * Converts a string with exactly four characters to a unique tag value.
263 * @param tagString The string with four characters to be converted
264 * @return The resulting tag value
265 */
266 static constexpr uint32_t string2tag(const char tagString[4]);
267
268 protected:
269
270 /**
271 * Creates a new subscription object for a given subscription id.
272 * @param subscriptionId The subscription id, must be valid
273 * @return The resulting subscription object
274 */
275 [[nodiscard]] static MessageScopedSubscription createMessageScopedSubscription(const unsigned int subscriptionId);
276
277 /**
278 * Removes a subscription for response messages with specific message type.
279 * @param subscriptionId The subscription id to unsubscribe, must be valid
280 * @see subscribeForMessageResponse().
281 */
282 static void unsubscribeForMessageResponse(const unsigned int& subscriptionId);
283};
284
285template <typename T>
286bool MessageHandler::invokeRequest(const ovrRequest requestId, const ResponseCallbackFunctionT<T>& responseCallback)
287{
288 return invokeRequest(requestId, std::bind(responseCallback, (T*)(this), std::placeholders::_1, std::placeholders::_2));
289}
290
291template <typename T>
293{
294 return subscribeForMessageResponse(messageType, std::bind(responseCallback, (T*)(this), std::placeholders::_1, std::placeholders::_2));
295}
296
297template <typename T>
298inline MessageHandler::ScopedOptions<T>::ScopedOptions(const T& options, const DestroyFunction& destroyFunction) :
299 options_(options),
300 destroyFunction_(destroyFunction)
301{
302 ocean_assert(options_ != nullptr);
303 ocean_assert(destroyFunction_ != nullptr);
304}
305
306template <typename T>
308{
309 ocean_assert(options_ != nullptr);
310 ocean_assert(destroyFunction_ != nullptr);
311
312 destroyFunction_(options_);
313}
314
315template <typename T>
317{
318 return options_;
319}
320
321template <typename T>
323{
324 const ScopedLock scopedLock(lock_);
325
326 latestResponse_ = std::move(response);
327 hasLatestResponse_ = true;
328}
329
330template <typename T>
332{
333 const ScopedLock scopedLock(lock_);
334
335 latestResponse_ = response;
336 hasLatestResponse_ = true;
337}
338
339template <typename T>
341{
342 const ScopedLock scopedLock(lock_);
343
344 if (hasLatestResponse_)
345 {
346 value = std::move(latestResponse_);
347 hasLatestResponse_ = false;
348
349 return true;
350 }
351
352 return false;
353}
354
355template <typename T>
357{
358 const ScopedLock scopedLock(this->lock_);
359
360 std::promise<T> promise;
361 std::future future = promise.get_future();
362
363 promises_.push(std::move(promise));
364
365 return future;
366}
367
368template <typename T>
370{
371 const ScopedLock scopedLock(this->lock_);
372
373 ocean_assert(!promises_.empty());
374
375 std::promise<T>& promise = promises_.front();
376 promise.set_value(response);
377
378 RequestObject<T>::setResponse(std::move(response));
379
380 promises_.pop();
381}
382
383template <typename T>
385{
386 const ScopedLock scopedLock(this->lock_);
387
388 ocean_assert(!promises_.empty());
389
390 std::promise<T>& promise = promises_.front();
391 promise.set_value(response);
392
394
395 promises_.pop();
396}
397
398constexpr uint32_t MessageHandler::string2tag(const char tagString[4])
399{
400 ocean_assert(tagString[0] != 0 && tagString[1] != 0 && tagString[2] != 0 && tagString[3] != 0);
401
402 return (uint32_t(tagString[0]) << 0ull)
403 | (uint32_t(tagString[1]) << 8ull)
404 | (uint32_t(tagString[2]) << 16ull)
405 | (uint32_t(tagString[3]) << 24ull);
406}
407
408}
409
410}
411
412}
413
414}
415
416}
417
418#endif // META_OCEAN_PLATFORM_META_QUEST_PLATFORMSDK_MESSAGE_HANDLER_H
This class implements a recursive lock object.
Definition Lock.h:31
This class implements a manager that handles the central PlatformSDK functionalities.
Definition platform/meta/quest/platformsdk/Manager.h:41
This class implements a helper object allowing to store responses for requests.
Definition MessageHandler.h:117
Lock lock_
The object's lock.
Definition MessageHandler.h:154
bool latestResponse(T &response)
Returns whether this object holds a latest response.
Definition MessageHandler.h:340
void setResponse(T &&response)
Sets the latest response.
Definition MessageHandler.h:322
T latestResponse_
The latest response.
Definition MessageHandler.h:148
RequestObject()=default
Default constructor creating a new object without response.
This class implements a helper object allowing to queue responses of requests.
Definition MessageHandler.h:162
void setResponse(T &&response)
Sets the latest response.
Definition MessageHandler.h:369
std::queue< std::promise< T > > promises_
The queue holding all active promises for the futures of all requests.
Definition MessageHandler.h:193
std::future< T > addRequest()
Adds a new request and returns the corresponding future.
Definition MessageHandler.h:356
This class implements a scoped handle for options.
Definition MessageHandler.h:52
ScopedOptions(const T &options, const DestroyFunction &destoryFunction)
Creates a new scoped options object.
Definition MessageHandler.h:298
T options_
The actual options.
Definition MessageHandler.h:105
ScopedOptions & operator=(const ScopedOptions &)=delete
Disabled assign operator.
void(*)(T object) DestroyFunction
Definition of a function pointer to a function destroying the object.
Definition MessageHandler.h:58
ScopedOptions(const ScopedOptions &)=delete
Disabled copy constructor.
DestroyFunction destroyFunction_
The destroy function.
Definition MessageHandler.h:108
ScopedOptions & operator=(ScopedOptions &&)=delete
Disabled move operator.
ScopedOptions(ScopedOptions &&)=delete
Disabled move constructor.
This class is the base class for all objects needing to handle with messages.
Definition MessageHandler.h:40
static MessageScopedSubscription subscribeForMessageResponse(const ovrMessageType &messageType, ResponseCallback responseCallback)
Subscribes a callback function for response messages with specific type.
std::function< void(ovrMessage *message, bool succeeded)> ResponseCallback
Definition of a callback function for message responses.
Definition MessageHandler.h:201
static MessageScopedSubscription createMessageScopedSubscription(const unsigned int subscriptionId)
Creates a new subscription object for a given subscription id.
static bool invokeRequest(const ovrRequest requestId, ResponseCallback responseCallback)
Invokes a new request.
std::vector< MessageScopedSubscription > MessageScopedSubscriptions
Definition of a vector holding MessageScopedSubscription objects.
Definition MessageHandler.h:220
static constexpr uint32_t string2tag(const char tagString[4])
Converts a string with exactly four characters to a unique tag value.
Definition MessageHandler.h:398
static void unsubscribeForMessageResponse(const unsigned int &subscriptionId)
Removes a subscription for response messages with specific message type.
MessageScopedSubscription subscribeForMessageResponse(const ovrMessageType &messageType, const ResponseCallbackFunctionT< T > &responseCallback)
Subscribes a callback function for response messages with specific type.
Definition MessageHandler.h:292
bool invokeRequest(const ovrRequest requestId, const ResponseCallbackFunctionT< T > &responseCallback)
Invokes a new request.
Definition MessageHandler.h:286
void(T::*)(ovrMessage *message, const bool succeeded) ResponseCallbackFunctionT
Definition of a member callback function for message responses.
Definition MessageHandler.h:210
This class implements a scoped lock object for recursive lock objects.
Definition Lock.h:135
This class implements a subscription object which can be used unique subscriptions to e....
Definition ScopedSubscription.h:28
The namespace covering the entire Ocean framework.
Definition Accessor.h:15