Skip to content

Instantly share code, notes, and snippets.

@MateSteinforth
Last active December 21, 2023 15:16
Show Gist options
  • Select an option

  • Save MateSteinforth/16f6eb6b2fb5a46471f79fa8187439ed to your computer and use it in GitHub Desktop.

Select an option

Save MateSteinforth/16f6eb6b2fb5a46471f79fa8187439ed to your computer and use it in GitHub Desktop.
Spark Imperative Update Loop
import Time from 'Time';
/**
* The Update class manages subscriptions to snapshot items and provides an update method that can be overridden by subclasses.
*
* import Scene from 'Scene';
* import Update from './Update';
*
* class OtherClass extends Update {
* private _mySceneObject: Scene.SceneObjectBase = Scene.root.findFirstSync('plane0');
*
* constructor() {
* super();
* this.addSnapshotItem('planeX', this._mySceneObject.transform.x);
* }
*
* update(deltaTime: number, snapshot: object): void {
* Diagnostics.log(deltaTime + " : " + snapshot.planeX);
* }
* }
*
* let myClassInstance = new OtherClass();
*
*/
class Update {
private static timeSubscription: any;
private static allSnapshotItems: { [key: string]: any } = {};
private static allUpdateCallbacks: Array<(deltaTime: number, snapshot: object) => void> = [];
private snapshotItems: { [key: string]: any };
private lastExecutionTime: number;
/**
* Constructs a new Update instance.
*/
constructor() {
this.snapshotItems = {};
this.lastExecutionTime = Time.ms.pinLastValue();
Update.allUpdateCallbacks.push(this.update.bind(this));
if (!Update.timeSubscription) {
this.startSubscription();
}
}
/**
* This method can be overridden by subclasses to provide custom behavior when the subscription is triggered.
* @param deltaTime - The time elapsed since the last execution.
* @param snapshot - The current snapshot of the subscribed items.
*/
update(deltaTime: number, snapshot: object): void {}
/**
* Adds a new snapshot item to the subscription and restarts the subscription.
* @param itemKey - The key of the snapshot item.
* @param itemValue - The value of the snapshot item.
*/
addSnapshotItem(itemKey: string, itemValue: any): void {
this.snapshotItems[itemKey] = itemValue;
Update.allSnapshotItems[itemKey] = itemValue;
this.restartSubscription();
}
/**
* Starts the subscription to the snapshot items.
*/
private startSubscription(): void {
Update.timeSubscription = Time.ms.monitor().subscribeWithSnapshot(
Update.allSnapshotItems,
(timeMS, snapshot) => {
const currentTime = timeMS.newValue;
const deltaTime = currentTime - this.lastExecutionTime;
Update.allUpdateCallbacks.forEach(callback => callback(deltaTime, snapshot));
this.lastExecutionTime = currentTime;
}
);
}
/**
* Unsubscribes from the current subscription and starts a new one. This is used to include new snapshot items in the subscription.
*/
private restartSubscription(): void {
Update.timeSubscription.unsubscribe();
this.startSubscription();
}
}
export default Update;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment