Created
August 16, 2023 12:10
-
-
Save amiika/44f6450f7bc42d5d60f306c4c5ada604 to your computer and use it in GitHub Desktop.
Typescript linked list with number references for live coding method chaining
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Simple pattern class creating pattern from list of values | |
export class Pattern { | |
events: Event[]; | |
_current : number | undefined = undefined; | |
constructor(values: number[]) { | |
this.events = values.map((value, index) => new Event(value)); | |
this.buildLinks(); | |
} | |
// Create links cyclic links between events | |
buildLinks(): void { | |
this.events.forEach((event, index) => { | |
event._next = index + 1 < this.events.length ? index + 1 : 0; | |
}); | |
} | |
// Get the current event for this pattern | |
next(): Event { | |
if(this._current !== undefined) { | |
// Get current event | |
const currentEvent = this.events[this._current % this.events.length]; | |
// Set currentEvent undefined (If you dont want to mofify modified events) | |
if(currentEvent.modifiedEvent) currentEvent.modifiedEvent = undefined; | |
// Set next event index | |
this._current = this._current + 1 < this.events.length ? this._current + 1 : 0; | |
} else { | |
// Set current event index when starting | |
this._current = 0; | |
} | |
// Get next event | |
const nextEvent = this.events[this._current % this.events.length]; | |
return nextEvent; | |
} | |
peek(): Event { | |
return this.events[this._current || 0]; | |
} | |
hasStarted(): boolean { | |
return this._current !== undefined; | |
} | |
} | |
// Simple event class with simple numerical value and link to next event | |
export class Event { | |
_next!: number; | |
_value: number; | |
// Used to store a modified version of the event | |
modifiedEvent: Event | undefined = undefined; | |
constructor(value: number) { | |
this._value = value; | |
} | |
get value(): number { | |
if(this.modifiedEvent) return this.modifiedEvent._value; | |
return this._value; | |
} | |
add(value: number): Event { | |
if(!this.modifiedEvent) { | |
this.modifiedEvent = this.clone(); | |
} | |
this.modifiedEvent._value += value; | |
return this; | |
} | |
clone(): Event { | |
const event = new Event(this._value); | |
event._next = this._next; | |
return event; | |
} | |
} | |
// Simple cache for patterns | |
let cache = new Map<string, Pattern>(); | |
// Create a cache key from the values of a pattern somehow | |
const createCacheKey = (values: number[]) => values.join('-'); | |
// Get a cached pattern or create a new one | |
const getCachedPattern = (values: number[]) => { | |
const key = createCacheKey(values); | |
const cachedPattern = cache.get(key); | |
if(cachedPattern) return cachedPattern; | |
const newPattern = new Pattern(values); | |
cache.set(key, newPattern); | |
return newPattern; | |
} | |
// Cached event function that includes the main logic | |
const cachedEvent = (values: number[]): Event => { | |
const pattern = getCachedPattern(values); | |
if(pattern.hasStarted()) { console.log("Play: ", pattern.peek().value) } | |
else { console.log("Current is undefined so just starting!") } | |
return pattern.next(); | |
} | |
// Test it out | |
let i = 0; | |
while(true) { | |
cachedEvent([1, 2, 3]).add(1).add(2); | |
if(i++>10) break; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment