Esempio n. 1
0
    bool PureClientContext::m_connectCallbacksOnPath(std::string const &path) {
        /// Start by removing handler from interface tree and handler container
        /// for this path, if found. Ensures that if we early-out (fail to set
        /// up a handler) we don't have a leftover one still active.
        m_interfaces.eraseHandlerForPath(path);

        auto source = common::resolveTreeNode(m_pathTree, path);
        if (!source.is_initialized()) {
            OSVR_DEV_VERBOSE("Could not resolve source for " << path);
            return false;
        }
        auto handler = m_factory.invokeFactory(
            *source, m_interfaces.getInterfacesForPath(path), *this);
        if (handler) {
            OSVR_DEV_VERBOSE("Successfully produced handler for " << path);
            // Store the new handler in the interface tree
            auto oldHandler = m_interfaces.replaceHandlerForPath(path, handler);
            BOOST_ASSERT_MSG(
                !oldHandler,
                "We removed the old handler before so it should be null now");
            return true;
        }

        OSVR_DEV_VERBOSE("Could not produce handler for " << path);
        return false;
    }
Esempio n. 2
0
OSVR_ReturnCode osvrClientGetSkeletonBoneName(OSVR_Skeleton skel,
                                              OSVR_SkeletonBoneCount boneId,
                                              char *boneName, uint32_t len) {
    OSVR_VALIDATE_SKELETON_CONFIG;
    OSVR_VALIDATE_OUTPUT_PTR(boneName, "bone name");
    try {
        auto name = skel->getBoneName(boneId);
        if (name.size() + 1 > len) {
            /// buffer too small
            return OSVR_RETURN_FAILURE;
        }
        // this line pops warning 4996 on VS compiler, disabled above
        name.copy(boneName, name.size());
        boneName[name.size()] = '\0';
    } catch (osvr::client::IdNotFound &) {
        OSVR_DEV_VERBOSE(
            "Error getting name for provided boneId : Id not found");
        return OSVR_RETURN_FAILURE;
    } catch (std::exception &e) {
        OSVR_DEV_VERBOSE(
            "Error getting name for provided boneId : " << e.what());
        return OSVR_RETURN_FAILURE;
    }
    return OSVR_RETURN_SUCCESS;
}
OSVR_ReturnCode
osvrAnalysisSyncInit(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_OUT_PTR OSVR_ClientContext *clientCtx) {
    if (!ctx) {
        OSVR_DEV_VERBOSE("osvrAnalysisSyncInit: can't use a null plugin "
                         "registration context.");
        return OSVR_RETURN_FAILURE;
    }
    if (!name || !(name[0])) {
        OSVR_DEV_VERBOSE(
            "osvrAnalysisSyncInit: can't use a null or empty device name.");
        return OSVR_RETURN_FAILURE;
    }
    OSVR_VALIDATE_OUTPUT_PTR(device, "device token");
    OSVR_VALIDATE_OUTPUT_PTR(clientCtx, "client context");

    auto initialResult =
        osvrDeviceSyncInitWithOptions(ctx, name, options, device);
    if (initialResult == OSVR_RETURN_FAILURE) {
        OSVR_DEV_VERBOSE(
            "osvrAnalysisSyncInit: couldn't create initial device token.");
        return OSVR_RETURN_FAILURE;
    }

    /// Dig the VRPN connection out of the server.
    auto osvrConn = osvr::connection::Connection::retrieveConnection(
        osvr::pluginhost::PluginSpecificRegistrationContext::get(ctx)
            .getParent());
    auto vrpnConn = extractVrpnConnection(*osvrConn);

    /// Create a client context here

    /// @todo Use an interface factory that handles relative paths.
    auto clientCtxSmart = osvr::common::wrapSharedContext(
        osvr::client::createAnalysisClientContext(
            "org.osvr.analysisplugin" /**< @todo */, "localhost" /**< @todo */,
            vrpn_ConnectionPtr(vrpnConn)));
    auto &dev = **device;
    /// pass ownership
    dev.acquireObject(clientCtxSmart);

    /// register client context update
    dev.setPreConnectionInteract([=] { clientCtxSmart->update(); });

    /// finally return the client context too.
    *clientCtx = clientCtxSmart.get();
    return OSVR_RETURN_SUCCESS;
}
Esempio n. 4
0
 bool addAlias(PathNode &node, std::string const &source,
               AliasPriority priority) {
     ParsedAlias newSource(source);
     if (!newSource.isValid()) {
         /// @todo signify invalid route in some other way?
         OSVR_DEV_VERBOSE("Could not parse source: " << source);
         return false;
     }
     if (!isPathAbsolute(newSource.getLeaf())) {
         /// @todo signify not to pass relative paths here in some other way?
         OSVR_DEV_VERBOSE(
             "Source contains a relative path, not permitted: " << source);
         return false;
     }
     return addAliasImpl(node, newSource.getAlias(), priority);
 }
Esempio n. 5
0
    void ParsedAlias::m_parse(Json::Value &val) {
        if (val.isString()) {
            // Assume a string is just a string.
            m_value = val;
            return;
        }
        if (val.isObject()) {
            if (val.isMember(SOURCE_KEY)) {
                // Strip any initial "source" level
                m_parse(val[SOURCE_KEY]);
                return;
            }

            // Assume an object means a transform.
            m_simple = false;
            m_value = val;

            auto &leaf = m_leaf();
            if (leaf.isString()) {
                return;
            }

            auto trackerEquiv = getPathFromOldRouteSource(leaf);
            if (!trackerEquiv.empty()) {
                leaf = trackerEquiv;
                return;
            }

            OSVR_DEV_VERBOSE(
                "Couldn't handle transform leaf: " << leaf.toStyledString());
        }
        m_value = Json::nullValue;
        /// @todo finish by throwing?
    }
Esempio n. 6
0
    bool ServerImpl::loop() {
        bool shouldContinue;
        {
            /// @todo More elegant way of running queued things than grabbing a
            /// mutex each time through?
            boost::unique_lock<boost::mutex> lock(m_mainThreadMutex);
            m_conn->process();
            if (m_treeDirty) {
                OSVR_DEV_VERBOSE("Path tree updated");
                m_sendTree();
                m_treeDirty.reset();
            }
            m_systemDevice->update();
            for (auto &f : m_mainloopMethods) {
                f();
            }
            shouldContinue = m_run.shouldContinue();
        }

        if (m_sleepTime > 0) {
            osvr::util::time::microsleep(m_sleepTime);
        } else {
            m_thread.yield();
        }
        return shouldContinue;
    }
    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.
    }
 RenderManagerConfigPtr RenderManagerConfigFactory::createShared(OSVR_ClientContext ctx) {
     try {
         auto const configString = ctx->getStringParameter("/renderManagerConfig");
         RenderManagerConfigPtr cfg(new RenderManagerConfig(configString));
         return cfg;
     }
     catch (std::exception const &e) {
         OSVR_DEV_VERBOSE(
             "Couldn't create a render manager config internally! Exception: "
             << e.what());
         return RenderManagerConfigPtr{};
     }
     catch (...) {
         OSVR_DEV_VERBOSE("Couldn't create a render manager config internally! "
             "Unknown exception!");
         return RenderManagerConfigPtr{};
     }
 }
Esempio n. 9
0
OSVR_ReturnCode osvrClientGetSkeletonStringBoneNameLength(
    OSVR_Skeleton skel, OSVR_SkeletonBoneCount boneId, uint32_t *len) {
    OSVR_VALIDATE_SKELETON_CONFIG;
    OSVR_VALIDATE_OUTPUT_PTR(len, "name length");
    try {
        auto boneName = skel->getBoneName(boneId);
        *len =
            static_cast<uint32_t>(boneName.empty() ? 0 : (boneName.size() + 1));
    } catch (osvr::client::IdNotFound &) {
        OSVR_DEV_VERBOSE(
            "Error getting name for provided boneId : Id not found");
        return OSVR_RETURN_FAILURE;
    } catch (std::exception &e) {
        OSVR_DEV_VERBOSE(
            "Error getting name for provided boneId : " << e.what());
        return OSVR_RETURN_FAILURE;
    }
    return OSVR_RETURN_SUCCESS;
}
Esempio n. 10
0
OSVR_ReturnCode osvrClientGetSkeletonBoneId(OSVR_Skeleton skel,
                                            const char *boneName,
                                            OSVR_SkeletonBoneCount *boneId) {
    OSVR_VALIDATE_SKELETON_CONFIG;
    OSVR_VALIDATE_OUTPUT_PTR(boneId, "bone Id");
    if (!skel->getBoneId(boneName, boneId)) {
        OSVR_DEV_VERBOSE("Error getting boneId for " << boneName);
        return OSVR_RETURN_FAILURE;
    }
    return OSVR_RETURN_SUCCESS;
}
Esempio n. 11
0
OSVR_ReturnCode
osvrClientGetSkeletonJointState(OSVR_Skeleton skel,
                                OSVR_SkeletonJointCount jointId,
                                OSVR_SkeletonJointState *state) {
    OSVR_VALIDATE_SKELETON_CONFIG;
    OSVR_VALIDATE_OUTPUT_PTR(state, "joint state");
    try {
        OSVR_Pose3 pose = skel->getJointState(jointId);
        state->jointId = jointId;
        state->pose = pose;
    } catch (osvr::client::NoPoseYet &) {
        OSVR_DEV_VERBOSE("Error getting pose for joint: no pose yet available");
        return OSVR_RETURN_FAILURE;
    } catch (std::exception &e) {
        OSVR_DEV_VERBOSE("Error getting joint pose - exception: " << e.what());
        return OSVR_RETURN_FAILURE;
    }

    return OSVR_RETURN_SUCCESS;
}
Esempio n. 12
0
OSVR_ReturnCode osvrClientGetSkeletonJointId(OSVR_Skeleton skel,
                                             const char *jointName,
                                             OSVR_SkeletonJointCount *jointId) {
    OSVR_VALIDATE_SKELETON_CONFIG;
    OSVR_VALIDATE_OUTPUT_PTR(jointId, "joint Id");
    if (!skel->getJointId(jointName, jointId)) {
        OSVR_DEV_VERBOSE("Error getting jointId for " << jointName);
        return OSVR_RETURN_FAILURE;
    }
    return OSVR_RETURN_SUCCESS;
}
Esempio n. 13
0
 void VrpnBasedConnection::m_initConnection(const char iface[], int port) {
     if (!m_network.isUp()) {
         OSVR_DEV_VERBOSE("Network error: " << m_network.getError());
         throw std::runtime_error(m_network.getError());
     }
     if (0 == port) {
         port = vrpn_DEFAULT_LISTEN_PORT_NO;
     }
     m_vrpnConnection = vrpn_ConnectionPtr::create_server_connection(
         port, nullptr, nullptr, iface);
 }
Esempio n. 14
0
OSVR_CLIENTKIT_EXPORT OSVR_ReturnCode osvrClientGetSkeletonAvailableJointId(
    OSVR_Skeleton skel, OSVR_SkeletonJointCount jointIndex,
    OSVR_SkeletonJointCount *jointId) {
    OSVR_VALIDATE_SKELETON_CONFIG;
    OSVR_VALIDATE_OUTPUT_PTR(jointId, "joint Id");
    if (!skel->getAvailableJointId(jointIndex, jointId)) {
        OSVR_DEV_VERBOSE("ERROR getting the jointId for jointIndex "
                         << jointIndex);
        return OSVR_RETURN_FAILURE;
    }
    return OSVR_RETURN_SUCCESS;
}
Esempio n. 15
0
        VRPNAnalogHandler(vrpn_ConnectionPtr const &conn, const char *src,
                          boost::optional<int> sensor,
                          common::InterfaceList &ifaces)
            : m_remote(new vrpn_Analog_Remote(src, conn.get())),
              m_interfaces(ifaces), m_all(!sensor.is_initialized()) {
            m_remote->register_change_handler(this, &VRPNAnalogHandler::handle);
            OSVR_DEV_VERBOSE("Constructed an AnalogHandler for " << src);

            if (sensor.is_initialized()) {
                m_sensors.setValue(*sensor);
            }
        }
Esempio n. 16
0
OSVR_CLIENTKIT_EXPORT OSVR_ReturnCode osvrClientGetSkeletonAvailableBoneId(
    OSVR_Skeleton skel, OSVR_SkeletonBoneCount boneIndex,
    OSVR_SkeletonBoneCount *boneId) {
    OSVR_VALIDATE_SKELETON_CONFIG;
    OSVR_VALIDATE_OUTPUT_PTR(boneId, "bone Id");
    if (!skel->getAvailableBoneId(boneIndex, boneId)) {
        OSVR_DEV_VERBOSE("ERROR getting the boneId for boneIndex "
                         << boneIndex);
        return OSVR_RETURN_FAILURE;
    }
    return OSVR_RETURN_SUCCESS;
}
Esempio n. 17
0
 void ServerImpl::m_handleDeviceDescriptors() {
     for (auto const &dev : m_conn->getDevices()) {
         auto const &descriptor = dev->getDeviceDescriptor();
         if (descriptor.empty()) {
             OSVR_DEV_VERBOSE("Developer Warning: No device descriptor for "
                              << dev->getName());
         } else {
             m_treeDirty += common::processDeviceDescriptorForPathTree(
                 m_tree, dev->getName(), descriptor);
         }
     }
 }
Esempio n. 18
0
    void JointClientContext::m_handleReplaceTree(Json::Value const &nodes) {
        OSVR_DEV_VERBOSE("Got updated path tree, processing");
        // reset path tree
        m_pathTree.reset();
        // wipe out handlers in the interface tree
        m_interfaces.clearHandlers();

        // populate path tree from message
        common::jsonToPathTree(m_pathTree, nodes);

        // re-connect handlers.
        m_connectNeededCallbacks();
    }
Esempio n. 19
0
 /// @brief Handle an alias element
 void operator()(elements::AliasElement const &elt) {
     // This is an alias.
     ParsedAlias parsed(elt.getSource());
     if (!parsed.isValid()) {
         OSVR_DEV_VERBOSE("Couldn't parse alias: " << elt.getSource());
         return;
     }
     /// @todo update the element with the normalized source?
     if (!parsed.isSimple()) {
         // Not simple: store the full string as a transform.
         m_source.nestTransform(parsed.getAliasValue());
     }
     m_recurse(parsed.getLeaf());
 }
Esempio n. 20
0
    void PureClientContext::m_update() {
        /// Mainloop connections
        m_vrpnConns.updateAll();

        if (!m_gotConnection && m_mainConn->connected()) {
            OSVR_DEV_VERBOSE("Got connection to main OSVR server");
            m_gotConnection = true;
        }

        /// Update system device
        m_systemDevice->update();
        /// Update handlers.
        m_interfaces.updateHandlers();
    }
Esempio n. 21
0
 bool addAliasFromSourceAndRelativeDest(PathNode &node,
                                        std::string const &source,
                                        std::string const &dest,
                                        AliasPriority priority) {
     auto &aliasNode = treePathRetrieve(node, dest);
     ParsedAlias newSource(source);
     if (!newSource.isValid()) {
         /// @todo signify invalid route in some other way?
         OSVR_DEV_VERBOSE("Could not parse source: " << source);
         return false;
     }
     auto absSource = getAbsolutePath(node, newSource.getLeaf());
     newSource.setLeaf(absSource);
     return addAliasImpl(aliasNode, newSource.getAlias(), priority);
 }
Esempio n. 22
0
 NetworkDirectionRemoteHandler(vrpn_ConnectionPtr const &conn,
                               std::string const &deviceName,
                               boost::optional<OSVR_ChannelCount> sensor,
                               common::InterfaceList &ifaces)
     : m_dev(common::createClientDevice(deviceName, conn)),
       m_internals(ifaces), m_all(!sensor.is_initialized()),
       m_sensor(sensor) {
     auto direction = common::DirectionComponent::create();
     m_dev->addComponent(direction);
     direction->registerDirectionHandler(
         [&](common::DirectionData const &data,
             util::time::TimeValue const &timestamp) {
             m_handleDirection(data, timestamp);
         });
     OSVR_DEV_VERBOSE("Constructed an Direction Handler for "
                      << deviceName);
 }
Esempio n. 23
0
    shared_ptr<RemoteHandler> ButtonRemoteFactory::
    operator()(common::OriginalSource const &source,
               common::InterfaceList &ifaces, common::ClientContext &) {

        shared_ptr<RemoteHandler> ret;

        if (source.hasTransform()) {
            OSVR_DEV_VERBOSE(
                "Ignoring transform found on route for Button data!");
        }

        auto const &devElt = source.getDeviceElement();

        /// @todo find out why make_shared causes a crash here
        ret.reset(new VRPNButtonHandler(m_conns.getConnection(devElt),
                                        devElt.getFullDeviceName().c_str(),
                                        source.getSensorNumber(), ifaces));
        return ret;
    }
Esempio n. 24
0
    JointClientContext::JointClientContext(const char appId[],
                                           common::ClientContextDeleter del)
        : ::OSVR_ClientContextObject(appId, del),
          m_ifaceMgr(m_pathTreeOwner, m_factory,
                     *static_cast<common::ClientContext *>(this)) {

        /// Create all the remote handler factories.
        populateRemoteHandlerFactory(m_factory, m_vrpnConns);

        /// creates the OSVR connection with its nested VRPN connection
        auto conn = connection::Connection::createLoopbackConnection();

        /// Get the VRPN connection out and use it.
        m_mainConn = static_cast<vrpn_Connection *>(std::get<0>(conn));
        m_vrpnConns.addConnection(m_mainConn, HOST);
        BOOST_ASSERT(!m_vrpnConns.empty());

        /// Get the OSVR connection out and use it to make a server.
        m_server = server::Server::createNonListening(std::get<1>(conn));

        std::string sysDeviceName =
            std::string(common::SystemComponent::deviceName()) + "@" + HOST;

        /// Create the system client device.
        m_systemDevice = common::createClientDevice(sysDeviceName, m_mainConn);
        m_systemComponent =
            m_systemDevice->addComponent(common::SystemComponent::create());
        typedef common::DeduplicatingFunctionWrapper<Json::Value const &>
            DedupJsonFunction;

        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);
            }));
    }
    shared_ptr<RemoteHandler> ImagingRemoteFactory::
    operator()(common::OriginalSource const &source,
               common::InterfaceList &ifaces, common::ClientContext &) {

        shared_ptr<RemoteHandler> ret;

        if (source.hasTransform()) {
            OSVR_DEV_VERBOSE(
                "Ignoring transform found on route for Imaging data!");
        }

        /// @todo This is where we'd take a different path for IPC imaging data.
        auto const &devElt = source.getDeviceElement();

        /// @todo find out why make_shared causes a crash here
        ret.reset(new NetworkImagingRemoteHandler(
            m_conns.getConnection(devElt), devElt.getFullDeviceName(),
            source.getSensorNumberAsChannelCount(), ifaces));
        return ret;
    }
Esempio n. 26
0
 void PureClientContext::m_connectNeededCallbacks() {
     std::unordered_set<std::string> failedPaths;
     size_t successfulPaths{0};
     for (auto const &iface : getInterfaces()) {
         /// @todo slightly overkill, but it works - tree traversal would be
         /// better.
         auto path = iface->getPath();
         /// For every interface, if there's no handler at that path on the
         /// interface tree, try to set one up.
         if (!m_interfaces.getHandlerForPath(path)) {
             auto success = m_connectCallbacksOnPath(path);
             if (success) {
                 successfulPaths++;
             } else {
                 failedPaths.insert(path);
             }
         }
     }
     OSVR_DEV_VERBOSE("Connected " << successfulPaths << " of "
                                   << successfulPaths + failedPaths.size()
                                   << " unconnected paths successfully");
 }
Esempio n. 27
0
    void PureClientContext::m_handleReplaceTree(Json::Value const &nodes) {
        m_gotTree = true;
        OSVR_DEV_VERBOSE("Got updated path tree, processing");
        // reset path tree
        m_pathTree.reset();
        // wipe out handlers in the interface tree
        m_interfaces.clearHandlers();

        // populate path tree from message
        common::jsonToPathTree(m_pathTree, nodes);

        // replace the @localhost with the correct host name
        // in case we are a remote client, otherwise the connection
        // would fail

        LocalhostReplacer replacer(m_host);
        util::traverseWith(m_pathTree.getRoot(),
                           [&replacer](osvr::common::PathNode &node) {
                               common::applyPathNodeVisitor(replacer, node);
                           });

        // re-connect handlers.
        m_connectNeededCallbacks();
    }
Esempio n. 28
0
        void
        DisplayDescriptor::m_processResolution(Json::Value const &resolution) {
            // if there is more than 1 input, display descriptor right now
            // specifies one resolution value for both inputs. that may be
            // changed in the future
            Resolution res;
            res.video_inputs = resolution.get("video_inputs", 1).asInt();

            // Window bounds
            res.width = resolution["width"].asInt();
            res.height = resolution["height"].asInt();

            // Display mode - Default to horiz side by side unless we have
            // multiple video inputs, then default to full screen (? seems
            // logical but not strictly what the json schema specifies)
            res.display_mode =
                (res.video_inputs > 1 ? FULL_SCREEN : HORIZONTAL_SIDE_BY_SIDE);

            auto const &display_mode = resolution["display_mode"];
            if (display_mode.isString()) {
                const std::string display_mode_str = display_mode.asString();
                if ("horz_side_by_side" == display_mode_str) {
                    res.display_mode = HORIZONTAL_SIDE_BY_SIDE;
                } else if ("vert_side_by_side" == display_mode_str) {
                    res.display_mode = VERTICAL_SIDE_BY_SIDE;
                } else if ("full_screen" == display_mode_str) {
                    res.display_mode = FULL_SCREEN;
                } else {
                    OSVR_DEV_VERBOSE("DisplayDescriptor::parse(): WARNING: "
                                     "Unknown display mode string: "
                                     << display_mode_str << " (using default)");
                }
            }

            m_resolutions.push_back(res);
        }
Esempio n. 29
0
    PureClientContext::PureClientContext(const char appId[], const char host[],
                                         common::ClientContextDeleter del)
        : ::OSVR_ClientContextObject(appId, del), m_host(host) {

        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());
#define OSVR_USE_DEDUP
#ifdef OSVR_USE_DEDUP
        typedef common::DeduplicatingFunctionWrapper<Json::Value const &>
            DedupJsonFunction;
        m_systemComponent->registerReplaceTreeHandler(DedupJsonFunction(
            [&](Json::Value const &nodes) { m_handleReplaceTree(nodes); }));
#else
        // Just for testing purposes, figuring out why we end up looping too
        // much.
        m_systemComponent->registerReplaceTreeHandler(
            [&](Json::Value const &nodes, util::time::TimeValue const &) {
                m_handleReplaceTree(nodes);
            });
#endif
        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) {
            OSVR_DEV_VERBOSE(
                "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_gotTree) {
            m_update();
            std::this_thread::sleep_for(STARTUP_LOOP_SLEEP);
        }
        auto timeToStartup = (clock::now() - begin);
        OSVR_DEV_VERBOSE(
            "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_gotTree ? "have path tree" : "don't have path tree"));
    }
Esempio n. 30
0
        void DisplayDescriptor::parse(const std::string &display_description) {
            auto root = common::jsonParse(display_description);
            auto const &hmd = root["hmd"];
            {
                auto const &fov = hmd["field_of_view"];
                // Field of view
                m_monocularHorizontalFOV = util::Angle(
                    fov["monocular_horizontal"].asDouble() * util::degrees);
                m_monocularVerticalFOV = util::Angle(
                    fov["monocular_vertical"].asDouble() * util::degrees);
                m_overlapPercent =
                    fov.get("overlap_percent", 100).asDouble() / 100.0;
                m_pitchTilt = util::Angle(fov.get("pitch_tilt", 0).asDouble() *
                                          util::degrees);
            }
            {
                auto const &devprops = hmd["device"];
                // Device properties
                m_vendor = devprops["vendor"].asString();
                m_model = devprops["model"].asString();
                m_version = devprops["Version"].asString();
                m_note = devprops["Note"].asString();
            }
            {
                auto const &resolutions = hmd["resolutions"];
                if (resolutions.isNull()) {
                    OSVR_DEV_VERBOSE(
                        "DisplayDescriptor::parse(): ERROR: Couldn't "
                        "find resolutions array!");
                    throw DisplayDescriptorParseException(
                        "Couldn't find resolutions array.");
                }

                for (auto const &resolution : resolutions) {
                    m_processResolution(resolution);
                }

                if (m_resolutions.empty()) {
                    // We couldn't find any appropriate resolution entries
                    OSVR_DEV_VERBOSE(
                        "DisplayDescriptor::parse(): ERROR: Couldn't "
                        "find any appropriate resolutions.");
                    return;
                }
            }

            {
                auto const &rendering = hmd["rendering"];
                m_rightRoll = rendering.get("right_roll", 0).asDouble();
                m_leftRoll = rendering.get("left_roll", 0).asDouble();
            }
            {
                auto const &distortion = hmd["distortion"];
                m_distort.k1_red = distortion.get("k1_red", 0).asDouble();
                m_distort.k1_green = distortion.get("k1_green", 0).asDouble();
                m_distort.k1_blue = distortion.get("k1_blue", 0).asDouble();
            }
            {
                auto const &eyes = hmd["eyes"];
                if (eyes.isNull()) {
                    OSVR_DEV_VERBOSE("DisplayDescriptor::parse(): ERROR: "
                                     "Couldn't find eyes array!");
                    throw DisplayDescriptorParseException(
                        "Couldn't find eyes array.");
                }
                for (auto const &eye : eyes) {
                    EyeInfo e;
                    e.m_CenterProjX = eye.get("center_proj_x", 0.5).asDouble();
                    e.m_CenterProjY = eye.get("center_proj_y", 0.5).asDouble();
                    if (eye.isMember("rotate_180")) {
                        auto const& rot = eye["rotate_180"];
                        if (rot.isBool()) {
                            e.m_rotate180 = rot.asBool();
                        } else {
                            e.m_rotate180 = (rot.asInt() != 0);
                        }
                    }
                    m_eyes.push_back(e);
                }
            }
        }