Skip to content

Latest commit

 

History

History
493 lines (392 loc) · 23.2 KB

File metadata and controls

493 lines (392 loc) · 23.2 KB

steploop

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.

Lifecycle

The StepLoop class executes in three distinct stages, with hooks that can be overridden to add custom logic:

  1. Initialization: Runs once at the beginning of the loop
  2. Looping: The core of the loop, which repeatedly executes the following sequence:
  3. 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

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

new exports.StepLoop(sps, lifespan)

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();

stepLoop.initial() ⇒ void

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()}`);
    }
}

stepLoop.background() ⇒ Promise.<void>

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()}`);
    }
}

stepLoop.before() ⇒ void

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()}`);
    }
}

stepLoop.step() ⇒ void

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()}`);
    }
}

stepLoop.after() ⇒ void

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()}`);
    }
}

stepLoop.final() ⇒ void

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()}`);
    }
}

stepLoop.on_pause() ⇒ void

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`);
    }
}

stepLoop.on_play() ⇒ void

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`);
    }
}

stepLoop.is_running() ⇒ boolean

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`

stepLoop.is_paused() ⇒ boolean

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`

stepLoop.get_step() ⇒ number

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`

stepLoop.get_sps() ⇒ number

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`

stepLoop.get_real_sps() ⇒ number

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())

stepLoop.get_lifespan() ⇒ number | undefined

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`

stepLoop.set_sps(sps) ⇒ number

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`

stepLoop.set_use_RAF(status) ⇒ boolean

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()

stepLoop.set_lifespan([steps]) ⇒ number | undefined

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`

stepLoop.extend_lifespan(steps) ⇒ number | undefined

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`

stepLoop.pause() ⇒ void

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()

stepLoop.play() ⇒ void

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()

stepLoop.start() ⇒ void

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()

stepLoop.finish() ⇒ void

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()