feat: auto-save and multiple tracks
This commit is contained in:
124
src/BeatStore.ts
Normal file
124
src/BeatStore.ts
Normal file
@@ -0,0 +1,124 @@
|
||||
import Beat, {BeatEvents} from "@/Beat";
|
||||
import Ref from "@/Ref";
|
||||
import ISubscriber from "@/Subscriber";
|
||||
|
||||
const EventTypeSubscriptions = [
|
||||
BeatEvents.TimeSigUpChanged,
|
||||
BeatEvents.BarCountChanged,
|
||||
BeatEvents.GlobalDisplayTypeChanged,
|
||||
BeatEvents.TrackListChanged,
|
||||
BeatEvents.LockingChanged,
|
||||
BeatEvents.AutoBeatSettingsChanged,
|
||||
BeatEvents.DeepChange,
|
||||
] as const;
|
||||
type EventTypeSubscriptions = typeof EventTypeSubscriptions[number];
|
||||
|
||||
export default class BeatStore implements ISubscriber<EventTypeSubscriptions> {
|
||||
private readonly beats: Beat[];
|
||||
private activeBeat: Ref<Beat>;
|
||||
private onBeatChangeCbs: (() => void)[] = [];
|
||||
private autoSave: boolean;
|
||||
|
||||
constructor(options: { loadFromLocalStorage: boolean, autoSave: boolean }) {
|
||||
this.autoSave = options.autoSave;
|
||||
if (options.loadFromLocalStorage) {
|
||||
const save = localStorage.getItem("drum-slayer-save");
|
||||
if (save) {
|
||||
const serial = JSON.parse(save);
|
||||
this.beats = [BeatStore.defaultMainBeatGroup()];
|
||||
this.activeBeat = Ref.new(this.beats[0]);
|
||||
this.loadFromSave(serial);
|
||||
if (this.autoSave) {
|
||||
this.activeBeat.watch(() => this.save("localStorage"), true);
|
||||
this.beats.forEach(beat => beat.addSubscriber(this, EventTypeSubscriptions));
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
this.beats = [
|
||||
BeatStore.defaultMainBeatGroup(),
|
||||
];
|
||||
this.activeBeat = Ref.new(this.beats[0]);
|
||||
}
|
||||
|
||||
notify(publisher: unknown, event: EventTypeSubscriptions): void {
|
||||
this.save("localStorage");
|
||||
}
|
||||
|
||||
static defaultMainBeatGroup(): Beat {
|
||||
const defaultSettings = {
|
||||
barCount: 2,
|
||||
isLooping: false,
|
||||
timeSigUp: 8,
|
||||
};
|
||||
const mainBeatGroup = new Beat(defaultSettings);
|
||||
mainBeatGroup.addTrack({name: "LF"});
|
||||
mainBeatGroup.addTrack({name: "LH"});
|
||||
mainBeatGroup.addTrack({name: "RH"});
|
||||
mainBeatGroup.addTrack({name: "RF"});
|
||||
return mainBeatGroup;
|
||||
}
|
||||
|
||||
getActiveBeat(): Ref<Beat> {
|
||||
return this.activeBeat;
|
||||
}
|
||||
|
||||
resetActiveBeat(): void {
|
||||
const index = this.beats.indexOf(this.activeBeat.val);
|
||||
const reset = BeatStore.defaultMainBeatGroup();
|
||||
this.beats[index] = reset;
|
||||
this.activeBeat.val = reset;
|
||||
}
|
||||
|
||||
getBeats(): Beat[] {
|
||||
return this.beats.slice();
|
||||
}
|
||||
|
||||
setActiveBeat(beat: Beat): void {
|
||||
const index = this.beats.indexOf(beat);
|
||||
if (index !== -1) {
|
||||
this.activeBeat.val = this.beats[index];
|
||||
}
|
||||
}
|
||||
|
||||
addNewBeat(): void {
|
||||
const newBeat = BeatStore.defaultMainBeatGroup();
|
||||
this.beats.push(newBeat);
|
||||
if (this.autoSave) {
|
||||
newBeat.addSubscriber(this, EventTypeSubscriptions);
|
||||
}
|
||||
this.onBeatChangeCbs.forEach(cb => cb());
|
||||
if (this.autoSave) {
|
||||
this.save("localStorage");
|
||||
}
|
||||
}
|
||||
|
||||
onBeatChanges(callback: () => void) {
|
||||
this.onBeatChangeCbs.push(callback);
|
||||
}
|
||||
|
||||
save(destination: "localStorage"): void {
|
||||
if (destination === "localStorage") {
|
||||
const serials = this.beats.map(beat => beat.serialise());
|
||||
localStorage.setItem("drum-slayer-save", JSON.stringify({
|
||||
beats: serials,
|
||||
activeBeatIndex: this.beats.indexOf(this.activeBeat.val),
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
loadFromSave(source: any): void {
|
||||
this.beats.length = 0;
|
||||
if (Array.isArray(source.beats)
|
||||
&& (typeof source.activeBeatIndex === "number" || typeof source.activeBeatIndex === "undefined")) {
|
||||
try {
|
||||
source.beats.forEach((beat: any) => this.beats.push(Beat.deserialise(beat)));
|
||||
if (typeof source.activeBeatIndex === "number") {
|
||||
this.activeBeat.val = this.beats[source.activeBeatIndex];
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user