Added options to server application and did some stuff for the application
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,3 +1,4 @@
|
|||||||
*.idea*
|
*.idea*
|
||||||
cmake-build-debug
|
cmake-build-debug
|
||||||
.idea/*
|
.idea/*
|
||||||
|
*__pycache__/*
|
||||||
|
|||||||
@@ -39,27 +39,10 @@ IF(CROSS_COMPILE)
|
|||||||
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
||||||
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
||||||
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
||||||
|
|
||||||
# SET(Boost_NO_SYSTEM_PATHS TRUE)
|
|
||||||
# SET(BOOST_ROOT "$ENV{HOME}/boost_1_64_0/")
|
|
||||||
# SET(BOOST_INCLUDEDIR "${RPI_ROOT}/rootfs/usr/include//boost_1_64_0/")
|
|
||||||
# SET(BOOST_LIBRARYDIR "$ENV{HOME}/boost_1_64_0/")
|
|
||||||
|
|
||||||
#SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --sysroot=${CMAKE_FIND_ROOT_PATH}")
|
|
||||||
#SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} --sysroot=${CMAKE_FIND_ROOT_PATH}")
|
|
||||||
#SET(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} --sysroot=${CMAKE_FIND_ROOT_PATH}")
|
|
||||||
|
|
||||||
# Search for programs only in the build host directories
|
|
||||||
#SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
|
||||||
|
|
||||||
# Search for libraries and headers only in the target directories
|
|
||||||
#SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
|
||||||
#SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
|
||||||
ENDIF(CROSS_COMPILE)
|
ENDIF(CROSS_COMPILE)
|
||||||
|
|
||||||
###################### START_CMAKE #######################
|
###################### START_CMAKE #######################
|
||||||
cmake_minimum_required(VERSION 3.0.1)
|
cmake_minimum_required(VERSION 3.0.1)
|
||||||
#cmake_minimum_required(VERSION 3.0.2)
|
|
||||||
project(FlippR-Driver VERSION 0.1.0)# LANGUAGES CXX)
|
project(FlippR-Driver VERSION 0.1.0)# LANGUAGES CXX)
|
||||||
|
|
||||||
#set easylogging flags
|
#set easylogging flags
|
||||||
|
|||||||
@@ -3,22 +3,22 @@ project(flippR_driver_networking)
|
|||||||
|
|
||||||
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/${OUTPUT_PATH}/cli)
|
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/${OUTPUT_PATH}/cli)
|
||||||
set(SOURCES
|
set(SOURCES
|
||||||
input/SocketHandler.cpp
|
input/InputSocketHandler.cpp
|
||||||
output/OutputRequestHandler.cpp
|
output/OutputRequestHandler.cpp
|
||||||
output/OutputRequestHandlerFactory.cpp
|
output/OutputRequestHandlerFactory.cpp
|
||||||
FlippRServer.cpp
|
FlippRServer.cpp)
|
||||||
)
|
|
||||||
|
|
||||||
add_executable(${PROJECT_NAME} ${SOURCES})
|
add_executable(${PROJECT_NAME} ${SOURCES})
|
||||||
|
|
||||||
target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_SOURCE_DIR}/include)
|
target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_SOURCE_DIR}/include)
|
||||||
|
target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_SOURCE_DIR}/src)
|
||||||
target_link_libraries(${PROJECT_NAME} PRIVATE FlippR-Driver)
|
target_link_libraries(${PROJECT_NAME} PRIVATE FlippR-Driver)
|
||||||
|
|
||||||
####################### POCO ##############################
|
####################### POCO ##############################
|
||||||
find_package(Poco REQUIRED COMPONENTS Foundation Net JSON )
|
find_package(Poco REQUIRED COMPONENTS Foundation Net JSON Util)
|
||||||
|
|
||||||
if(NOT Poco_FOUND)
|
if(NOT Poco_FOUND)
|
||||||
message(FATAL_ERROR, "Could not find libPoco")
|
message(FATAL_ERROR, "Could not find libPoco")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
target_link_libraries(${PROJECT_NAME} PUBLIC Poco::Foundation Poco::Net Poco::JSON)
|
target_link_libraries(${PROJECT_NAME} PUBLIC Poco::Foundation Poco::Net Poco::JSON Poco::Util)
|
||||||
|
|||||||
@@ -4,14 +4,17 @@
|
|||||||
|
|
||||||
#include "FlippRServer.h"
|
#include "FlippRServer.h"
|
||||||
#include "output/OutputRequestHandlerFactory.h"
|
#include "output/OutputRequestHandlerFactory.h"
|
||||||
|
#include "input/InputDriverFactory.h"
|
||||||
#include <DriverFactory.h>
|
#include "DriverFactory.h"
|
||||||
#include <output/OutputDriver.h>
|
|
||||||
#include <input/InputDriver.h>
|
|
||||||
|
|
||||||
#include <Poco/Net/SocketAddress.h>
|
#include <Poco/Net/SocketAddress.h>
|
||||||
#include <Poco/Net/ServerSocket.h>
|
#include <Poco/Net/ServerSocket.h>
|
||||||
#include <Poco/Net/HTTPServer.h>
|
#include <Poco/Net/HTTPServer.h>
|
||||||
|
#include <Poco/Util/HelpFormatter.h>
|
||||||
|
#include <Poco/JSON/Parser.h>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
@@ -24,28 +27,221 @@ namespace flippR_driver
|
|||||||
namespace networking
|
namespace networking
|
||||||
{
|
{
|
||||||
using namespace Poco::Net;
|
using namespace Poco::Net;
|
||||||
|
using namespace Poco::Util;
|
||||||
|
using namespace Poco::JSON;
|
||||||
|
using namespace Poco;
|
||||||
|
|
||||||
|
FlippRServer::FlippRServer() :
|
||||||
|
help_requested(false),
|
||||||
|
input_port(9980),
|
||||||
|
output_port(9981),
|
||||||
|
input_config("Not set"),
|
||||||
|
matrix_config("Not set"),
|
||||||
|
output_pin_config("Not set"),
|
||||||
|
lamp_config("Not set"),
|
||||||
|
solenoid_config("Not set"),
|
||||||
|
sound_config("Not set"),
|
||||||
|
display_config("Not set")
|
||||||
|
{
|
||||||
|
this->parse_server_config_file();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FlippRServer::parse_server_config_file()
|
||||||
|
{
|
||||||
|
std::ifstream config;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
config.open("server_config.json");
|
||||||
|
}
|
||||||
|
catch(const std::exception e)
|
||||||
|
{
|
||||||
|
logger().information("No config file specified.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Parser parser;
|
||||||
|
Object::Ptr json = parser.parse(config).extract<Object::Ptr>();
|
||||||
|
|
||||||
|
for(auto &config_json : json->getNames())
|
||||||
|
{
|
||||||
|
handle_config_file(config_json, json->get(config_json));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initially called before main.
|
||||||
|
*/
|
||||||
|
void FlippRServer::initialize(Application &self)
|
||||||
|
{
|
||||||
|
//Todo May restructure with subsystems
|
||||||
|
//make this one application and subsystems ServerApplications
|
||||||
|
|
||||||
|
|
||||||
|
this->initialize_output_driver();
|
||||||
|
//Todo initialize input server
|
||||||
|
|
||||||
|
//https://gist.github.com/NIPE-SYSTEMS/5a06428c0880ed7ff3cc4304be436e3e
|
||||||
|
ServerApplication::initialize(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FlippRServer::initialize_output_driver()
|
||||||
|
{
|
||||||
|
std::ifstream input_config_stream;
|
||||||
|
std::ifstream matrix_config_stream;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
input_config_stream.open(this->input_config);
|
||||||
|
matrix_config_stream.open(this->matrix_config);
|
||||||
|
}
|
||||||
|
catch(const std::exception& e)
|
||||||
|
{
|
||||||
|
logger().error(e.what());
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
//todo should use DriverFactory from input
|
||||||
|
this->input_driver = flippR_driver::input::InputDriverFactory::get_InputDriver(input_config_stream, matrix_config_stream);
|
||||||
|
}
|
||||||
|
|
||||||
int FlippRServer::main(const std::vector<std::string>& args)
|
int FlippRServer::main(const std::vector<std::string>& args)
|
||||||
{
|
{
|
||||||
if (!_helpRequested)
|
if(help_requested)
|
||||||
{
|
return Application::EXIT_OK;
|
||||||
unsigned short port = (unsigned short)
|
|
||||||
config().getInt("HTTPTimeServer.port", 9980);
|
|
||||||
|
|
||||||
|
std::unique_ptr<HTTPServer> output_server(this->build_output_server());
|
||||||
|
output_server->start();
|
||||||
|
|
||||||
// todo XDG_RUNTIME_DIR
|
std::unique_ptr<TCPServer>
|
||||||
SocketAddress address("/tmp/flippR_driver/S.flippR_driver");
|
|
||||||
ServerSocket svs(address);
|
waitForTerminationRequest();
|
||||||
|
this->output_driver->deactivate_all_lamps();
|
||||||
|
this->output_driver->deactivate_displays();
|
||||||
|
output_server->stop();
|
||||||
|
|
||||||
HTTPServer srv(new OutputRequestHandlerFactory(),
|
|
||||||
svs, new HTTPServerParams);
|
|
||||||
srv.start();
|
|
||||||
waitForTerminationRequest();
|
|
||||||
srv.stop();
|
|
||||||
}
|
|
||||||
return Application::EXIT_OK;
|
return Application::EXIT_OK;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
HTTPServer* FlippRServer::build_output_server()
|
||||||
|
{
|
||||||
|
unsigned short port = (unsigned short) config().getInt("HTTPTimeServer.port", this->output_port);
|
||||||
|
|
||||||
|
// todo XDG_RUNTIME_DIR
|
||||||
|
SocketAddress address("/tmp/flippR_driver/S.flippR_driver");
|
||||||
|
ServerSocket svs(address);
|
||||||
|
|
||||||
|
return new HTTPServer(new OutputRequestHandlerFactory(this->output_driver), svs, new HTTPServerParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void FlippRServer::defineOptions(OptionSet& options)
|
||||||
|
{
|
||||||
|
ServerApplication::defineOptions(options);
|
||||||
|
|
||||||
|
options.addOption(
|
||||||
|
Option("help", "h", "display argument help information")
|
||||||
|
.required(false)
|
||||||
|
.repeatable(false)
|
||||||
|
.callback(OptionCallback<FlippRServer>(
|
||||||
|
this, &FlippRServer::handle_help)));
|
||||||
|
|
||||||
|
options.addOption(Option("input-port", "i", "Define the port for the TCP-Input-Server, which represents the flipper inputs. Default 9980")
|
||||||
|
.required(false)
|
||||||
|
.repeatable(false)
|
||||||
|
.callback(OptionCallback<FlippRServer>(this, &FlippRServer::handle_config_file))
|
||||||
|
.argument("input-port", true));
|
||||||
|
|
||||||
|
options.addOption(Option("output-port", "o", "Define the port for the HTTP-Output-Server, which represents the flipper outputs. Default 9981")
|
||||||
|
.required(false)
|
||||||
|
.repeatable(false)
|
||||||
|
.callback(OptionCallback<FlippRServer>(this, &FlippRServer::handle_config_file))
|
||||||
|
.argument("output-port", true));
|
||||||
|
|
||||||
|
options.addOption(Option("input-config", "I", "Specify where the input-config file is located. Only needed when not in this folder.")
|
||||||
|
.required(this->input_config == "Not set")
|
||||||
|
.repeatable(false)
|
||||||
|
.callback(OptionCallback<FlippRServer>(this, &FlippRServer::handle_config_file))
|
||||||
|
.argument("input-config", true));
|
||||||
|
|
||||||
|
options.addOption(Option("matrix-config", "M", "Specify where the matrix-config file is located. Only needed when not in this folder.")
|
||||||
|
.required(this->matrix_config == "Not set")
|
||||||
|
.repeatable(false)
|
||||||
|
.callback(OptionCallback<FlippRServer>(this, &FlippRServer::handle_config_file))
|
||||||
|
.argument("matric-config", true));
|
||||||
|
|
||||||
|
options.addOption(Option("output-pin-config", "O", "Specify where the matrix-config file is located. Only needed when not in this folder.")
|
||||||
|
.required(this->output_pin_config == "Not set")
|
||||||
|
.repeatable(false)
|
||||||
|
.callback(OptionCallback<FlippRServer>(this, &FlippRServer::handle_config_file))
|
||||||
|
.argument("output-pin-config", true));
|
||||||
|
|
||||||
|
options.addOption(Option("lamp-config", "L", "Specify where the lamp-config file is located. Only needed when not in this folder.")
|
||||||
|
.required(this->lamp_config == "Not set")
|
||||||
|
.repeatable(false)
|
||||||
|
.callback(OptionCallback<FlippRServer>(this, &FlippRServer::handle_config_file))
|
||||||
|
.argument("lamp-config", true));
|
||||||
|
|
||||||
|
options.addOption(Option("solenoid-config", "N", "Specify where the solenoid-config file is located. Only needed when not in this folder.")
|
||||||
|
.required(this->solenoid_config == "Not set")
|
||||||
|
.repeatable(false)
|
||||||
|
.callback(OptionCallback<FlippRServer>(this, &FlippRServer::handle_config_file))
|
||||||
|
.argument("solenoid-config", true));
|
||||||
|
|
||||||
|
options.addOption(Option("sound-config", "S", "Specify where the sound-config file is located. Only needed when not in this folder.")
|
||||||
|
.required(this->sound_config == "Not set")
|
||||||
|
.repeatable(false)
|
||||||
|
.callback(OptionCallback<FlippRServer>(this, &FlippRServer::handle_config_file))
|
||||||
|
.argument("sound-config", true));
|
||||||
|
|
||||||
|
options.addOption(Option("display-config", "D", "Specify where the display-config file is located. Only needed when not in this folder.")
|
||||||
|
.required(this->display_config == "Not set")
|
||||||
|
.repeatable(false)
|
||||||
|
.callback(OptionCallback<FlippRServer>(this, &FlippRServer::handle_config_file))
|
||||||
|
.argument("display-config", true));
|
||||||
|
}
|
||||||
|
|
||||||
|
void FlippRServer::handle_config_file(const std::string &name, const std::string &value)
|
||||||
|
{
|
||||||
|
if(name == "input-config")
|
||||||
|
this->input_config = value;
|
||||||
|
else if(name == "matrix-config")
|
||||||
|
this->matrix_config = value;
|
||||||
|
else if(name == "output-pin-config")
|
||||||
|
this->output_pin_config = value;
|
||||||
|
else if(name == "lamp-config")
|
||||||
|
this->lamp_config = value;
|
||||||
|
else if(name == "solenoid-config")
|
||||||
|
this->solenoid_config = value;
|
||||||
|
else if(name == "sound-config")
|
||||||
|
this->sound_config = value;
|
||||||
|
else if(name == "display-config")
|
||||||
|
this->display_config = value;
|
||||||
|
else if(name == "input-port")
|
||||||
|
this->input_port = std::stoi(value);
|
||||||
|
else if(name == "output-port")
|
||||||
|
this->output_port = std::stoi(value);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
logger().information("Configuration \"" + name + "\" is not known.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
logger().information("Set " + name + " to " + value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FlippRServer::handle_help(const std::string& name, const std::string& value)
|
||||||
|
{
|
||||||
|
Poco::Util::HelpFormatter helpFormatter(options());
|
||||||
|
helpFormatter.setCommand(commandName());
|
||||||
|
helpFormatter.setUsage("OPTIONS");
|
||||||
|
helpFormatter.setHeader(
|
||||||
|
"The FlippR-Server, appropriate config-files must either be located in the actual folder\
|
||||||
|
or the paths must be specified by commandline options. \
|
||||||
|
The config file paths as well as the port settings can be specified in a a file server_config.json");
|
||||||
|
helpFormatter.format(std::cout);
|
||||||
|
stopOptionsProcessing();
|
||||||
|
help_requested = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,7 +4,12 @@
|
|||||||
|
|
||||||
#ifndef FLIPPR_DRIVER_FLIPPRSERVER_H
|
#ifndef FLIPPR_DRIVER_FLIPPRSERVER_H
|
||||||
#define FLIPPR_DRIVER_FLIPPRSERVER_H
|
#define FLIPPR_DRIVER_FLIPPRSERVER_H
|
||||||
|
|
||||||
|
#include "output/OutputDriver.h"
|
||||||
|
#include "input/InputDriver.h"
|
||||||
|
|
||||||
#include <Poco/Util/ServerApplication.h>
|
#include <Poco/Util/ServerApplication.h>
|
||||||
|
#include <Poco/Net/HTTPServer.h>
|
||||||
|
|
||||||
namespace flippR_driver
|
namespace flippR_driver
|
||||||
{
|
{
|
||||||
@@ -13,7 +18,43 @@ namespace networking
|
|||||||
|
|
||||||
class FlippRServer : public Poco::Util::ServerApplication
|
class FlippRServer : public Poco::Util::ServerApplication
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
FlippRServer();
|
||||||
|
|
||||||
|
int main(const std::vector<std::string>& args);
|
||||||
|
|
||||||
|
void initialize(Poco::Util::Application& self);
|
||||||
|
|
||||||
|
void defineOptions(Poco::Util::OptionSet& options);
|
||||||
|
|
||||||
|
void handle_set_input_port(const std::string &name, const std::string &port);
|
||||||
|
void handle_set_output_port(const std::string &name, const std::string &port);
|
||||||
|
void handle_help(const std::string &name, const std::string &port);
|
||||||
|
void handle_config_file(const std::string &name, const std::string &value);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void initialize_output_driver();
|
||||||
|
void parse_server_config_file();
|
||||||
|
|
||||||
|
Poco::Net::HTTPServer* build_output_server();
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
int input_port;
|
||||||
|
int output_port;
|
||||||
|
|
||||||
|
bool help_requested;
|
||||||
|
|
||||||
|
std::string input_config;
|
||||||
|
std::string matrix_config;
|
||||||
|
std::string output_pin_config;
|
||||||
|
std::string lamp_config;
|
||||||
|
std::string solenoid_config;
|
||||||
|
std::string sound_config;
|
||||||
|
std::string display_config;
|
||||||
|
|
||||||
|
std::shared_ptr<input::InputDriver> input_driver;
|
||||||
|
std::shared_ptr<output::OutputDriver> output_driver;
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
* Author: Andreas Schneider, Johannes Wendel, Jonas Zeunert
|
* Author: Andreas Schneider, Johannes Wendel, Jonas Zeunert
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "SocketHandler.h"
|
#include "InputSocketHandler.h"
|
||||||
|
|
||||||
|
|
||||||
using Poco::Net::StreamSocket;
|
using Poco::Net::StreamSocket;
|
||||||
@@ -21,16 +21,14 @@ namespace networking
|
|||||||
namespace input
|
namespace input
|
||||||
{
|
{
|
||||||
|
|
||||||
SocketHandler::SocketHandler(StreamSocket streamSocket, std::shared_ptr<InputDriver> inputDriver) :
|
InputSocketHandler::InputSocketHandler(StreamSocket streamSocket, std::shared_ptr<InputDriver> inputDriver) :
|
||||||
TCPServerConnection(streamSocket),
|
TCPServerConnection(streamSocket),
|
||||||
EventHandler(inputDriver)
|
EventHandler(inputDriver)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void SocketHandler::run()
|
void InputSocketHandler::run()
|
||||||
{
|
{
|
||||||
StreamSocket& streamSocket = socket(); // todo ?
|
|
||||||
|
|
||||||
while(true)
|
while(true)
|
||||||
{
|
{
|
||||||
Event event = this->queue->pop();
|
Event event = this->queue->pop();
|
||||||
@@ -42,11 +40,11 @@ void SocketHandler::run()
|
|||||||
|
|
||||||
std::string str = event.getJsonString();
|
std::string str = event.getJsonString();
|
||||||
|
|
||||||
streamSocket.sendBytes(str.c_str(), str.length());
|
this->socket().sendBytes(str.c_str(), str.length());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SocketHandler::handle(Event &event)
|
void InputSocketHandler::handle(Event &event)
|
||||||
{
|
{
|
||||||
this->queue->push(event);
|
this->queue->push(event);
|
||||||
}
|
}
|
||||||
@@ -22,16 +22,17 @@ namespace networking
|
|||||||
{
|
{
|
||||||
namespace input
|
namespace input
|
||||||
{
|
{
|
||||||
class SocketHandler : public Poco::Net::TCPServerConnection, flippR_driver::input::EventHandler
|
|
||||||
|
class InputSocketHandler : public Poco::Net::TCPServerConnection, flippR_driver::input::EventHandler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SocketHandler(Poco::Net::StreamSocket streamSocket, std::shared_ptr<flippR_driver::input::InputDriver> input_driver);
|
InputSocketHandler(Poco::Net::StreamSocket streamSocket, std::shared_ptr<flippR_driver::input::InputDriver> input_driver);
|
||||||
|
|
||||||
void run() override;
|
void run() override;
|
||||||
void handle(flippR_driver::input::Event &event) override;
|
void handle(flippR_driver::input::Event &event) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
flippR_driver::utility::IBlockingQueue<flippR_driver::input::Event>* queue;
|
utility::IBlockingQueue<flippR_driver::input::Event>* queue;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user