1
0
Fork 0
spacetac/src/common/Toggle.ts

94 lines
2.8 KiB
TypeScript
Raw Normal View History

2019-05-06 17:14:12 +00:00
module TK {
/**
* Client for Toggle object, allowing to manipulate it
*
* *state* may be:
* - a boolean to require on or off
* - a number to require on for the duration in milliseconds
* - undefined to switch between on and off (based on the client state, not the toggle state)
*
* The function returns the actual state after applying the requirement
*/
export type ToggleClient = (state?: boolean | number) => boolean
/**
* A toggle between two states (on and off).
*
* A toggle will be on if at least one ToggleClient requires it to be on.
*/
export class Toggle {
private on: Function
private off: Function
private status = false
private clients: string[] = []
private scheduled: { [client: string]: any } = {}
private timer = Timer.global
constructor(on: Function = () => null, off: Function = () => null) {
this.on = on;
this.off = off;
}
/**
* Check if the current state is on
*/
isOn(): boolean {
return this.status;
}
/**
* Register a client to manipulate the toggle's state
*/
manipulate(client: string): ToggleClient {
return state => {
if (this.scheduled[client]) {
this.timer.cancel(this.scheduled[client]);
this.scheduled[client] = null;
}
if (typeof state == "undefined") {
if (contains(this.clients, client)) {
this.stop(client);
} else {
this.start(client);
}
} else if (typeof state == "number") {
if (state > 0) {
this.start(client);
this.scheduled[client] = this.timer.schedule(state, () => this.stop(client));
} else {
this.stop(client);
}
} else if (!state) {
this.stop(client);
} else {
this.start(client);
}
return this.status;
}
}
/**
* Start the toggle for a client (set the status *on*)
*/
private start(client: string) {
add(this.clients, client);
if (!this.status) {
this.status = true;
this.on();
}
}
/**
* Stop the toggle (set the status *off*)
*/
private stop(client: string) {
remove(this.clients, client);
if (this.status && this.clients.length == 0) {
this.status = false;
this.off();
}
}
}
}