Skip to content
This repository has been archived by the owner on Jul 31, 2020. It is now read-only.

Commit

Permalink
add control.update(), which takes a partial control (#65)
Browse files Browse the repository at this point in the history
* add control.update(), which takes a partial control

This allows developers to make a batch update to the entire control.

* PR Comments from Connor

* Restructure stuff

* ss

* This dont make sense now

* Ok how about generics

* Birtles fixes
  • Loading branch information
ProbablePrime authored Jun 8, 2017
1 parent 773a1e0 commit 510d7c2
Show file tree
Hide file tree
Showing 7 changed files with 131 additions and 13 deletions.
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

0 comments on commit 510d7c2

Please sign in to comment.