Skip to content
This repository has been archived by the owner on Mar 1, 2024. It is now read-only.

Fix: controller indices from multiple peers would clash #165

Merged
merged 3 commits into from
Mar 20, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Frontend/library/src/DataChannel/InitialSettings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export class InitialSettings {
export class PixelStreamingSettings {
AllowPixelStreamingCommands?: boolean;
DisableLatencyTest?: boolean;
PlayerId?: number;
Belchy06 marked this conversation as resolved.
Show resolved Hide resolved
}

/**
Expand Down
44 changes: 41 additions & 3 deletions Frontend/library/src/Inputs/GamepadController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,14 @@ export class GamePadController {
*/
unregisterGamePadEvents() {
this.gamePadEventListenerTracker.unregisterAll();
for(const controller of this.controllers) {
if(controller.id !== undefined) {
this.onGamepadDisconnected(controller.id);
}
}
this.controllers = [];
this.onGamepadConnected = () => { /* */ };
this.onGamepadDisconnected = () => { /* */ };
}

/**
Expand All @@ -81,7 +88,8 @@ export class GamePadController {

const temp: Controller = {
currentState: gamepad,
prevState: gamepad
prevState: gamepad,
id: undefined
};

this.controllers.push(temp);
Expand All @@ -92,7 +100,8 @@ export class GamePadController {
'gamepad: ' + gamepad.id + ' connected',
6
);
this.requestAnimationFrame(() => this.updateStatus());
window.requestAnimationFrame(() => this.updateStatus());
this.onGamepadConnected();
}

/**
Expand All @@ -106,10 +115,12 @@ export class GamePadController {
'gamepad: ' + gamePadEvent.gamepad.id + ' disconnected',
6
);
const deletedController = this.controllers[gamePadEvent.gamepad.index];
delete this.controllers[gamePadEvent.gamepad.index];
this.controllers = this.controllers.filter(
(controller) => controller !== undefined
);
this.onGamepadDisconnected(deletedController.id);
}

/**
Expand Down Expand Up @@ -138,7 +149,8 @@ export class GamePadController {

// Iterate over multiple controllers in the case the multiple gamepads are connected
for (const controller of this.controllers) {
const controllerIndex = this.controllers.indexOf(controller);
// If we haven't received an id (possible if using an older version of UE), return to original functionality
const controllerIndex = (controller.id === undefined) ? this.controllers.indexOf(controller) : controller.id;
const currentState = controller.currentState;
for (let i = 0; i < controller.currentState.buttons.length; i++) {
const currentButton = controller.currentState.buttons[i];
Expand Down Expand Up @@ -217,8 +229,34 @@ export class GamePadController {
this.requestAnimationFrame(() => this.updateStatus());
}
}

onGamepadResponseReceived(gamepadId: number) {
for(const controller of this.controllers) {
if(controller.id === undefined) {
controller.id = gamepadId;
break;
}
}
}

/**
* Event to send the gamepadconnected message to the application
*/
onGamepadConnected() {
// Default Functionality: Do Nothing
}

/**
* Event to send the gamepaddisconnected message to the application
*/
// eslint-disable-next-line @typescript-eslint/no-unused-vars
onGamepadDisconnected(controllerIdx: number) {
// Default Functionality: Do Nothing
}
}



/**
* Additional types for Window and Navigator
*/
Expand Down
1 change: 1 addition & 0 deletions Frontend/library/src/Inputs/GamepadTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@
export interface Controller {
currentState: Gamepad;
prevState: Gamepad;
id: number | undefined;
}
3 changes: 2 additions & 1 deletion Frontend/library/src/Inputs/XRGamepadController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ export class XRGamepadController {
if (this.controllers[handedness] === undefined) {
this.controllers[handedness] = {
prevState: undefined,
currentState: undefined
currentState: undefined,
id: undefined
};
this.controllers[handedness].prevState =
WebXRUtils.deepCopyGamepad(source.gamepad);
Expand Down
12 changes: 12 additions & 0 deletions Frontend/library/src/UeInstanceMessage/StreamMessageController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,11 @@ export class StreamMessageController {
structure: ['uint8', 'uint16', 'uint16', 'uint8', 'uint8', 'uint8']
});
// Gamepad Input Messages. Range = 90..99
this.toStreamerMessages.add('GamepadConnected', {
id: 93,
byteLength: 0,
structure: []
Belchy06 marked this conversation as resolved.
Show resolved Hide resolved
});
this.toStreamerMessages.add('GamepadButtonPressed', {
id: 90,
byteLength: 3,
Expand All @@ -194,6 +199,12 @@ export class StreamMessageController {
// ctrlerId button analogValue
structure: ['uint8', 'uint8', 'double']
});
this.toStreamerMessages.add('GamepadDisconnected', {
id: 94,
byteLength: 1,
// ctrlerId
structure: ['uint8']
});

this.fromStreamerMessages.add('QualityControlOwnership', 0);
this.fromStreamerMessages.add('Response', 1);
Expand All @@ -208,6 +219,7 @@ export class StreamMessageController {
this.fromStreamerMessages.add('FileContents', 10);
this.fromStreamerMessages.add('TestEcho', 11);
this.fromStreamerMessages.add('InputControlOwnership', 12);
this.fromStreamerMessages.add('GamepadResponse', 13);
this.fromStreamerMessages.add('Protocol', 255);
}

Expand Down
38 changes: 38 additions & 0 deletions Frontend/library/src/WebRtcPlayer/WebRtcPlayerController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,11 @@ export class WebRtcPlayerController {
'InputControlOwnership',
(data: ArrayBuffer) => this.onInputControlOwnership(data)
);
this.streamMessageController.registerMessageHandler(
MessageDirection.FromStreamer,
'GamepadResponse',
(data: ArrayBuffer) => this.onGamepadResponse(data)
);
this.streamMessageController.registerMessageHandler(
MessageDirection.FromStreamer,
'Protocol',
Expand Down Expand Up @@ -582,6 +587,14 @@ export class WebRtcPlayerController {
data
)
);
this.streamMessageController.registerMessageHandler(
MessageDirection.ToStreamer,
'GamepadConnected',
() =>
this.sendMessageController.sendMessageToStreamer(
'GamepadConnected'
)
);
this.streamMessageController.registerMessageHandler(
MessageDirection.ToStreamer,
'GamepadButtonPressed',
Expand Down Expand Up @@ -609,6 +622,15 @@ export class WebRtcPlayerController {
data
)
);
this.streamMessageController.registerMessageHandler(
MessageDirection.ToStreamer,
'GamepadDisconnected',
(data: Array<number>) =>
this.sendMessageController.sendMessageToStreamer(
'GamepadDisconnected',
data
)
);
this.streamMessageController.registerMessageHandler(
MessageDirection.ToStreamer,
'XRHMDTransform',
Expand Down Expand Up @@ -852,6 +874,16 @@ export class WebRtcPlayerController {
this.pixelStreaming._onInputControlOwnership(inputControlOwnership);
}

/**
*
* @param message
*/
onGamepadResponse(message: ArrayBuffer) {
const responseString = new TextDecoder('utf-16').decode(message.slice(1));
const responseJSON = JSON.parse(responseString);
this.gamePadController.onGamepadResponseReceived(responseJSON.controllerId);
}

onAfkTriggered(): void {
this.afkController.onAfkClick();

Expand Down Expand Up @@ -1936,6 +1968,12 @@ export class WebRtcPlayerController {
this.gamePadController?.unregisterGamePadEvents();
if (isEnabled) {
this.gamePadController = this.inputClassesFactory.registerGamePad();
this.gamePadController.onGamepadConnected = () => {
this.streamMessageController.toStreamerHandlers.get('GamepadConnected')();
}
this.gamePadController.onGamepadDisconnected = (controllerIdx: number) => {
this.streamMessageController.toStreamerHandlers.get('GamepadDisconnected')([controllerIdx]);
}
}
}

Expand Down