-
Notifications
You must be signed in to change notification settings - Fork 148
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.
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)`
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>ViewPtr
s in m_devices
. See the descriptions of ServerControllerView
, ServerTrackerView
, and ServerHMDView
below.
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.
* `m_network_manager.startup()`
* `m_device_manager.startup()`
* `m_request_handler.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.
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.
This doesn't appear to do much.