Skip to content
This repository was archived by the owner on Jul 31, 2020. It is now read-only.
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
2 changes: 1 addition & 1 deletion src/state/Scene.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ export class Scene extends EventEmitter implements IScene {
private onControlUpdated(controlData: IControlData) {
const control = this.getControl(controlData.controlID);
if (control) {
control.update(controlData);
control.onUpdate(controlData);
}
}
/**
Expand Down
14 changes: 13 additions & 1 deletion src/state/controls/Button.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { IButton, IButtonData } from '../interfaces/controls/IButton';
import { IButton, IButtonData, IButtonUpdate } from '../interfaces/controls/IButton';
import { IButtonInput } from '../interfaces/controls/IInput';
import { Control } from './Control';

Expand Down Expand Up @@ -71,4 +71,16 @@ export class Button extends Control<IButtonData> implements IButton {
public giveInput(input: IButtonInput): Promise<void> {
return this.sendInput(input);
}

/**
* Update this button on the server.
*/
public update(controlUpdate: IButtonUpdate): Promise<void> {
// Clone to prevent mutations
const changedData = {...controlUpdate};
if (changedData.cooldown) {
changedData.cooldown = this.client.state.synchronizeLocalTime().getTime() + changedData.cooldown;
}
return super.update(changedData);
}
}
21 changes: 21 additions & 0 deletions src/state/controls/Control.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { expect, use } from 'chai';
import * as sinon from 'sinon';

import { Client, ClientType } from '../../Client';
import { IButtonUpdate } from '../interfaces/controls';
import { Scene } from '../Scene';
import { Button } from './';

Expand Down Expand Up @@ -58,4 +59,24 @@ describe('control', () => {
});
stub.restore();
});

it('allows batch updates', () => {
const buttonDiff: IButtonUpdate = {
cost: 200,
text: 'foobar',
};
const updatedButton = {
etag: buttonData.etag,
controlID: buttonData.controlID,
...buttonDiff,
};
const stub = sinon.stub(mockClient, 'updateControls');
control.update(buttonDiff);
expect(stub).to.be
.calledWith({
sceneID: 'default',
controls: [updatedButton],
});
stub.restore();
});
});
21 changes: 19 additions & 2 deletions src/state/controls/Control.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
ControlKind,
IControl,
IControlData,
IControlUpdate,
IGridPlacement,
} from '../interfaces/controls/IControl';
import { IInput, IInputEvent } from '../interfaces/controls/IInput';
Expand Down Expand Up @@ -93,13 +94,29 @@ export abstract class Control<T extends IControlData> extends EventEmitter imple
}

/**
* Merges in values from the server in response to an update operation.
* Merges in values from the server in response to an update operation from the server.
*/
public update(controlData: IControlData) {
public onUpdate(controlData: IControlData) {
merge(this, controlData);
this.emit('updated', this);
}

/**
* Update this control on the server.
*/
public update<T2 extends IControlUpdate>(controlUpdate: T2): Promise<void> {
const changedData = {
...<IControlUpdate>controlUpdate,
controlID: this.controlID,
etag: this.etag,
};

return this.client.updateControls({
sceneID: this.scene.sceneID,
controls: [changedData],
});
}

public destroy(): void {
this.emit('deleted', this);
}
Expand Down
30 changes: 29 additions & 1 deletion src/state/interfaces/controls/IButton.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { IParticipant } from '../';
import { IControl, IControlData } from './IControl';
import { IControl, IControlData, IControlUpdate } from './IControl';
import { IButtonInput, IInputEvent } from './IInput';

/**
Expand Down Expand Up @@ -28,6 +28,33 @@ export interface IButtonData extends IControlData {
keyCode?: number;
}

/**
* Represents updatable components of a button which developers can update
* from game clients.
*/
export interface IButtonUpdate extends IControlUpdate {
/**
* Will update the text of this button.
*/
text?: string;
/**
* In milliseconds, will be converted to a unix timestamp of when this cooldown expires.
*/
cooldown?: number;
/**
* Will update the spark cost of this button.
*/
cost?: number;
/**
* Will update the progress bar underneath the button. 0 - 1.
*/
progress?: number;
/**
* Will update the keycode used by participants for keyboard control.
*/
keyCode?: number;
}

export interface IButton extends IControl, IButtonData {
text: string;
cost: number;
Expand All @@ -39,6 +66,7 @@ export interface IButton extends IControl, IButtonData {
setProgress(progress: number): Promise<void>;
setCooldown(duration: number): Promise<void>;
setCost(cost: number): Promise<void>;
update(changedData: IButtonUpdate): Promise<void>;

/**
* Fired when a participant presses this button.
Expand Down
25 changes: 19 additions & 6 deletions src/state/interfaces/controls/IControl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { EventEmitter } from 'events';

import { ETag, IParticipant } from '../';
import { IClient } from '../../../IClient';
import { ISceneDataArray } from '../IScene';
import { IInput, IInputEvent } from './IInput';
import { IMeta } from './IMeta';

Expand Down Expand Up @@ -40,6 +39,19 @@ export interface IControlData {
*/
etag?: ETag;
}

/**
* Represents updatable components of a control which developers can update
* from game clients.
*/
export interface IControlUpdate {
/**
* When set to true this will disable the control.
* When set to false this will enable the control.
*/
disabled?: boolean;
}

/**
* Control is used a base class for all other controls within an interactive session.
* It contains shared logic which all types of controls can utilize.
Expand Down Expand Up @@ -69,7 +81,12 @@ export interface IControl extends IControlData, EventEmitter {
/**
* Merges in updated control data from the mediator
*/
update(controlData: IControlData): void;
onUpdate(controlData: IControlData): void;

/**
* Updates the control with the supplied update parameters
*/
update(controlUpdate: IControlUpdate): Promise<void>;

/**
* Fired when the control is deleted.
Expand Down Expand Up @@ -113,7 +130,3 @@ export interface IGridPlacement {
*/
y: number;
}

export interface IControlUpdate {
scenes: ISceneDataArray;
}
31 changes: 29 additions & 2 deletions src/state/interfaces/controls/IJoystick.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { IParticipant } from '../';
import { IControl, IControlData } from './IControl';
import { IControl, IControlData, IControlUpdate } from './IControl';
import { IInputEvent, IJoystickInput } from './IInput';

/**
Expand All @@ -8,7 +8,7 @@ import { IInputEvent, IJoystickInput } from './IInput';
export interface IJoystickData extends IControlData {
/**
* The angle of the Joysticks direction indicator.
* In radians 0 - 2.
* In radians 0 - .
*/
angle?: number;
/**
Expand All @@ -24,6 +24,28 @@ export interface IJoystickData extends IControlData {
sampleRate?: number;
}

/**
* Represents updatable components of a joystick which developers can update
* from game clients.
*/
export interface IJoystickUpdate extends IControlUpdate {
/**
* Updates the angle of the Joysticks direction indicator.
* In radians 0 - 2π.
*/
angle?: number;
/**
* updates the strength/opacity of the direction indicator.
*/
intensity?: number;
/**
* Updates the sampleRate of this joystick
*
* In milliseconds.
*/
sampleRate?: number;
}

/**
* A joysticks coordinates.
*
Expand All @@ -48,6 +70,11 @@ export interface IJoystick extends IControl, IJoystickData {
*/
setIntensity(intensity: number): Promise<void>;

/**
* Updates the joystick with the supplied joystick parameters
*/
update(controlUpdate: IJoystickUpdate): Promise<void>;

/**
* Fired when a participant moves this joystick.
*/
Expand Down