Skip to content

Commit

Permalink
refacto apimanager, adding category + adding fullscren api
Browse files Browse the repository at this point in the history
  • Loading branch information
jparez committed Jun 25, 2024
1 parent f4cdb19 commit 1cb706b
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 71 deletions.
70 changes: 39 additions & 31 deletions src/APIManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,61 +6,64 @@ module.exports = class APIManager {
this.apiFunctions = {};

// record fn to send data to instance
this.registerFunction(
'sendData',
(json) => {
this.registerFunction({
name: 'sendData',
category: 'VM_communication',
fn: (json) => {
this.instance.sendEvent(json);
},
'send data to WS messages of player, must be a JSON object. Example: {type: "MOUSE_PRESS", x: 100, y: 100}',
);
description: `send data to WS messages of player, must be a JSON object.
Example: {type: "MOUSE_PRESS", x: 100, y: 100}`,
});

// record fn to get registered functions
this.registerFunction(
'getRegisteredFunctions',
() => this.getRegisteredFunctions(),
'list all registered functions',
);
this.registerFunction({
name: 'getRegisteredFunctions',
category: 'utils',
fn: () => this.getRegisteredFunctions(),
description: 'list all registered functions',
});

// record fn to get registered functions
this.registerFunction(
'addEventListener',
(event, fn) => {
return this.addEventListener(event, fn);
this.registerFunction({
name: 'addEventListener',
category: 'VM_communication',
fn: (event, fn) => {
return this.instance.addEventListener(event, fn);
},
'attach event listener to WS messages of player',
);
description: 'attach event listener to WS messages of player',
});

// record fn to disconnect from the instance
this.registerFunction(
'disconnect',
() => {
this.registerFunction({
name: 'disconnect',
category: 'VM_communication',
fn: () => {
this.instance.disconnect();
},
'disconnect from the instance',
);
description: 'disconnect from the instance',
});
}

registerFunction(name, fn, description = '') {
if (this.apiFunctions[name]) {
throw new Error(`Function ${name} is already registered.`);
registerFunction({name, category = 'global', fn, description = ''}) {
if (this.apiFunctions[`${category}_${name}`]) {
throw new Error(`Function ${name} for category ${category} is already registered.`);
}
this.apiFunctions[name] = {
this.apiFunctions[`${category}_${name}`] = {
fn,
category,
description,
name,
};
}
addEventListener(event, fn) {
// expose listener to ws instance
this.instance.registerEventCallback(event, fn);
}

/**
* Get exposed API description
* @returns {Array} list of api description {apiName: string, apiDescription: string}
*/
getRegisteredFunctions() {
const exposedFunctionsDescription = Object.entries(this.apiFunctions).reduce((acc, val) => {
acc[val[0]] = val[1].description;
acc[val[1].name] = val[1].description;
return acc;
}, {});
return exposedFunctionsDescription;
Expand All @@ -72,7 +75,12 @@ module.exports = class APIManager {
*/
getExposedApiFunctions() {
const exposedFunctions = Object.entries(this.apiFunctions).reduce((acc, val) => {
acc[val[0]] = val[1].fn;
const {name, category, fn} = val[1];

if (!acc[category]) {
acc[category] = {};
}
acc[category][name] = fn;
return acc;
}, {});
return exposedFunctions;
Expand Down
12 changes: 12 additions & 0 deletions src/plugins/Fullscreen.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,18 @@ module.exports = class Fullscreen {
this.instance.addListener(document, 'fullscreenchange', this.onFullscreenEvent.bind(this), false);
}

this.instance.apiManager.registerFunction({
name: 'fullsreen',
category: 'video',
fn: () => {
if (this.fullscreenEnabled()) {
this.exitFullscreen();
} else {
this.goFullscreen(this.instance.root);
}
},
description: 'toggle fullscreen mode',
});
// Display widget
this.renderToolbarButton();
}
Expand Down
69 changes: 35 additions & 34 deletions src/plugins/KeyboardMapping.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ const NEW_SOUL_KNIGHT = {
],
};

// eslint-disable-next-line no-unused-vars
const MINECRAFT = {
dPad: [
{
Expand Down Expand Up @@ -147,7 +148,7 @@ const MINECRAFT = {
},
],
};

// eslint-disable-next-line no-unused-vars
const SUBWAY_SURFERS = {
swipe: [
{
Expand Down Expand Up @@ -272,9 +273,10 @@ module.exports = class KeyboardMapping {
// register api function

// set config file
this.instance.apiManager.registerFunction(
'setConfigFile',
(config) => {
this.instance.apiManager.registerFunction({
name: 'setConfig',
category: 'keyMapping',
fn: (config) => {
// check it's a valid JSON
try {
this.state.mappedKeysConfig = JSON.parse(JSON.stringify(config));
Expand All @@ -283,33 +285,25 @@ module.exports = class KeyboardMapping {
}
this.state.config = config;
},
'Submit a config for mapping keys',
);
description: 'Submit a config for mapping keys',
});

// active trace when click on screen
this.instance.apiManager.registerFunction(
'activeKeyMappingDebug',
(isTraceActivate = false, isGridActivate = false) => {
if (isTraceActivate) {
this.activateTrace(true);
} else {
this.activateTrace(false);
}
if (isGridActivate) {
this.activateGrid(true);
} else {
this.activateGrid(false);
}
this.instance.apiManager.registerFunction({
name: 'activeKeyMappingDebug',
category: 'keyMapping',
fn: (isTraceActivate = false, isGridActivate = false) => {
this.activateTrace(isTraceActivate);
this.activateGrid(isGridActivate);
},
`Activate debug mode for key mapping. the first parameter activate
description: `Activate debug mode for key mapping. the first parameter activate
feature "click on screen add a div with x, y and x%, y%coordonates.\n
The second parameter activate a grid on the screen to help mapping keys.
10% of the screen width and height.`,
);
});

// load default config to test purpose TODO delete for production
this.state.mappedKeysConfig = NEW_SOUL_KNIGHT;

}

sendMultiTouch() {
Expand Down Expand Up @@ -456,8 +450,8 @@ module.exports = class KeyboardMapping {
if (this.dPadPushed.includes(keyConfig.groupId)) {
touchPoints.push(dPadT);
} else {
touchPointsBeforeMove.push(dPadT);
movePoints.push(dPadM);
touchPointsBeforeMove.push(dPadT);
movePoints.push(dPadM);
// also add the groupId to the dPadPushed array to keep track of the dPad pressed
this.dPadPushed.push(keyConfig.groupId);
}
Expand Down Expand Up @@ -580,15 +574,17 @@ module.exports = class KeyboardMapping {
],
};
this.instance.sendEvent(json);
/*
* Array.from(Array(2).keys()).forEach(() => {
* this.instance.sendEvent({type: 'ACCELEROMETER', x: -100, y: -10, z: 0});
* this.instance.sendEvent({type: 'ACCELEROMETER', x: 100, y: -10, z: 0});
* this.instance.sendEvent({type: 'ACCELEROMETER', x: 200, y: 0, z: 0});
* });
*/
return;
Array.from(Array(2).keys()).forEach(() => {
this.instance.sendEvent({type: 'ACCELEROMETER', x: -100, y: -10, z: 0});
this.instance.sendEvent({type: 'ACCELEROMETER', x: 100, y: -10, z: 0});
this.instance.sendEvent({type: 'ACCELEROMETER', x: 200, y: 0, z: 0});
});
}

activateTrace(isActive = true) {
activateTrace(isActive) {
const debug = (event) => {
// create div with x, y coordonates where this.instantce.root element is clicked
const xCoor = this.instance.coordinateUtils.getXCoordinate(event);
Expand All @@ -602,7 +598,7 @@ module.exports = class KeyboardMapping {
div.style.padding = '10px';
div.style.background = 'red';

//adding x and y coordonates of this.instantce.root element to the div create above
// adding x and y coordonates of this.instantce.root element to the div create above
const videoSize = this.instance.video.getBoundingClientRect();

const xPercent = 100 / ((videoSize.width * this.instance.coordinateUtils.getXRatio()) / xCoor);
Expand Down Expand Up @@ -630,12 +626,15 @@ module.exports = class KeyboardMapping {
if (isActive) {
this.removeDebugListener = this.instance.addListener(window, ['click'], debug.bind(this));
} else {
this.removeDebugListener && this.removeDebugListener();
// eslint-disable-next-line no-unused-expressions
if (this.removeDebugListener) {
this.removeDebugListener();
}
this.removeDebugListener = null;
}
}

activateGrid(isActive = true) {
activateGrid(isActive) {
if (isActive) {
const parentSize = this.instance.videoWrapper.getBoundingClientRect();
const videoSize = this.instance.video.getBoundingClientRect();
Expand Down Expand Up @@ -673,7 +672,9 @@ module.exports = class KeyboardMapping {
this.instance.videoWrapper.appendChild(div);
});
} else {
this.instance.videoWrapper.querySelectorAll('.keyMapping-helping-grid').forEach((e) => e.remove());
this.instance.videoWrapper.querySelectorAll('.keyMapping-helping-grid').forEach((e) => {
e.remove();
});
}
}

Expand Down
20 changes: 14 additions & 6 deletions src/plugins/MediaManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,21 @@ module.exports = class MediaManager {
this.videoWithMicrophone = videoWithMicrophone;

// register mute/unmute to exposed API
this.instance.apiManager.registerFunction('mute', () => {
this.instance.video.isMuted = true;
this.instance.video.muted = true;
this.instance.apiManager.registerFunction({
name: 'mute',
category: 'media',
fn: () => {
this.instance.video.isMuted = true;
this.instance.video.muted = true;
},
});
this.instance.apiManager.registerFunction('unmute', () => {
this.instance.video.isMuted = false;
this.instance.video.muted = false;
this.instance.apiManager.registerFunction({
name: 'unmute',
category: 'media',
fn: () => {
this.instance.video.isMuted = false;
this.instance.video.muted = false;
},
});
}

Expand Down

0 comments on commit 1cb706b

Please sign in to comment.