OSVR Framework (Internal Development Docs)  0.6-1962-g59773924
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
ButtonRemoteFactory.cpp
Go to the documentation of this file.
1 
11 // Copyright 2015 Sensics, Inc.
12 //
13 // Licensed under the Apache License, Version 2.0 (the "License");
14 // you may not use this file except in compliance with the License.
15 // You may obtain a copy of the License at
16 //
17 // http://www.apache.org/licenses/LICENSE-2.0
18 //
19 // Unless required by applicable law or agreed to in writing, software
20 // distributed under the License is distributed on an "AS IS" BASIS,
21 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 // See the License for the specific language governing permissions and
23 // limitations under the License.
24 
25 // Internal Includes
26 #include "ButtonRemoteFactory.h"
27 #include "RemoteHandlerInternals.h"
32 #include <osvr/Util/UniquePtr.h>
35 #include <osvr/Util/ValueOrRange.h>
36 #include <osvr/Util/Verbosity.h>
37 
38 // Library/third-party includes
39 #include <vrpn_Button.h>
40 #include <boost/lexical_cast.hpp>
41 #include <boost/any.hpp>
42 #include <boost/variant/get.hpp>
43 #include <json/value.h>
44 #include <json/reader.h>
45 
46 // Standard includes
47 // - none
48 
49 namespace osvr {
50 namespace client {
51 
53  public:
55  VRPNButtonHandler(vrpn_ConnectionPtr const &conn, const char *src,
56  boost::optional<int> sensor,
57  common::InterfaceList &ifaces)
58  : m_remote(new vrpn_Button_Remote(src, conn.get())),
59  m_internals(ifaces), m_all(!sensor.is_initialized()) {
60  m_remote->register_change_handler(this, &VRPNButtonHandler::handle);
61  m_remote->register_states_handler(
62  this, &VRPNButtonHandler::handle_states);
63  OSVR_DEV_VERBOSE("Constructed a ButtonHandler for " << src);
64 
65  if (sensor.is_initialized()) {
66  m_sensors.setValue(*sensor);
67  }
68  }
69  virtual ~VRPNButtonHandler() {
70  m_remote->unregister_change_handler(this,
71  &VRPNButtonHandler::handle);
72  m_remote->unregister_states_handler(
73  this, &VRPNButtonHandler::handle_states);
74  }
75 
76  static void VRPN_CALLBACK handle(void *userdata, vrpn_BUTTONCB info) {
77  auto self = static_cast<VRPNButtonHandler *>(userdata);
78  self->m_handle(info);
79  }
80 
81  static void VRPN_CALLBACK handle_states(void *userdata,
82  vrpn_BUTTONSTATESCB info) {
83  auto self = static_cast<VRPNButtonHandler *>(userdata);
84  self->m_handle(info);
85  }
86  virtual void update() { m_remote->mainloop(); }
87 
88  private:
89  void m_handle(vrpn_BUTTONCB const &info) {
90  if (!m_all && !m_sensors.contains(info.button)) {
91  return;
92  }
93 
94  OSVR_TimeValue timestamp;
95  osvrStructTimevalToTimeValue(&timestamp, &(info.msg_time));
96 
97  m_report(timestamp, info.button, info.state);
98  }
99  void m_handle(vrpn_BUTTONSTATESCB const &info) {
100  auto maxChannel =
101  m_all ? info.num_buttons - 1 : m_sensors.getValue();
102  if (!m_all &&
103  m_sensors.getIntersection(RangeType::RangeZeroTo(maxChannel))
104  .empty()) {
105  // early out if we're looking for just a single channel number
106  // that isn't in this report.
107  return;
108  }
109  if (m_all) {
110  if (m_sensors.empty()) {
111  m_sensors.setRangeMaxMin(maxChannel);
112  } else {
113  m_sensors.extendRangeToMax(maxChannel);
114  }
115  }
116  OSVR_TimeValue timestamp;
117  osvrStructTimevalToTimeValue(&timestamp, &(info.msg_time));
118 
119  for (auto sensor : m_sensors.getIntersection(
120  RangeType::RangeZeroTo(maxChannel))) {
121  m_report(timestamp, sensor, info.states[sensor]);
122  }
123  }
124  void m_report(OSVR_TimeValue const &timestamp, int32_t sensor,
125  vrpn_int32 state) {
126  OSVR_ButtonReport report;
127  report.sensor = sensor;
128  report.state = static_cast<uint8_t>(state);
129  m_internals.setStateAndTriggerCallbacks(timestamp, report);
130  }
131  unique_ptr<vrpn_Button_Remote> m_remote;
132  RemoteHandlerInternals m_internals;
133  bool m_all;
134  RangeType m_sensors;
135  };
136 
137  ButtonRemoteFactory::ButtonRemoteFactory(
138  VRPNConnectionCollection const &conns)
139  : m_conns(conns) {}
140 
141  shared_ptr<RemoteHandler> ButtonRemoteFactory::
143  common::InterfaceList &ifaces, common::ClientContext &) {
144 
145  shared_ptr<RemoteHandler> ret;
146 
147  if (source.hasTransform()) {
148  OSVR_DEV_VERBOSE(
149  "Ignoring transform found on route for Button data!");
150  }
151 
152  auto const &devElt = source.getDeviceElement();
153 
155  ret.reset(new VRPNButtonHandler(m_conns.getConnection(devElt),
156  devElt.getFullDeviceName().c_str(),
157  source.getSensorNumber(), ifaces));
158  return ret;
159  }
160 
161 } // namespace client
162 } // namespace osvr
The result of resolving a tree node to a device: either an original source to connect to...
shared_ptr< RemoteHandler > operator()(common::OriginalSource const &source, common::InterfaceList &ifaces, common::ClientContext &ctx)
Header including PathTree.h and all additional headers needed to define related types.
Header to bring unique_ptr into the osvr namespace.
Report type for a callback on a button interface.
OSVR_ButtonState state
The button state: 1 is pressed, 0 is not pressed.
void setStateAndTriggerCallbacks(const OSVR_TimeValue &timestamp, ReportType const &report)
Set state and call callbacks for a report type.
int32_t sensor
Identifies the sensor that the report comes from.
void osvrStructTimevalToTimeValue(OSVR_TimeValue *dest, const struct timeval *src)
Converts from a TimeValue struct to your system's struct timeval.
Internal, configured header file for verbosity macros.
Standardized, portable parallel to struct timeval for representing both absolute times and time inter...
Definition: TimeValueC.h:81
Base class for remote device handler classes.
Definition: RemoteHandler.h:40
Class holding shared implementation between the various handlers. Primarily used to avoid the need fo...