OSVR-Core
DeviceInterface.h
Go to the documentation of this file.
1 
12 // Copyright 2014 Sensics, Inc.
13 //
14 // Licensed under the Apache License, Version 2.0 (the "License");
15 // you may not use this file except in compliance with the License.
16 // You may obtain a copy of the License at
17 //
18 // http://www.apache.org/licenses/LICENSE-2.0
19 //
20 // Unless required by applicable law or agreed to in writing, software
21 // distributed under the License is distributed on an "AS IS" BASIS,
22 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
23 // See the License for the specific language governing permissions and
24 // limitations under the License.
25 
26 #ifndef INCLUDED_DeviceInterface_h_GUID_A929799C_02F5_4C92_C503_36C7F59D6BA1
27 #define INCLUDED_DeviceInterface_h_GUID_A929799C_02F5_4C92_C503_36C7F59D6BA1
28 
29 // Internal Includes
31 #include <osvr/Util/TimeValue.h>
32 
33 // Library/third-party includes
34 // - none
35 
36 // Standard includes
37 #include <stdexcept>
38 #include <vector>
39 #include <string>
40 
41 namespace osvr {
42 namespace pluginkit {
43 
51  inline OSVR_MessageType
60  OSVR_IN_STRZ const char *name) {
61  OSVR_MessageType msg;
62  OSVR_ReturnCode ret = osvrDeviceRegisterMessageType(ctx, name, &msg);
63  if (OSVR_RETURN_SUCCESS != ret) {
64  throw std::runtime_error("Could not register message type: " +
65  std::string(name));
66  }
67  return msg;
68  }
69 
71  inline OSVR_MessageType
73  OSVR_IN std::string const &name) {
74  if (name.empty()) {
75  throw std::runtime_error(
76  "Cannot register a message type with an empty name!");
77  }
78  return registerMessageType(ctx, name.c_str());
79  }
80 
81 #ifndef OSVR_DOXYGEN_EXTERNAL
82  namespace detail {
83  template <typename DeviceObjectType> struct UpdateTrampoline {
84  static OSVR_ReturnCode update(void *userData) {
86  return static_cast<DeviceObjectType *>(userData)->update();
87  }
88  };
89  } // namespace detail
90 #endif
91 
93  class DeviceToken {
94  public:
96  DeviceToken(OSVR_DeviceToken device) : m_dev(device) {}
97 
99  DeviceToken() : m_dev(NULL) {}
100 
102  operator OSVR_DeviceToken() const {
103  m_validateToken();
104  return m_dev;
105  }
106 
110  OSVR_IN_STRZ const char *name,
111  OSVR_IN_OPT OSVR_DeviceInitOptions options = NULL) {
112  OSVR_ReturnCode ret;
113  if (options) {
114  ret = osvrDeviceSyncInitWithOptions(ctx, name, options, &m_dev);
115  } else {
116  ret = osvrDeviceSyncInit(ctx, name, &m_dev);
117  }
118  if (OSVR_RETURN_SUCCESS != ret) {
119  throw std::runtime_error("Could not initialize device token: " +
120  std::string(name));
121  }
122  }
123 
126  OSVR_IN std::string const &name,
127  OSVR_IN_OPT OSVR_DeviceInitOptions options = NULL) {
128  if (name.empty()) {
129  throw std::runtime_error("Could not initialize device token "
130  "with an empty name field!");
131  }
132  initSync(ctx, name.c_str(), options);
133  }
134 
138  OSVR_IN_STRZ const char *name,
139  OSVR_IN_OPT OSVR_DeviceInitOptions options = NULL) {
140  OSVR_ReturnCode ret;
141  if (options) {
142  ret =
143  osvrDeviceAsyncInitWithOptions(ctx, name, options, &m_dev);
144  } else {
145  ret = osvrDeviceAsyncInit(ctx, name, &m_dev);
146  }
147  if (OSVR_RETURN_SUCCESS != ret) {
148  throw std::runtime_error("Could not initialize device token: " +
149  std::string(name));
150  }
151  }
152 
155  OSVR_IN std::string const &name,
156  OSVR_IN_OPT OSVR_DeviceInitOptions options = NULL) {
157  if (name.empty()) {
158  throw std::runtime_error("Could not initialize device token "
159  "with an empty name field!");
160  }
161  initAsync(ctx, name.c_str(), options);
162  }
163 
171  template <typename InterfaceType, typename MessageType>
172  void send(InterfaceType &iface, MessageType const &msg,
173  OSVR_TimeValue const &timestamp) {
174  iface.send(*this, msg, timestamp);
175  }
176 
179  template <typename InterfaceType, typename MessageType>
180  void send(InterfaceType &iface, MessageType const &msg) {
181  send(iface, msg, util::time::getNow());
182  }
183 
190  void sendJsonDescriptor(OSVR_IN_READS(len) const char *json,
191  OSVR_IN size_t len) {
192  m_validateToken();
193  OSVR_ReturnCode ret =
194  osvrDeviceSendJsonDescriptor(m_dev, json, len);
195  if (OSVR_RETURN_SUCCESS != ret) {
196  throw std::runtime_error("Could not send JSON descriptor!");
197  }
198  }
199 
204  template <size_t N> void sendJsonDescriptor(const char(&json)[N]) {
205  sendJsonDescriptor(json, N);
206  }
207 
209  void sendJsonDescriptor(OSVR_IN std::string const &json) {
210  if (json.empty()) {
211  throw std::runtime_error(
212  "Cannot send an empty JSON descriptor!");
213  }
214  sendJsonDescriptor(json.c_str(), json.length());
215  }
216 
222  template <typename DeviceObjectType>
223  void registerUpdateCallback(OSVR_IN_PTR DeviceObjectType *object) {
224  if (!object) {
225  throw std::logic_error(
226  "Cannot register update callback for a null object!");
227  }
228  m_validateToken();
229  OSVR_ReturnCode ret = osvrDeviceRegisterUpdateCallback(
231  static_cast<void *>(object));
232  if (OSVR_RETURN_SUCCESS != ret) {
233  throw std::runtime_error("Could not register update callback!");
234  }
235  }
236 
251  void sendData(OSVR_IN_PTR OSVR_MessageType msg,
252  OSVR_IN_READS(len) const char *bytestream = NULL,
253  OSVR_IN size_t len = 0) {
254  m_validateToken();
255  OSVR_ReturnCode ret =
256  osvrDeviceSendData(m_dev, msg, bytestream, len);
257  if (OSVR_RETURN_SUCCESS != ret) {
258  throw std::runtime_error("Could not send data!");
259  }
260  }
261 
266  template <size_t N>
267  void sendData(OSVR_MessageType msg, const char(&bytestream)[N]) {
268  sendData(msg, bytestream, N);
269  }
270 
273  OSVR_IN std::string const &bytestream) {
274  if (bytestream.empty()) {
275  sendData(msg);
276  } else {
277  sendData(msg, bytestream.data(), bytestream.length());
278  }
279  }
280 
283  OSVR_IN std::vector<char> const &bytestream) {
284  if (bytestream.empty()) {
285  sendData(msg);
286  } else {
287  sendData(msg, bytestream.data(), bytestream.size());
288  }
289  }
290 
305  void sendData(OSVR_IN OSVR_TimeValue const &timestamp,
307  OSVR_IN_READS(len) const char *bytestream = NULL,
308  OSVR_IN size_t len = 0) {
309  OSVR_ReturnCode ret = osvrDeviceSendTimestampedData(
310  m_dev, &timestamp, msg, bytestream, len);
311  if (OSVR_RETURN_SUCCESS != ret) {
312  throw std::runtime_error("Could not send data!");
313  }
314  }
315 
320  template <size_t N>
321  void sendData(OSVR_IN OSVR_TimeValue const &timestamp,
322  OSVR_MessageType msg, const char(&bytestream)[N]) {
323  sendData(timestamp, msg, bytestream, N);
324  }
325 
327  void sendData(OSVR_IN OSVR_TimeValue const &timestamp,
329  OSVR_IN std::string const &bytestream) {
330  if (bytestream.empty()) {
331  sendData(timestamp, msg);
332  } else {
333  sendData(timestamp, msg, bytestream.data(),
334  bytestream.length());
335  }
336  }
337 
339  void sendData(OSVR_IN OSVR_TimeValue const &timestamp,
341  OSVR_IN std::vector<char> const &bytestream) {
342  if (bytestream.empty()) {
343  sendData(timestamp, msg);
344  } else {
345  sendData(timestamp, msg, bytestream.data(), bytestream.size());
346  }
347  }
349 
350  private:
353  void m_validateToken() const {
354  if (!m_dev) {
355  throw std::logic_error("Attempting an operation on a device "
356  "token that is not yet initialized!");
357  }
358  }
359  OSVR_DeviceToken m_dev;
360  };
361 
363 } // namespace pluginkit
364 } // namespace osvr
365 
366 #endif // INCLUDED_DeviceInterface_h_GUID_A929799C_02F5_4C92_C503_36C7F59D6BA1
OSVR_PLUGINKIT_EXPORT OSVR_ReturnCode osvrDeviceRegisterMessageType(OSVR_IN_PTR OSVR_PluginRegContext ctx, OSVR_IN_STRZ const char *name, OSVR_OUT_PTR OSVR_MessageType *msgtype) OSVR_FUNC_NONNULL((1
Register (or recall) a message type by name.
#define OSVR_IN_STRZ
Indicates a null-terminated string function parameter that serves only as input.
Definition: AnnotationMacrosC.h:124
DeviceToken(OSVR_DeviceToken device)
Constructor wrapping an existing device token.
Definition: DeviceInterface.h:96
Wrapper class for OSVR_DeviceToken.
Definition: DeviceInterface.h:93
#define OSVR_IN_PTR
Indicates a required pointer (non-null) function parameter that serves only as input.
Definition: AnnotationMacrosC.h:108
#define OSVR_IN_OPT
Indicates a function parameter (pointer) that serves only as input, but is optional and might be NULL...
Definition: AnnotationMacrosC.h:116
A DeviceToken connects the generic device interaction code in PluginKit&#39;s C API with the workings of ...
Definition: DeviceToken.h:56
Definition: DeviceInterface.h:83
OSVR_PLUGINKIT_EXPORT OSVR_ReturnCode OSVR_PLUGINKIT_EXPORT OSVR_ReturnCode osvrDeviceSyncInitWithOptions(OSVR_IN_PTR OSVR_PluginRegContext ctx, OSVR_IN_STRZ const char *name, OSVR_IN_PTR OSVR_DeviceInitOptions options, OSVR_OUT_PTR OSVR_DeviceToken *device) OSVR_FUNC_NONNULL((1
Initialize a synchronous device token.
void sendJsonDescriptor(OSVR_IN_READS(len) const char *json, OSVR_IN size_t len)
Submit a JSON self-descriptor string for the device.
Definition: DeviceInterface.h:190
void getNow(TimeValue &tv)
Set the given TimeValue to the current time.
Definition: TimeValue.h:51
static OSVR_ReturnCode update(void *userData)
Definition: DeviceInterface.h:84
The main namespace for all C++ elements of the framework, internal and external.
Definition: namespace_osvr.dox:3
void sendData(OSVR_IN OSVR_TimeValue const &timestamp, OSVR_MessageType msg, const char(&bytestream)[N])
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: DeviceInterface.h:321
OSVR_PLUGINKIT_EXPORT OSVR_ReturnCode OSVR_PLUGINKIT_EXPORT OSVR_ReturnCode OSVR_PLUGINKIT_EXPORT OSVR_ReturnCode osvrDeviceSendTimestampedData(OSVR_IN_PTR OSVR_DeviceToken dev, OSVR_IN_PTR const OSVR_TimeValue *timestamp, OSVR_IN_PTR OSVR_MessageType msg, OSVR_IN_READS(len) const char *bytestream, OSVR_IN size_t len) OSVR_FUNC_NONNULL((1
Send a raw bytestream from your device, with a known timestamp.
void sendData(OSVR_IN OSVR_TimeValue const &timestamp, OSVR_IN_PTR OSVR_MessageType msg, OSVR_IN_READS(len) const char *bytestream=NULL, OSVR_IN size_t len=0)
Sends a raw bytestream from your device with a known timestamp.
Definition: DeviceInterface.h:305
void send(InterfaceType &iface, MessageType const &msg)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: DeviceInterface.h:180
OSVR_MessageType registerMessageType(OSVR_IN_PTR OSVR_PluginRegContext ctx, OSVR_IN_STRZ const char *name)
Register or recall a message type by name.
Definition: DeviceInterface.h:59
void initSync(OSVR_IN_PTR OSVR_PluginRegContext ctx, OSVR_IN_STRZ const char *name, OSVR_IN_OPT OSVR_DeviceInitOptions options=NULL)
Initialize this device token as synchronous, with the given name and options.
Definition: DeviceInterface.h:109
void send(InterfaceType &iface, MessageType const &msg, OSVR_TimeValue const &timestamp)
Send a message on a registered interface type, providing the timestamp yourself.
Definition: DeviceInterface.h:172
Structure used internally to construct the desired type of device.
Definition: DeviceInitObject.h:59
#define OSVR_IN_READS(NUM_ELEMENTS)
Indicates a buffer containing input with the specified number of elements.
Definition: AnnotationMacrosC.h:134
void sendData(OSVR_IN_PTR OSVR_MessageType msg, OSVR_IN std::string const &bytestream)
Definition: DeviceInterface.h:272
void initSync(OSVR_IN_PTR OSVR_PluginRegContext ctx, OSVR_IN std::string const &name, OSVR_IN_OPT OSVR_DeviceInitOptions options=NULL)
Definition: DeviceInterface.h:125
Definition: newuoa.h:1888
Base class for connection-specific message type registration.
Definition: MessageType.h:38
void sendData(OSVR_IN_PTR OSVR_MessageType msg, OSVR_IN std::vector< char > const &bytestream)
Definition: DeviceInterface.h:282
DeviceToken()
Default constructor.
Definition: DeviceInterface.h:99
struct OSVR_DeviceTokenObject * OSVR_DeviceToken
Opaque type of a registered device token within the core library.
Definition: DeviceInterfaceC.h:60
void initAsync(OSVR_IN_PTR OSVR_PluginRegContext ctx, OSVR_IN_STRZ const char *name, OSVR_IN_OPT OSVR_DeviceInitOptions options=NULL)
Initialize this device token as asynchronous, with the given name and options.
Definition: DeviceInterface.h:137
#define OSVR_RETURN_SUCCESS
The "success" value for an OSVR_ReturnCode.
Definition: ReturnCodesC.h:45
void sendData(OSVR_MessageType msg, const char(&bytestream)[N])
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: DeviceInterface.h:267
OSVR_PLUGINKIT_EXPORT OSVR_ReturnCode OSVR_PLUGINKIT_EXPORT OSVR_ReturnCode OSVR_PLUGINKIT_EXPORT OSVR_ReturnCode OSVR_PLUGINKIT_EXPORT OSVR_ReturnCode OSVR_PLUGINKIT_EXPORT OSVR_ReturnCode osvrDeviceRegisterUpdateCallback(OSVR_IN_PTR OSVR_DeviceToken dev, OSVR_IN OSVR_DeviceUpdateCallback updateCallback, OSVR_IN_OPT void *userData OSVR_CPP_ONLY(=NULL)) OSVR_FUNC_NONNULL((1))
Register the update callback of a device.
void sendJsonDescriptor(const char(&json)[N])
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: DeviceInterface.h:204
OSVR_PLUGINKIT_EXPORT OSVR_ReturnCode OSVR_PLUGINKIT_EXPORT OSVR_ReturnCode osvrDeviceAsyncInitWithOptions(OSVR_IN_PTR OSVR_PluginRegContext ctx, OSVR_IN_STRZ const char *name, OSVR_IN_PTR OSVR_DeviceInitOptions options, OSVR_OUT_PTR OSVR_DeviceToken *device) OSVR_FUNC_NONNULL((1
Initialize an asynchronous device token.
void sendJsonDescriptor(OSVR_IN std::string const &json)
Definition: DeviceInterface.h:209
Header providing a C++ wrapper around TimeValueC.h.
void initAsync(OSVR_IN_PTR OSVR_PluginRegContext ctx, OSVR_IN std::string const &name, OSVR_IN_OPT OSVR_DeviceInitOptions options=NULL)
Definition: DeviceInterface.h:154
OSVR_PLUGINKIT_EXPORT OSVR_ReturnCode osvrDeviceAsyncInit(OSVR_IN_PTR OSVR_PluginRegContext ctx, OSVR_IN_STRZ const char *name, OSVR_OUT_PTR OSVR_DeviceToken *device) OSVR_FUNC_NONNULL((1
Initialize an asynchronous device token.
void sendData(OSVR_IN OSVR_TimeValue const &timestamp, OSVR_IN_PTR OSVR_MessageType msg, OSVR_IN std::string const &bytestream)
Definition: DeviceInterface.h:327
OSVR_PLUGINKIT_EXPORT OSVR_ReturnCode osvrDeviceSyncInit(OSVR_IN_PTR OSVR_PluginRegContext ctx, OSVR_IN_STRZ const char *name, OSVR_OUT_PTR OSVR_DeviceToken *device) OSVR_FUNC_NONNULL((1
Initialize a synchronous device token.
OSVR_EXTERN_C_BEGIN typedef void * OSVR_PluginRegContext
A context pointer passed in to your plugin&#39;s entry point and other locations of control flow transfer...
Definition: PluginRegContextC.h:47
#define OSVR_IN
Indicates a required function parameter that serves only as input.
Definition: AnnotationMacrosC.h:100
Standardized, portable parallel to struct timeval for representing both absolute times and time inter...
Definition: TimeValueC.h:81
void sendData(OSVR_IN OSVR_TimeValue const &timestamp, OSVR_IN_PTR OSVR_MessageType msg, OSVR_IN std::vector< char > const &bytestream)
Definition: DeviceInterface.h:339
OSVR_PLUGINKIT_EXPORT OSVR_ReturnCode OSVR_PLUGINKIT_EXPORT OSVR_ReturnCode osvrDeviceSendData(OSVR_IN_PTR OSVR_DeviceToken dev, OSVR_IN_PTR OSVR_MessageType msg, OSVR_IN_READS(len) const char *bytestream, OSVR_IN size_t len) OSVR_FUNC_NONNULL((1
Send a raw bytestream from your device.
void registerUpdateCallback(OSVR_IN_PTR DeviceObjectType *object)
Given a pointer to your object that has a public OSVR_ReturnCode update() method, registers that inst...
Definition: DeviceInterface.h:223
OSVR_PLUGINKIT_EXPORT OSVR_ReturnCode OSVR_PLUGINKIT_EXPORT OSVR_ReturnCode OSVR_PLUGINKIT_EXPORT OSVR_ReturnCode OSVR_PLUGINKIT_EXPORT OSVR_ReturnCode osvrDeviceSendJsonDescriptor(OSVR_IN_PTR OSVR_DeviceToken dev, OSVR_IN_READS(len) const char *json, OSVR_IN size_t len) OSVR_FUNC_NONNULL((1
Submit a JSON self-descriptor string for the device.