AnalysisClientContext::AnalysisClientContext( const char appId[], const char host[], vrpn_ConnectionPtr const &conn, common::ClientContextDeleter del) : ::OSVR_ClientContextObject(appId, del), m_mainConn(conn), m_ifaceMgr(m_pathTreeOwner, m_factory, *static_cast<common::ClientContext *>(this)) { /// Create all the remote handler factories. populateRemoteHandlerFactory(m_factory, m_vrpnConns); m_vrpnConns.addConnection(m_mainConn, "localhost"); m_vrpnConns.addConnection(m_mainConn, host); std::string sysDeviceName = std::string(common::SystemComponent::deviceName()) + "@" + host; m_mainConn = m_vrpnConns.getConnection( common::SystemComponent::deviceName(), host); /// Create the system client device. m_systemDevice = common::createClientDevice(sysDeviceName, m_mainConn); m_systemComponent = m_systemDevice->addComponent(common::SystemComponent::create()); using DedupJsonFunction = common::DeduplicatingFunctionWrapper<Json::Value const &>; m_systemComponent->registerReplaceTreeHandler( DedupJsonFunction([&](Json::Value nodes) { OSVR_DEV_VERBOSE("Got updated path tree, processing"); // Tree observers will handle destruction/creation of remote // handlers. m_pathTreeOwner.replaceTree(nodes); })); // No startup spin. }
PureClientContext::PureClientContext(const char appId[], const char host[], common::ClientContextDeleter del) : ::OSVR_ClientContextObject(appId, del), m_host(host), m_ifaceMgr(m_pathTreeOwner, m_factory, *static_cast<common::ClientContext *>(this)) { if (!m_network.isUp()) { throw std::runtime_error("Network error: " + m_network.getError()); } /// Create all the remote handler factories. populateRemoteHandlerFactory(m_factory, m_vrpnConns); std::string sysDeviceName = std::string(common::SystemComponent::deviceName()) + "@" + host; m_mainConn = m_vrpnConns.getConnection( common::SystemComponent::deviceName(), host); /// Create the system client device. m_systemDevice = common::createClientDevice(sysDeviceName, m_mainConn); m_systemComponent = m_systemDevice->addComponent(common::SystemComponent::create()); using DedupJsonFunction = common::DeduplicatingFunctionWrapper<Json::Value const &>; m_systemComponent->registerReplaceTreeHandler( DedupJsonFunction([&](Json::Value nodes) { logger()->debug("Got updated path tree, processing"); // Replace localhost before we even convert the json to a tree. // replace the @localhost with the correct host name // in case we are a remote client, otherwise the connection // would fail replaceLocalhostServers(nodes, m_host); // Tree observers will handle destruction/creation of remote // handlers. m_pathTreeOwner.replaceTree(nodes); })); typedef std::chrono::system_clock clock; auto begin = clock::now(); // Spin the update to get a connection auto connEnd = begin + STARTUP_CONNECT_TIMEOUT; while (clock::now() < connEnd && !m_gotConnection) { m_update(); std::this_thread::sleep_for(STARTUP_LOOP_SLEEP); } if (!m_gotConnection) { logger()->notice() << "Could not connect to OSVR server in the timeout period " "allotted of " << std::chrono::duration_cast<std::chrono::milliseconds>( STARTUP_CONNECT_TIMEOUT) .count() << "ms"; return; // Bail early if we don't even have a connection } // Spin the update to get a path tree auto treeEnd = begin + STARTUP_TREE_TIMEOUT; while (clock::now() < treeEnd && !m_pathTreeOwner) { m_update(); std::this_thread::sleep_for(STARTUP_LOOP_SLEEP); } auto timeToStartup = (clock::now() - begin); // this message is just "info" if we're all good, but "notice" if we // aren't fully set up yet. logger()->log(m_pathTreeOwner ? util::log::LogLevel::info : util::log::LogLevel::notice) << "Connection process took " << std::chrono::duration_cast<std::chrono::milliseconds>( timeToStartup) .count() << "ms: " << (m_gotConnection ? "have connection to server, " : "don't have connection to server, ") << (m_pathTreeOwner ? "have path tree" : "don't have path tree"); }