Skip to content
This repository has been archived by the owner on May 3, 2021. It is now read-only.

PSMoveService Startup Walkthrough

Guido Sanchez edited this page Apr 29, 2017 · 1 revision

PSMoveService Startup Walkthrough

The only thing in the EntryPoint's main is the instantiation of a PSMoveService app object and a call to app.exec(). app.exec() handles the command-line arguments and then instantiates and "launches" a PSMoveServiceImpl object. "Launching" happens through PSMoveServiceImpl's '()' operator, which starts with a call to startup(), then in the application loop it calls update(), and finally shutdown(). Let's look at each step from initialization to shutdown.

Initialize PSMoveServiceImpl object.

PSMoveServiceImpl has relevant member variables (initialized in this order):

* `DeviceManager` `m_device_manager()`
* `ServerRequestHandler` `m_request_handler(&m_device_manager)`
* `ServerNetworkManager` `m_network_manager(&m_io_service, PSMOVE_SERVER_PORT, &m_request_handler)`

m_device_manager via DeviceManager::DeviceManager()

Relevant DeviceManager member variables, instantiated by constructor:

* `ControllerManager m_controller_manager`
* `TrackerManager m_tracker_manager`
* `HMDManager m_hmd_manager`

Each of these device-type managers is a child of DeviceTypeManager. Their constructors allocate an array of Server<device>ViewPtrs in m_devices. See the descriptions of ServerControllerView, ServerTrackerView, and ServerHMDView below.

m_request_handler via ServerRequestHandler::ServerRequestHandler(DeviceManager *m_device_manager)

ServerRequestHandler uses the PImpl idiom. ServerRequestHandlerImpl::ServerRequestHandlerImpl retains a reference to the device manager and initializes a t_connection_state_map m_connection_state_map. The m_connection_state_map maintains a list of connection states, one for each registered client. The connection state RequestConnectionState includes which device streams the client is tracking, and the stream info for those streams. TODO: TrackerStreamInfo and HMDStreamInfo

m_network_manager via ServerNetworkManager::ServerNetworkManager(boost::asio::io_service *io_service, unsigned port, ServerRequestHandler *request_handler)

ServerNetworkManager also uses the PImpl idiom and has singleton access. ServerNetworkManagerImpl::ServerNetworkManagerImpl([...]) maintains a reference to the request_handler, m_io_service, tcp and udp connection information, and a t_client_connection_map named m_connections. m_connections maps ints to an instance of ClientConnection, one for each connected client. ClientConnection maintains TCP and UDP connection state to a single client, handles async socket callbacks on the connection, and routes requests through the request handler. TODO: ClientConnection needs tracker and hmd data_frames.

PSMoveServiceImpl::startup()

* `m_network_manager.startup()`
* `m_device_manager.startup()`
* `m_request_handler.startup()`

m_network_manager.startup()

ServerNetworkManagerImpl::start_connection_accept() ClientConnection::create then add the id-connection mapping to m_connections. Then use m_tcp_acceptor to async get new tcp client with handler ServerNetworkManagerImpl::handle_tcp_accept. Call start_udp_receive_connection_id() which uses m_udp_socket to start an async read with handler ServerNetworkManagerImpl::handle_udp_read_connection_id.

ServerNetworkManagerImpl::handle_tcp_accept(ClientConnectionPtr connection, const boost::system::error_code& error) should always be called before handle_udp_read_connection_id because the client should always make a tcp connection before a udp connection. This tells the tcp connection->start() and start_connection_accept() again to accept another client.

ServerNetworkManagerImpl::handle_udp_read_connection_id(...) binds the remote endpoint to the UDP connection map. Then this sends an async result to the remote endpoint with handler ServerNetworkManagerImpl::handle_udp_write_connection_result, which eventually calls start_udp_receive_connection_id() to look for the next UDP client.

m_device_manager.startup()

DeviceManager::startup() calls each specific manager's .startup(). This should initialize any hardware communication services required. TODO: Implement TrackerManager::startup and HMDManager::startup() if needed.

ServerRequestHandler m_request_handler.startup()

This doesn't appear to do much.

Clone this wiki locally