<commit_before>/** @file
    @brief Implementation

    @date 2014

    @author
    Sensics, Inc.
    <http://sensics.com/osvr>
*/

// Copyright 2014 Sensics, Inc.
//
// All rights reserved.
//
// (Final version intended to be licensed under
// the Apache License, Version 2.0)

// Internal Includes
#include "VRPNContext.h"
#include "RouterPredicates.h"
#include "RouterTransforms.h"
#include "ImagingRouter.h"
#include "VRPNAnalogRouter.h"
#include "VRPNButtonRouter.h"
#include "VRPNTrackerRouter.h"
#include <osvr/Util/ClientCallbackTypesC.h>
#include <osvr/Client/ClientContext.h>
#include <osvr/Client/ClientInterface.h>
#include <osvr/Util/Verbosity.h>
#include <osvr/Transform/JSONTransformVisitor.h>
#include <osvr/Transform/ChangeOfBasis.h>
#include <osvr/Common/CreateDevice.h>
#include <osvr/Common/SystemComponent.h>

#include <osvr/Client/display_json.h>

// Library/third-party includes
#include <json/value.h>
#include <json/reader.h>

#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/classification.hpp>

// Standard includes
#include <cstring>

namespace osvr {
namespace client {
    RouterEntry::~RouterEntry() {}

    VRPNContext::VRPNContext(const char appId[], const char host[])
        : ::OSVR_ClientContextObject(appId), m_host(host) {

        std::string sysDeviceName =
            std::string(common::SystemComponent::deviceName()) + "@" + m_host;
        /// Get connection, forcing a re-open for improved thread-safety.
        m_conn =
            vrpn_get_connection_by_name(sysDeviceName.c_str(), nullptr, nullptr,
                                        nullptr, nullptr, nullptr, true);
        m_conn->removeReference(); // Remove extra reference.

        /// Create the system client device.
        m_systemDevice = common::createClientDevice(sysDeviceName, m_conn);
        m_systemComponent =
            m_systemDevice->addComponent(common::SystemComponent::create());
        m_systemComponent->registerRoutesHandler(
            &VRPNContext::m_handleRoutingMessage, static_cast<void *>(this));

        setParameter("/display",
                     std::string(display_json, sizeof(display_json)));
    }

    VRPNContext::~VRPNContext() {}

    int VRPNContext::m_handleRoutingMessage(void *userdata,
                                            vrpn_HANDLERPARAM p) {
        VRPNContext *self = static_cast<VRPNContext *>(userdata);
        self->m_replaceRoutes(std::string(p.buffer, p.payload_len));
        return 0;
    }
    static const char SOURCE_KEY[] = "source";
    static const char DESTINATION_KEY[] = "destination";
    static const char SENSOR_KEY[] = "sensor";
    static const char TRACKER_KEY[] = "tracker";
    static const char IMAGING_KEY[] = "imaging";
    void VRPNContext::m_replaceRoutes(std::string const &routes) {

        Json::Value root;
        Json::Reader reader;
        if (!reader.parse(routes, root)) {
            throw std::runtime_error("JSON parse error: " +
                                     reader.getFormattedErrorMessages());
        }
        OSVR_DEV_VERBOSE("Replacing routes: had "
                         << m_routers.size() << ", received " << root.size());
        m_routers.clear();
        for (Json::ArrayIndex i = 0, e = root.size(); i < e; ++i) {
            Json::Value route = root[i];

            std::string dest = route[DESTINATION_KEY].asString();

            Json::Value src = route[SOURCE_KEY];
            if (src.isString()) {
                m_handleStringRouteEntry(dest, src.asString());
            } else {
                m_handleTrackerRouteEntry(dest, src);
            }
        }

#define OSVR_HYDRA_BUTTON(SENSOR, NAME)                                        \
    m_addButtonRouter("org_opengoggles_bundled_Multiserver/RazerHydra0",       \
                      "/controller/left/" NAME, SensorPredicate(SENSOR));      \
    m_addButtonRouter("org_opengoggles_bundled_Multiserver/RazerHydra0",       \
                      "/controller/right/" NAME, SensorPredicate(SENSOR + 8))

        OSVR_HYDRA_BUTTON(0, "middle");
        OSVR_HYDRA_BUTTON(1, "1");
        OSVR_HYDRA_BUTTON(2, "2");
        OSVR_HYDRA_BUTTON(3, "3");
        OSVR_HYDRA_BUTTON(4, "4");
        OSVR_HYDRA_BUTTON(5, "bumper");
        OSVR_HYDRA_BUTTON(6, "joystick/button");

#undef OSVR_HYDRA_BUTTON

#define OSVR_HYDRA_ANALOG(SENSOR, NAME)                                        \
    m_addAnalogRouter("org_opengoggles_bundled_Multiserver/RazerHydra0",       \
                      "/controller/left/" NAME, SENSOR);                       \
    m_addAnalogRouter("org_opengoggles_bundled_Multiserver/RazerHydra0",       \
                      "/controller/right/" NAME, SENSOR + 3)

        OSVR_HYDRA_ANALOG(0, "joystick/x");
        OSVR_HYDRA_ANALOG(1, "joystick/y");
        OSVR_HYDRA_ANALOG(2, "trigger");

#undef OSVR_HYDRA_ANALOG

        OSVR_DEV_VERBOSE("Now have " << m_routers.size() << " routes.");
    }

    void VRPNContext::m_handleTrackerRouteEntry(std::string const &dest,
                                                Json::Value src) {

        boost::optional<int> sensor;
        transform::JSONTransformVisitor xformParse(src);
        Json::Value srcLeaf = xformParse.getLeaf();
        std::string srcDevice = srcLeaf[TRACKER_KEY].asString();
        // OSVR_DEV_VERBOSE("Source device: " << srcDevice);
        srcDevice.erase(begin(srcDevice)); // remove leading slash
        if (srcLeaf.isMember(SENSOR_KEY)) {
            sensor = srcLeaf[SENSOR_KEY].asInt();
        }

        m_addTrackerRouter(srcDevice.c_str(), dest.c_str(), sensor,
                           xformParse.getTransform());
    }
    void VRPNContext::m_handleStringRouteEntry(std::string const &dest,
                                               std::string src) {
        std::vector<std::string> components;

        /// @todo replace literal with getPathSeparator
        boost::algorithm::split(components, src,
                                boost::algorithm::is_any_of("/"));
        if (!components.empty()) {
            if (components.front().empty()) {
                components.erase(begin(components));
            }
        }
        if (components.size() < 4) {
            OSVR_DEV_VERBOSE("Could not parse source for route, skipping: "
                             << src << " => " << dest);
            return;
        }

        std::string deviceName =
            components[0] + "/" + components[1] + "@" + m_host;
        std::reverse(begin(components), end(components));
        components.pop_back();
        components.pop_back();

        std::string interfaceType = components.back();
        components.pop_back();
        if (interfaceType == "imaging") {
            OSVR_DEV_VERBOSE("Adding imaging route for " << dest);
            m_routers.emplace_back(
                new ImagingRouter(this, m_conn, deviceName, components, dest));<commit_msg>Move constants closer to their usage and actually use one of them that went unused.<commit_after>/** @file
    @brief Implementation

    @date 2014

    @author
    Sensics, Inc.
    <http://sensics.com/osvr>
*/

// Copyright 2014 Sensics, Inc.
//
// All rights reserved.
//
// (Final version intended to be licensed under
// the Apache License, Version 2.0)

// Internal Includes
#include "VRPNContext.h"
#include "RouterPredicates.h"
#include "RouterTransforms.h"
#include "ImagingRouter.h"
#include "VRPNAnalogRouter.h"
#include "VRPNButtonRouter.h"
#include "VRPNTrackerRouter.h"
#include <osvr/Util/ClientCallbackTypesC.h>
#include <osvr/Client/ClientContext.h>
#include <osvr/Client/ClientInterface.h>
#include <osvr/Util/Verbosity.h>
#include <osvr/Transform/JSONTransformVisitor.h>
#include <osvr/Transform/ChangeOfBasis.h>
#include <osvr/Common/CreateDevice.h>
#include <osvr/Common/SystemComponent.h>

#include <osvr/Client/display_json.h>

// Library/third-party includes
#include <json/value.h>
#include <json/reader.h>

#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/classification.hpp>

// Standard includes
#include <cstring>

namespace osvr {
namespace client {
    RouterEntry::~RouterEntry() {}

    VRPNContext::VRPNContext(const char appId[], const char host[])
        : ::OSVR_ClientContextObject(appId), m_host(host) {

        std::string sysDeviceName =
            std::string(common::SystemComponent::deviceName()) + "@" + m_host;
        /// Get connection, forcing a re-open for improved thread-safety.
        m_conn =
            vrpn_get_connection_by_name(sysDeviceName.c_str(), nullptr, nullptr,
                                        nullptr, nullptr, nullptr, true);
        m_conn->removeReference(); // Remove extra reference.

        /// Create the system client device.
        m_systemDevice = common::createClientDevice(sysDeviceName, m_conn);
        m_systemComponent =
            m_systemDevice->addComponent(common::SystemComponent::create());
        m_systemComponent->registerRoutesHandler(
            &VRPNContext::m_handleRoutingMessage, static_cast<void *>(this));

        setParameter("/display",
                     std::string(display_json, sizeof(display_json)));
    }

    VRPNContext::~VRPNContext() {}

    int VRPNContext::m_handleRoutingMessage(void *userdata,
                                            vrpn_HANDLERPARAM p) {
        VRPNContext *self = static_cast<VRPNContext *>(userdata);
        self->m_replaceRoutes(std::string(p.buffer, p.payload_len));
        return 0;
    }
    static const char SOURCE_KEY[] = "source";
    static const char DESTINATION_KEY[] = "destination";
    void VRPNContext::m_replaceRoutes(std::string const &routes) {

        Json::Value root;
        Json::Reader reader;
        if (!reader.parse(routes, root)) {
            throw std::runtime_error("JSON parse error: " +
                                     reader.getFormattedErrorMessages());
        }
        OSVR_DEV_VERBOSE("Replacing routes: had "
                         << m_routers.size() << ", received " << root.size());
        m_routers.clear();
        for (Json::ArrayIndex i = 0, e = root.size(); i < e; ++i) {
            Json::Value route = root[i];

            std::string dest = route[DESTINATION_KEY].asString();

            Json::Value src = route[SOURCE_KEY];
            if (src.isString()) {
                m_handleStringRouteEntry(dest, src.asString());
            } else {
                m_handleTrackerRouteEntry(dest, src);
            }
        }

#define OSVR_HYDRA_BUTTON(SENSOR, NAME)                                        \
    m_addButtonRouter("org_opengoggles_bundled_Multiserver/RazerHydra0",       \
                      "/controller/left/" NAME, SensorPredicate(SENSOR));      \
    m_addButtonRouter("org_opengoggles_bundled_Multiserver/RazerHydra0",       \
                      "/controller/right/" NAME, SensorPredicate(SENSOR + 8))

        OSVR_HYDRA_BUTTON(0, "middle");
        OSVR_HYDRA_BUTTON(1, "1");
        OSVR_HYDRA_BUTTON(2, "2");
        OSVR_HYDRA_BUTTON(3, "3");
        OSVR_HYDRA_BUTTON(4, "4");
        OSVR_HYDRA_BUTTON(5, "bumper");
        OSVR_HYDRA_BUTTON(6, "joystick/button");

#undef OSVR_HYDRA_BUTTON

#define OSVR_HYDRA_ANALOG(SENSOR, NAME)                                        \
    m_addAnalogRouter("org_opengoggles_bundled_Multiserver/RazerHydra0",       \
                      "/controller/left/" NAME, SENSOR);                       \
    m_addAnalogRouter("org_opengoggles_bundled_Multiserver/RazerHydra0",       \
                      "/controller/right/" NAME, SENSOR + 3)

        OSVR_HYDRA_ANALOG(0, "joystick/x");
        OSVR_HYDRA_ANALOG(1, "joystick/y");
        OSVR_HYDRA_ANALOG(2, "trigger");

#undef OSVR_HYDRA_ANALOG

        OSVR_DEV_VERBOSE("Now have " << m_routers.size() << " routes.");
    }

    static const char SENSOR_KEY[] = "sensor";
    static const char TRACKER_KEY[] = "tracker";
    void VRPNContext::m_handleTrackerRouteEntry(std::string const &dest,
                                                Json::Value src) {

        boost::optional<int> sensor;
        transform::JSONTransformVisitor xformParse(src);
        Json::Value srcLeaf = xformParse.getLeaf();
        std::string srcDevice = srcLeaf[TRACKER_KEY].asString();
        // OSVR_DEV_VERBOSE("Source device: " << srcDevice);
        srcDevice.erase(begin(srcDevice)); // remove leading slash
        if (srcLeaf.isMember(SENSOR_KEY)) {
            sensor = srcLeaf[SENSOR_KEY].asInt();
        }

        m_addTrackerRouter(srcDevice.c_str(), dest.c_str(), sensor,
                           xformParse.getTransform());
    }

    static const char IMAGING_NAME[] = "imaging";
    void VRPNContext::m_handleStringRouteEntry(std::string const &dest,
                                               std::string src) {
        std::vector<std::string> components;

        /// @todo replace literal with getPathSeparator
        boost::algorithm::split(components, src,
                                boost::algorithm::is_any_of("/"));
        if (!components.empty()) {
            if (components.front().empty()) {
                components.erase(begin(components));
            }
        }
        if (components.size() < 4) {
            OSVR_DEV_VERBOSE("Could not parse source for route, skipping: "
                             << src << " => " << dest);
            return;
        }

        std::string deviceName =
            components[0] + "/" + components[1] + "@" + m_host;
        std::reverse(begin(components), end(components));
        components.pop_back();
        components.pop_back();

        std::string interfaceType = components.back();
        components.pop_back();
        if (interfaceType == IMAGING_NAME) {
            OSVR_DEV_VERBOSE("Adding imaging route for " << dest);
            m_routers.emplace_back(
                new ImagingRouter(this, m_conn, deviceName, components, dest));
{'fraction_non_alphanumeric': 0.12418394432886147, 'fraction_numerical': 0.005021881053160198, 'mean_word_length': 2.3598457459628825, 'pattern_counts': {'":': 0, '<': 85, '<?xml version=': 0, '>': 51, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 22, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '222858', 'n_tokens_mistral': 4286, 'n_tokens_neox': 4115, 'n_words': 739}