36 #include <boost/algorithm/string.hpp> 
   39 #include <json/value.h> 
   42 #include <unordered_set> 
   47     inline void replaceLocalhostServers(Json::Value &nodes,
 
   48                                         std::string 
const &host) {
 
   49         BOOST_ASSERT_MSG(host.length() > 0,
 
   50                          "Cannot replace localhost with an empty host name!");
 
   51         const auto deviceElementTypeName =
 
   52             common::elements::getTypeName<common::elements::DeviceElement>();
 
   53         static const auto LOCALHOST = 
"localhost";
 
   54         for (
auto &node : nodes) {
 
   55             if (node[
"type"].asString() == deviceElementTypeName) {
 
   56                 auto &serverRef = node[
"server"];
 
   57                 auto server = serverRef.asString();
 
   59                 auto it = server.find(LOCALHOST);
 
   61                 if (it != server.npos) {
 
   75                     serverRef = boost::algorithm::ireplace_first_copy(
 
   83     static const std::chrono::milliseconds STARTUP_CONNECT_TIMEOUT(200);
 
   84     static const std::chrono::milliseconds STARTUP_TREE_TIMEOUT(1000);
 
   85     static const std::chrono::milliseconds STARTUP_LOOP_SLEEP(1);
 
   87     PureClientContext::PureClientContext(
const char appId[], 
const char host[],
 
   88                                          common::ClientContextDeleter del)
 
   90           m_ifaceMgr(m_pathTreeOwner, m_factory,
 
   91                      *static_cast<common::ClientContext *>(this)) {
 
   93         if (!m_network.
isUp()) {
 
   94             throw std::runtime_error(
"Network error: " + m_network.
getError());
 
   98         populateRemoteHandlerFactory(m_factory, m_vrpnConns);
 
  100         std::string sysDeviceName =
 
  102         m_mainConn = m_vrpnConns.getConnection(
 
  109         using DedupJsonFunction =
 
  112         m_systemComponent->registerReplaceTreeHandler(
 
  113             DedupJsonFunction([&](Json::Value nodes) {
 
  114                 logger()->debug(
"Got updated path tree, processing");
 
  119                 replaceLocalhostServers(nodes, m_host);
 
  126         typedef std::chrono::system_clock clock;
 
  127         auto begin = clock::now();
 
  130         auto connEnd = begin + STARTUP_CONNECT_TIMEOUT;
 
  131         while (clock::now() < connEnd && !m_gotConnection) {
 
  133             std::this_thread::sleep_for(STARTUP_LOOP_SLEEP);
 
  135         if (!m_gotConnection) {
 
  137                 << 
"Could not connect to OSVR server in the timeout period " 
  139                 << std::chrono::duration_cast<std::chrono::milliseconds>(
 
  140                        STARTUP_CONNECT_TIMEOUT)
 
  147         auto treeEnd = begin + STARTUP_TREE_TIMEOUT;
 
  148         while (clock::now() < treeEnd && !m_pathTreeOwner) {
 
  150             std::this_thread::sleep_for(STARTUP_LOOP_SLEEP);
 
  152         auto timeToStartup = (clock::now() - begin);
 
  156         logger()->log(m_pathTreeOwner ? util::log::LogLevel::info
 
  157                                       : util::log::LogLevel::notice)
 
  158             << 
"Connection process took " 
  159             << std::chrono::duration_cast<std::chrono::milliseconds>(
 
  162             << 
"ms: " << (m_gotConnection ? 
"have connection to server, " 
  163                                           : 
"don't have connection to server, ")
 
  164             << (m_pathTreeOwner ? 
"have path tree" : 
"don't have path tree");
 
  167     PureClientContext::~PureClientContext() {}
 
  169     void PureClientContext::m_update() {
 
  171         m_vrpnConns.updateAll();
 
  173         if (!m_gotConnection && m_mainConn->connected()) {
 
  174             logger()->info(
"Got connection to main OSVR server");
 
  175             m_gotConnection = 
true;
 
  179         m_systemDevice->update();
 
  184     void PureClientContext::m_sendRoute(std::string 
const &route) {
 
  185         m_systemComponent->sendClientRouteUpdate(route);
 
  189     void PureClientContext::m_handleNewInterface(
 
  194     void PureClientContext::m_handleReleasingInterface(
 
  196         m_ifaceMgr.releaseInterface(iface);
 
  199     bool PureClientContext::m_getStatus()
 const {
 
  200         return m_gotConnection && m_pathTreeOwner;
 
  203     common::PathTree 
const &PureClientContext::m_getPathTree()
 const {
 
  204         return m_pathTreeOwner.
get();
 
  207     common::Transform 
const &
 
  208     PureClientContext::m_getRoomToWorldTransform()
 const {
 
  209         return m_roomToWorld;
 
  212     void PureClientContext::m_setRoomToWorldTransform(
 
  213         common::Transform 
const &xform) {
 
  214         m_roomToWorld = xform;
 
void replaceTree(Json::Value const &nodes)
Replace the entirety of the path tree from the given serialized array of nodes. 
shared_ptr< ClientInterface > ClientInterfacePtr
Pointer for holding ClientInterface objects safely. 
BaseDevicePtr createClientDevice(std::string const &name, vrpn_ConnectionPtr const &conn)
Factory function for a bare client device with no components/interfaces registered by default...
Header including PathTree.h and all additional headers needed to define related types. 
std::string const & getError() const 
Get error message, if any. 
static shared_ptr< SystemComponent > create()
Factory method. 
void addInterface(common::ClientInterfacePtr const &iface, bool verboseFailure=true)
Internal, configured header file for verbosity macros. 
static const char * deviceName()
Get the special device name to be used with this component. 
osvr::util::log::LoggerPtr const & logger() const 
Provides logger access for related internal classes. 
void updateHandlers()
run update on all remote handlers 
A wrapper for a unary function that only calls its contained function when the input has changed...
bool isUp() const 
Get whether the networking system is successfully "up". 
PathTree & get()
Access the path tree object itself.