/** * Checks every frame, whether controller inputs or other updates regarding a controller connection arrived and * uses them to properly set up connections and relay inputs to `ControllerInput` instances. */ void Update() { ConnectionUpdate updateBuffer; // buffer to store an inter-thread connection update message // For every update that has been received until this frame... while (_incomingConnectionUpdates.TryDequeue(out updateBuffer)) { // Perform a different action depending on the type of connection update... updateBuffer.Match(new ConnectionUpdate.Matcher() { // If a controller sets its player name, this means the connection still needs to be set up NameUpdate = update => HandleConnectionSetup(update.name, update.connectionId, update.websocketId), // If a regular message arrived from a controller, forward it to the corresponding `ControllerInput` instance MessageUpdate = update => { ControllerInput input; if (_clients.TryGetInputByConnectionId(update.connectionId, out input)) { input.HandleMessage(update.message); } else if (!(update.message is Message.NameMessage)) { LogError("Got a message from a connection which is not associated with any input. This should never happen and is a programming error."); } }, // If a controller connection disconnects / fails, reset the meta-data of this connection until we have // a new one and set the state of the `ControllerInput` instance to NotConnected. DisconnectUpdate = update => { ControllerInput input; if (_clients.TryGetInputByConnectionId(update.connectionId, out input)) { _clients.DeleteConnectionInfo(input.PlayerId, update.connectionId); input.SetStatus(ConnectionStatus.NotConnected); } } }); } }