Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove Reporter/Message scheme #44

Merged
merged 18 commits into from
May 8, 2023
Merged
Show file tree
Hide file tree
Changes from all 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
4 changes: 2 additions & 2 deletions dist/wams/client.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/wams/client.js.map

Large diffs are not rendered by default.

287 changes: 183 additions & 104 deletions package-lock.json

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@
"canvas-sequencer": "^3.0.6",
"core-js": "^3",
"express": "^4.17.1",
"socket.io": "^4.6.1",
"socket.io-client": "^4.6.1",
"socket.io": "^4.2.0",
"socket.io-client": "^4.2.0",
Comment on lines -25 to +26
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I downgrade socket.io back to 4.2.0 so that we can get debug messages in the browser if we want. See https://github.com/socketio/socket.io-client/issues/1516

"westures": "^1.0.0"
},
"devDependencies": {
Expand Down
88 changes: 38 additions & 50 deletions src/client/ClientController.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

const { io } = require('socket.io-client');

const { constants, DataReporter, PointerReporter, IdStamper, Message, NOP } = require('../shared.js');
const { constants, Message, NOP } = require('../shared.js');
const Interactor = require('./Interactor.js');

// Symbols to identify these methods as intended only for internal use
Expand Down Expand Up @@ -128,11 +128,11 @@ class ClientController {
[Message.UD_VIEW]: (data) => this.handle('updateView', data),

// For hopefully occasional extra adjustments to objects in the model.
[Message.RM_ATTRS]: ({ data }) => this.handle('removeAttributes', data),
[Message.SET_ATTRS]: ({ data }) => this.handle('setAttributes', data),
[Message.SET_IMAGE]: ({ data }) => this.handle('setImage', data),
[Message.SET_RENDER]: ({ data }) => this.handle('setRender', data),
[Message.SET_PARENT]: ({ data }) => this.handle('setParent', data),
[Message.RM_ATTRS]: (data) => this.handle('removeAttributes', data),
[Message.SET_ATTRS]: (data) => this.handle('setAttributes', data),
[Message.SET_IMAGE]: (data) => this.handle('setImage', data),
[Message.SET_RENDER]: (data) => this.handle('setRender', data),
[Message.SET_PARENT]: (data) => this.handle('setParent', data),

// Connection establishment related (disconnect, initial setup)
[Message.INITIALIZE]: this.setup.bind(this),
Expand All @@ -155,7 +155,7 @@ class ClientController {
},

// For user-defined behavior
[Message.DISPATCH]: ({ data }) => this.handleCustomEvent(data),
[Message.DISPATCH]: this.handleCustomEvent.bind(this),
};

Object.entries(listeners).forEach(([p, v]) => this.socket.on(p, v));
Expand All @@ -180,7 +180,7 @@ class ClientController {
* instantiation.
*/
connect() {
this.socket = io.connect(constants.NS_WAMS, {
this.socket = io(constants.NS_WAMS, {
autoConnect: false,
reconnection: false,
transports: ['websocket', 'polling'],
Expand All @@ -204,22 +204,6 @@ class ClientController {
window.requestAnimationFrame(this.render_fn);
}

/**
* Generates a function for forwarding the given message to the server.
*
* @see {@link module:shared.Message}
*
* @param {string} message - The type of message to forward. One of the static
* members of the Message class.
*
* @return {Function} A function bound to this instance for forwarding data to
* the server with the given message type label.
*/
forward(message, data) {
const dreport = new DataReporter({ data });
new Message(message, dreport).emitWith(this.socket);
}

mvanderkamp marked this conversation as resolved.
Show resolved Hide resolved
/**
* Passes messages to the View, and schedules a render.
*
Expand Down Expand Up @@ -254,7 +238,7 @@ class ClientController {
*/
resize() {
this.resizeCanvasToFillWindow();
new Message(Message.RESIZE, this.view).emitWith(this.socket);
this.socket.emit(Message.RESIZE, this.view);
this.view.draw();
}

Expand Down Expand Up @@ -291,29 +275,26 @@ class ClientController {
* not reflect the model automatically. This function responds to a message
* from the server which contains the current state of the model, and forwards
* this data to the view so that it can correctly render the model.
*
* @param {module:shared.FullStateReporter} data - All the information
* necessary to initially synchronize this client's model with the server's
* model.
*/
setup(data) {
if (data.clientScripts) this.loadClientScripts(data.clientScripts);
if (data.stylesheets) this.loadStylesheets(data.stylesheets);
document.title = data.title;
const { clientScripts, stylesheets, title, backgroundImage, color, useMultiScreenGestures } = data.settings;
if (clientScripts) this.loadClientScripts(clientScripts);
if (stylesheets) this.loadStylesheets(stylesheets);
document.title = title;

IdStamper.cloneId(this.view, data.id);
this.view.id = data.viewId;

if (data.backgroundImage) {
if (backgroundImage) {
this.canvas.style.backgroundColor = 'transparent';
document.body.style.backgroundImage = `url("${data.backgroundImage}")`;
document.body.style.backgroundImage = `url("${backgroundImage}")`;
} else {
this.canvas.style.backgroundColor = data.color;
this.canvas.style.backgroundColor = color;
}
this.model.setup(data);
this.setupInteractor(data.useMultiScreenGestures);
this.setupInteractor(useMultiScreenGestures);

// Need to tell the model what the view looks like once setup is complete.
new Message(Message.LAYOUT, this.view).emitWith(this.socket);
this.socket.emit(Message.LAYOUT, this.view);
}

loadClientScripts(scripts) {
Expand Down Expand Up @@ -351,10 +332,10 @@ class ClientController {
// eslint-disable-next-line
this.setupInputForwarding();
return new Interactor(this.rootElement, {
swipe: this.forward.bind(this, Message.SWIPE),
tap: this.forward.bind(this, Message.CLICK),
track: this.forward.bind(this, Message.TRACK),
transform: this.forward.bind(this, Message.TRANSFORM),
swipe: this.socket.emit.bind(this.socket, Message.SWIPE),
tap: this.socket.emit.bind(this.socket, Message.CLICK),
track: this.socket.emit.bind(this.socket, Message.TRACK),
transform: this.socket.emit.bind(this.socket, Message.TRANSFORM),
});
}

Expand Down Expand Up @@ -387,8 +368,7 @@ class ClientController {
*/
forwardBlurEvents() {
this.forwardEvents(['pointercancel', 'blur'], (event) => {
const breport = new DataReporter();
new Message(Message.BLUR, breport).emitWith(this.socket);
this.socket.emit(Message.BLUR, {});
});
}

Expand All @@ -397,8 +377,19 @@ class ClientController {
*/
forwardPointerEvents() {
this.forwardEvents(['pointerdown', 'pointermove', 'pointerup'], (event) => {
const treport = new PointerReporter(event);
new Message(Message.POINTER, treport).emitWith(this.socket);
// Extract only the properties we care about
const { type, pointerId, clientX, clientY, target, altKey, ctrlKey, metaKey, shiftKey } = event;
this.socket.emit(Message.POINTER, {
type,
pointerId,
clientX,
clientY,
target,
altKey,
ctrlKey,
metaKey,
shiftKey,
});
});
}

Expand All @@ -409,10 +400,7 @@ class ClientController {
* @param {object} payload
*/
dispatch(action, payload) {
const dreport = new DataReporter({
data: { action, payload },
});
new Message(Message.DISPATCH, dreport).emitWith(this.socket);
this.socket.emit(Message.DISPATCH, { action, payload });
}
}

Expand Down
17 changes: 2 additions & 15 deletions src/client/ClientElement.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
'use strict';

const { Point2D, IdStamper, WamsElement } = require('../shared.js');
const { Point2D, WamsElement } = require('../shared.js');

/**
* The ClientElement class exposes the draw() funcitonality of wams elements.
*
* @extends module:shared.WamsElement
* @memberof module:client
*
* @param {module:shared.WamsElement} data - The data from the server describing
* this item. Only properties explicity listed in the array passed to the
* ReporterFactory when the WamsElement class was defined will be accepted.
* @param {module:shared.WamsElement} data - The data from the server describing this item.
*/
class ClientElement extends WamsElement {
constructor(data) {
Expand Down Expand Up @@ -38,17 +36,6 @@ class ClientElement extends WamsElement {
if (Object.prototype.hasOwnProperty.call(data, 'attributes')) {
this.setAttributes(data.attributes);
}

/**
* Id to make the items uniquely identifiable.
*
* @name id
* @type {number}
* @constant
* @instance
* @memberof module:client.ClientElement
*/
IdStamper.cloneId(this, data.id);
}

/**
Expand Down
17 changes: 2 additions & 15 deletions src/client/ClientImage.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use strict';

const { IdStamper, WamsImage, Message } = require('../shared.js');
const { WamsImage, Message } = require('../shared.js');

/**
* Abstraction of the requisite logic for generating an image object which will
Expand Down Expand Up @@ -38,9 +38,7 @@ function createImage(src) {
* @extends module:shared.WamsImage
* @memberof module:client
*
* @param {module:shared.Item} data - The data from the server describing this
* item. Only properties explicity listed in the array passed to the
* ReporterFactory when the Item class was defined will be accepted.
* @param {module:shared.Item} data - The data from the server describing this item.
*/
class ClientImage extends WamsImage {
constructor(data) {
Expand All @@ -53,17 +51,6 @@ class ClientImage extends WamsImage {
*/
this.image = {};
if (data.src) this.setImage(data.src);

/**
* Id to make the items uniquely identifiable.
*
* @name id
* @type {number}
* @constant
* @instance
* @memberof module:client.ClientImage
*/
IdStamper.cloneId(this, data.id);
}

/**
Expand Down
17 changes: 2 additions & 15 deletions src/client/ClientItem.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use strict';

const { IdStamper, Item } = require('../shared.js');
const { Item } = require('../shared.js');
const { CanvasSequence } = require('canvas-sequencer');

/**
Expand All @@ -9,9 +9,7 @@ const { CanvasSequence } = require('canvas-sequencer');
* @extends module:shared.Item
* @memberof module:client
*
* @param {module:shared.Item} data - The data from the server describing this
* item. Only properties explicity listed in the array passed to the
* ReporterFactory when the Item class was defined will be accepted.
* @param {module:shared.Item} data - The data from the server describing this item.
*/
class ClientItem extends Item {
constructor(data) {
Expand All @@ -24,17 +22,6 @@ class ClientItem extends Item {
*/
this.render = null;
if (data.sequence) this.setRender(data.sequence);

/**
* Id to make the items uniquely identifiable.
*
* @name id
* @type {number}
* @constant
* @instance
* @memberof module:client.ClientItem
*/
IdStamper.cloneId(this, data.id);
}

/**
Expand Down
19 changes: 7 additions & 12 deletions src/client/ClientModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const ClientItem = require('./ClientItem.js');
const ShadowView = require('./ShadowView.js');
const { removeById } = require('../shared.js');

const REQUIRED_DATA = Object.freeze(['id', 'items', 'views']);
const REQUIRED_DATA = Object.freeze(['viewId', 'items', 'views']);

/**
* The ClientModel is a client-side copy of those aspects of the model that are
Expand Down Expand Up @@ -136,11 +136,6 @@ class ClientModel {
/**
* Set up the internal copy of the model according to the data provided by the
* server.
*
* @param {module:shared.FullStateReporter} data - The data from the server
* detailing the current state of the model. See REQUIRED_DATA. If any
* is missing, something has gone terribly wrong, and an exception will
* be thrown.
*/
setup(data) {
REQUIRED_DATA.forEach((d) => {
Expand All @@ -157,8 +152,8 @@ class ClientModel {
}
});
this.view.config.shadows = data.shadows;
this.view.config.status = data.status;
this.view.config.backgroundImage = data.backgroundImage;
this.view.config.status = data.settings.status;
this.view.config.backgroundImage = data.settings.backgroundImage;
}

/**
Expand Down Expand Up @@ -227,10 +222,10 @@ class ClientModel {
*/
update(container, data) {
if (this[container].has(data.id)) {
this[container].get(data.id).assign(data);
const itemOrView = this[container].get(data.id);
Object.assign(itemOrView, data);
if (container === 'items') {
const item = this[container].get(data.id);
if (!item.lockZ) {
if (!itemOrView.lockZ) {
this.bringItemToTop(data.id);
}
}
Expand Down Expand Up @@ -266,7 +261,7 @@ class ClientModel {
* pertaining to this client's view.
*/
updateView(data) {
this.view.assign(data);
Object.assign(this.view, data);
}

/**
Expand Down
12 changes: 0 additions & 12 deletions src/client/ClientView.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,18 +52,6 @@ class ClientView extends View {
*/
this.model = null;

/**
* Id to make the views uniquely identifiable. Will be assigned when setup
* message is received from server.
*
* @name id
* @type {number}
* @constant
* @instance
* @memberof module:client.ClientView
*/
this.id = null;

/**
* Configuration of ClientView that can be
* modified in user-defined `window.WAMS_CONFIG`.
Expand Down
7 changes: 1 addition & 6 deletions src/client/ShadowView.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

'use strict';

const { colours, IdStamper, View } = require('../shared.js');
const { colours, View } = require('../shared.js');

// Symbols to mark these methods as intended for internal use only.
const symbols = Object.freeze({
Expand All @@ -26,11 +26,6 @@ const symbols = Object.freeze({
* view.
*/
class ShadowView extends View {
constructor(values) {
super(values);
IdStamper.cloneId(this, values.id);
}

/**
* Render an outline of this view.
*
Expand Down
Loading