Provides the StepLoop class, a foundation for building loops that execute at a consistent, specified rate.
To define a new loop, extend the StepLoop class and override its methods to implement custom behavior.
The StepLoop class executes in three distinct stages, with hooks that can be overridden to add custom logic:
- Initialization: Runs once at the beginning of the loop
- Looping: The core of the loop, which repeatedly executes the following sequence:
- Termination: Runs once when the loop ends, either by reaching the end of its lifespan or being manually stopped
The loop can run indefinitely or for a set number of steps, and its execution can be precisely controlled, allowing it to be paused, resumed, and dynamically modified at runtime.
- steploop
- .StepLoop
- new exports.StepLoop(sps, lifespan)
- .initial() ⇒
void - .background() ⇒
Promise.<void> - .before() ⇒
void - .step() ⇒
void - .after() ⇒
void - .final() ⇒
void - .on_pause() ⇒
void - .on_play() ⇒
void - .is_running() ⇒
boolean - .is_paused() ⇒
boolean - .get_step() ⇒
number - .get_sps() ⇒
number - .get_real_sps() ⇒
number - .get_lifespan() ⇒
number|undefined - .set_sps(sps) ⇒
number - .set_use_RAF(status) ⇒
boolean - .set_lifespan([steps]) ⇒
number|undefined - .extend_lifespan(steps) ⇒
number|undefined - .pause() ⇒
void - .play() ⇒
void - .start() ⇒
void - .finish() ⇒
void
- .StepLoop
A base class for building loops that execute at a consistent, specified rate.
StepLoop provides a structured lifecycle with methods that can be overridden to implement custom behavior.
The StepLoop class manages the timing and execution flow, supporting both fixed-step updates via setTimeout() and smoother, display-synchronized updates using window.requestAnimationFrame().
The loop can run indefinitely or for a set number of steps, and its execution can be precisely controlled, allowing it to be paused, resumed, and dynamically modified at runtime.
Kind: static class of steploop
- .StepLoop
- new exports.StepLoop(sps, lifespan)
- .initial() ⇒
void - .background() ⇒
Promise.<void> - .before() ⇒
void - .step() ⇒
void - .after() ⇒
void - .final() ⇒
void - .on_pause() ⇒
void - .on_play() ⇒
void - .is_running() ⇒
boolean - .is_paused() ⇒
boolean - .get_step() ⇒
number - .get_sps() ⇒
number - .get_real_sps() ⇒
number - .get_lifespan() ⇒
number|undefined - .set_sps(sps) ⇒
number - .set_use_RAF(status) ⇒
boolean - .set_lifespan([steps]) ⇒
number|undefined - .extend_lifespan(steps) ⇒
number|undefined - .pause() ⇒
void - .play() ⇒
void - .start() ⇒
void - .finish() ⇒
void
Create a StepLoop, with options to define the steps-per-second and the lifespan of the loop.
| Param | Type | Default | Description |
|---|---|---|---|
| sps | number |
60 |
the steps-per-second of the loop (note: values that are greater than about 250 may result in unexpected behavior); default value is 60 |
| lifespan | number | undefined |
the number of steps that are executed before the loop ends; setting to undefined will result in an unlimited lifespan; default value is undefined |
Example
import { StepLoop } from "steploop";
class App extends StepLoop {
override initial(): void {
console.log("Loop starting");
}
override step(): void {
console.log(`Executing step: ${this.get_step()}`);
}
override final(): void {
console.log("Loop finished");
}
}
// Create a new loop that runs at 60 steps-per-second for 100 steps
const loop = new App(60, 100);
loop.start();Override StepLoop.initial() to add an initial block of code to execute at the very beginning of the loop.
The first code executed in the StepLoop. Called once at the beginning of the StepLoop lifecycle, and then moves on to the first StepLoop.background() call in the looping stage after resolving. Executed right after StepLoop.start() is called.
Kind: instance method of StepLoop
Returns: void - void
Example
class App extends StepLoop {
public override initial(): void {
console.log(`initial: ${Date.now()}`);
}
}Override StepLoop.background() to add a block of code to run in the background of each step of your loop.
Executed in the background at the beginning of the looping stage. Called asynchronously before the rest of the loop, executes while the rest of the loop does. Starts before StepLoop.before() but may not resolve before it is called.
Kind: instance method of StepLoop
Returns: Promise.<void> - Promise<void>
Example
class App extends StepLoop {
public override async background(): Promise<void> {
console.log(`background: ${this.get_step()}`);
}
}Override StepLoop.before() to add a block of code to run before each step of your loop.
Executed in the looping stage before the main StepLoop.step() code. Resolves before calling StepLoop.step(). Use this function to set up anything you need before StepLoop.step() is called.
Kind: instance method of StepLoop
Returns: void - void
Example
class App extends StepLoop {
public override before(): void {
console.log(`before: ${this.get_step()}`);
}
}Override StepLoop.step() to add the code for the main step of your loop.
The main loop code executed in the looping stage. Called after StepLoop.before() resolves, and resolves before StepLoop.after() is called. Use StepLoop.step() as the main update function of your StepLoop.
Kind: instance method of StepLoop
Returns: void - void
Example
class App extends StepLoop {
public override step(): void {
console.log(`step: ${this.get_step()}`);
}
}Override StepLoop.after() to add a block of code to run after each step of your loop.
Executed in the looping stage after the main StepLoop.step() code. Called after StepLoop.step() resolves. Use this function to clean up anything after StepLoop.step() resolves.
Kind: instance method of StepLoop
Returns: void - void
Example
class App extends StepLoop {
public override after(): void {
console.log(`after: ${this.get_step()}`);
}
}Override StepLoop.final() to add a final block of code to run at the very end of the loop.
The last code executed in the StepLoop, called after the looping stage is done. Executed once at the end of the StepLoop lifecycle, and then kills the loop. Called when the number of steps executed is greater than the lifespan of the StepLoop (i. e. StepLoop.get_step() > StepLoop.get_lifespan()) or when StepLoop.finish() is called.
Kind: instance method of StepLoop
Returns: void - void
Example
class App extends StepLoop {
public override final(): void {
console.log(`final: ${Date.now()}`);
}
}Override StepLoop.on_pause() to add a block of code to execute immediately after calling StepLoop.pause().
Called only when the StepLoop is paused, then stops executing until StepLoop.play() is called.
Kind: instance method of StepLoop
Returns: void - void
Example
class App extends StepLoop {
public override on_pause(): void {
console.log(`paused`);
}
}Override StepLoop.on_play() to add a block of code to execute immediately after calling StepLoop.play().
Called only when the StepLoop is played, then proceeds with the rest of the loop.
Kind: instance method of StepLoop
Returns: void - void
Example
class App extends StepLoop {
public override on_play(): void {
console.log(`played`);
}
}Returns true if the StepLoop is running and false otherwise.
Kind: instance method of StepLoop
Returns: boolean - true if the loop is currently running
Example
class App extends StepLoop {}
let app: App = new App();
app.start()
console.log(app.is_running()) // Output -> `true`Returns true if the StepLoop is paused and false otherwise.
Kind: instance method of StepLoop
Returns: boolean - true if the loop is currently paused
Example
class App extends StepLoop {}
let app: App = new App();
app.start()
console.log(app.is_paused()) // Output -> `false`Returns the current step number (the number of times the loop has run).
Kind: instance method of StepLoop
Returns: number - the current step number
Example
class App extends StepLoop {}
let app: App = new App();
app.start()
console.log(app.get_step()) // Output -> `1`Returns the current steps-per-second (sps).
Kind: instance method of StepLoop
Returns: number - the current steps-per-second (sps)
Example
class App extends StepLoop {}
let app: App = new App();
app.start()
console.log(app.get_sps()) // Output -> `60`Returns the real steps-per-second (sps) based on the time between the last two steps. This value may not be accurate until after the first few steps have completed.
Kind: instance method of StepLoop
Returns: number - the real steps-per-second (sps)
Example
class App extends StepLoop {}
let app: App = new App();
app.start()
console.log(app.get_real_sps())Returns the current lifespan of the StepLoop (in steps).
Kind: instance method of StepLoop
Returns: number | undefined - the current loop lifespan; returns undefined if the lifespan is unlimited
Example
class App extends StepLoop {}
let app: App = new App(500);
app.start()
console.log(app.get_lifespan()) // Output -> `500`Sets the current steps-per-second (sps). Alters the speed at which the StepLoop runs: higher values will result in more steps in a faster step-speed and lower values will result in a lower step-speed. Default speed is 60 steps-per-second.
Kind: instance method of StepLoop
Returns: number - the new steps-per-second
| Param | Type | Description |
|---|---|---|
| sps | number |
the target steps-per-second; default value is 60 |
Example
class App extends StepLoop {}
let app: App = new App();
app.start()
console.log(app.set_sps(120)) // Output -> `120`Set whether or not to use window.requestAnimationFrame() for the StepLoop. When set to true, the loop will synchronize with the browser's rendering cycle (if the loop is running in a browser), which can result in smoother animations and better performance. When disabled, the loop will use a step-scheduler based on setTimeout(), which may be less efficient but more predictable.
Kind: instance method of StepLoop
Returns: boolean - the new status of requestAnimationFrame
| Param | Type | Description |
|---|---|---|
| status | boolean |
true to use requestAnimationFrame, false to use the step scheduler. |
Example
class App extends StepLoop {}
let app: App = new App();
app.set_use_RAF(true)
app.start()Set the lifespan of the StepLoop to the specified number of steps, or removes the limit on the StepLoop's lifespan (will run until StepLoop.finish() is called).
If StepLoop.set_lifespan() is called after the lifespan limit is reached, StepLoop.play() can be called to resume executing the StepLoop. The termination stage will be executed again when the limit is reached again.
Kind: instance method of StepLoop
Returns: number | undefined - the new lifespan
| Param | Type | Description |
|---|---|---|
| [steps] | number |
the target lifespan (in number of steps); if undefined the lifespan becomes unlimited; default value is undefined if not provided |
Example
class App extends StepLoop {}
let app: App = new App();
app.start()
console.log(app.set_lifespan(100)) // Output -> `100`Extend (or reduce) the lifespan of the StepLoop. Adds the specified number of steps to the current lifespan.
If StepLoop.extend_lifespan() is called after the lifespan limit is reached, StepLoop.play() can be called to resume executing the StepLoop. The termination stage will be executed again when the limit is reached again.
Kind: instance method of StepLoop
Returns: number | undefined - the new lifespan; returns undefined if the loop is uninitialized
| Param | Type | Description |
|---|---|---|
| steps | number |
the number of steps to add to the lifespan |
Example
class App extends StepLoop {}
let app: App = new App();
app.start()
console.log(app.extend_lifespan(100)) // Output -> `100`Pause the execution of the StepLoop after the current step resolves. Steps will not advance and the current step (StepLoop.get_step()) will not increase while the StepLoop is paused. Use StepLoop.play() to resume execution and continue the loop.
Kind: instance method of StepLoop
Returns: void - void
Example
class App extends StepLoop {}
let app: App = new App();
app.start()
app.pause()Resume execution of the StepLoop after calling StepLoop.pause() to pause it. Will resume execution on the next step in the StepLoop lifespan. Use StepLoop.pause() to pause execution and stop the loop.
Kind: instance method of StepLoop
Returns: void - void
Example
class App extends StepLoop {}
let app: App = new App();
app.start()
app.pause()
app.play()Begin execution of the StepLoop lifecycle. Calls StepLoop.initial() to execute the initialization stage, then proceeds to the looping stage. The termination stage will not execute until StepLoop.finish() is called.
If StepLoop.start() is called after the termination stage has ended, the loop will restart at the beginning of the initialization stage.
Kind: instance method of StepLoop
Returns: void - void
Example
class App extends StepLoop {}
let app: App = new App();
app.start()Ends the StepLoop. Executes the termination stage of the StepLoop lifecycle. Calls StepLoop.final() and then kills the loop.
Kind: instance method of StepLoop
Returns: void - void
Example
class App extends StepLoop {}
let app: App = new App();
app.start()
app.finish()