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

add control.update(), which takes a partial control #65

Merged
merged 7 commits into from
Jun 8, 2017

Conversation

ProbablePrime
Copy link
Contributor

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

Resolves #38

This allows developers to make a batch update to the entire control.
@@ -71,4 +71,11 @@ export class Button extends Control<IButtonData> implements IButton {
public giveInput(input: IButtonInput): Promise<void> {
return this.sendInput(input);
}

public update(changedData: Partial<IButtonData>): Promise<void> {
if (changedData.cooldown) {
Copy link
Contributor

Choose a reason for hiding this comment

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

IButtonData is documented as having its cooldown be a unix timestamp, here that is broken. Prefer to keep a single unambiguous representation for all data, providing utility methods as needed for fluent shortcuts.

Also, avoid mutating function input! This is a surprising side effect.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Here im trying to understand how to indicate that for this particular method that the cooldown should be a UTC whereas setCooldown takes a duration.

Could we perhaps use an extended interface here that has duration to allow for this behavior?

Trying to make this make sense for everyone.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not clear on the need to allow the method to take a duration at all.

Copy link
Contributor Author

@ProbablePrime ProbablePrime Jun 8, 2017

Choose a reason for hiding this comment

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

Ok, so:

before: "I want to set the button's text to "connor" and the cooldown to 5 seconds"

control.setText('connor').then(() => control.setCooldown(5))

After:

control.update({
 text:'connor',
 cooldown:<A utc what?>
});

@connor4312

Copy link
Contributor Author

@ProbablePrime ProbablePrime Jun 8, 2017

Choose a reason for hiding this comment

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

Connor, I want to enable batch updates as a utility method

I want to enable them easily. Control.update(..what you want to update) => Promise<void> (or <IControlData>) makes sense to me.

What doesn't is the cooldown. This is the only problem imo. As you initially were the one to update setCooldown to take the inputed duration and change it into a timestamp I would like you advisement on how to do this. Within control.update.

I do not see how creating a utility method that allows people to update multiple properties in the same service call breaks Liskov.

Copy link
Contributor

@connor4312 connor4312 Jun 8, 2017

Choose a reason for hiding this comment

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

Within control.update.

This is the issue, this is not possible while overriding the behavior of the cooldown property. I mentioned above:

Control<T> has a method update(Partial<T>) while Button extends Control<R> while having a method update(Partial<X>)

The wikipedia page on the LSP lists:

Liskov's principle imposes some standard requirements on signatures... Contravariance of method arguments in the subtype.

Taking type X where X is not a supertype of R breaks contravariance.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok, so its the signature. let's change the signature: IControlUpdate, IButtonUpdate which we can document as having coolodwn in miliseconds. brb doing that.

Copy link
Contributor

Choose a reason for hiding this comment

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

Corrected my above message, sorry for the mistype: X must be a supertype of R, R can be a composition of X

Copy link
Contributor Author

Choose a reason for hiding this comment

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

oK! :)

changedData.etag = this.etag;
return this.client.updateControls({
sceneID: this.scene.sceneID,
controls: [ changedData ],
Copy link
Contributor

Choose a reason for hiding this comment

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

rm spaces

controlID: buttonData.controlID,
},
buttonDiff,
);
Copy link
Contributor

Choose a reason for hiding this comment

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

Prefer the spread operator to object.assign

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 prefer object.assign. Do you have a reason for its use over spreading?

Copy link
Contributor

@connor4312 connor4312 Jun 8, 2017

Choose a reason for hiding this comment

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

It's guaranteed to be free of side effects, and is the standard we follow in all other TypeScript code/projects

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Eh spread works, im just used to assign from the old days. changing sec

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The way i used object.assign with the initial parameter of {} guarantees no side effects too.

@ProbablePrime
Copy link
Contributor Author

@connor4312 I did a thing, with the new interface we actually prevent people shooting themselves in the foot too.

@connor4312
Copy link
Contributor

Still outstanding comments (in Slack DM)

@@ -104,9 +104,9 @@ export abstract class Control<T extends IControlData> extends EventEmitter imple
/**
* Update this control on the server.
*/
public update(controlUpdate: IControlUpdate): Promise<void> {
public update<T extends IControlUpdate>(controlUpdate: T): Promise<void> {
Copy link
Contributor

Choose a reason for hiding this comment

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

What is the point of this, T will always implement the interface so the statements are equivalent.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Connor says this PR breaks Liskov so im trying to fix it.

text: 'foobar',
};
const updatedButton = {
...{
Copy link
Contributor

Choose a reason for hiding this comment

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

you don't need to spread an object on here, you can include the properties directly

Copy link
Contributor Author

Choose a reason for hiding this comment

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

oh yes!

export interface IJoystickUpdate extends IControlUpdate {
/**
* Updates the angle of the Joysticks direction indicator.
* In radians 0 - 2.
Copy link
Contributor

Choose a reason for hiding this comment

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

0 - 2π surely?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

sure

@ProbablePrime ProbablePrime merged commit 510d7c2 into master Jun 8, 2017
@ProbablePrime ProbablePrime deleted the feature/batchUpdates branch June 8, 2017 13:48
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Development

Successfully merging this pull request may close these issues.

4 participants