Skip to content

Commit

Permalink
fix: Improves Bestiary event registration
Browse files Browse the repository at this point in the history
  • Loading branch information
valentine195 committed Mar 8, 2024
1 parent b25bebd commit a0870e3
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 41 deletions.
8 changes: 8 additions & 0 deletions src/api/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,14 @@ declare global {
declare module "obsidian" {
interface Workspace {
on(name: "fantasy-statblocks:loaded", callback: () => void): EventRef;
on(
name: "fantasy-statblocks:bestiary:resolved",
callback: () => void
): EventRef;
on(
name: "fantasy-statblocks:bestiary:updated",
callback: () => void
): EventRef;
}
}
export class API {
Expand Down
114 changes: 75 additions & 39 deletions src/bestiary/bestiary.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,43 @@ import type StatBlockPlugin from "src/main";
import { Watcher } from "src/watcher/watcher";
import { BESTIARY_BY_NAME } from "./srd-bestiary";
import { stringify } from "src/util/util";
import type { EventRef, Events, Workspace } from "obsidian";

declare module "obsidian" {
interface Workspace {
trigger(name: "fantasy-statblocks:bestiary:resolved"): void;
trigger(name: "fantasy-statblocks:bestiary:updated"): void;
trigger<T extends string>(
name: `fantasy-statblocks:bestiary:indexed:${T}`
): void;
trigger<T extends string>(
name: `fantasy-statblocks:bestiary:sorted:${T}`,
values: Array<Monster>
): void;
on<T extends string>(
name: `fantasy-statblocks:bestiary:indexed:${T}`,
callback: () => void
): EventRef;
on<T extends string>(
name: `fantasy-statblocks:bestiary:sorted:${T}`,
callback: (values: Array<Monster>) => void
): EventRef;
}
}

class BestiaryClass {
#bestiary: Map<string, Monster> = new Map();
#local: Map<string, Monster> = new Map();
#ephemeral: Map<string, Monster> = new Map();

#resolved = false;
#resolveCallbacks: Array<() => void> = [];
#updatedCallbacks: Array<() => void> = [];

enableSRD: boolean;

#indices: Map<string, Map<string, Set<string>>> = new Map();
#indexCallbacks: Map<string, Array<() => void>> = new Map();

#sorters: Map<string, (a: Monster, b: Monster) => number> = new Map();
#sorted: Map<string, Array<Monster>> = new Map();
#sortedCallbacks: Map<string, Array<(values: Array<Monster>) => void>> =
new Map();

getSortedBy(field: string): Array<Monster> {
return this.#sorted.get(field) ?? [];
Expand All @@ -31,15 +49,14 @@ class BestiaryClass {
field: string,
cb: (values: Array<Monster>) => void
): () => void {
if (!this.#sortedCallbacks.has(field)) {
this.#sortedCallbacks.set(field, []);
}
this.#sortedCallbacks.get(field).push(cb);
console.log(
"🚀 ~ file: bestiary.ts:40 ~ this.#sortedCallbacks.get(field):",
this.#sortedCallbacks.get(field)
let ref = this.#events.on(
`fantasy-statblocks:bestiary:sorted:${field}`,
(values) => cb(values)
);
return () => this.#sortedCallbacks.get(field)?.remove(cb);

return () => {
this.#events.offref(ref);
};
}

registerSorter(
Expand All @@ -64,9 +81,10 @@ class BestiaryClass {
this.#sorters.get(field)(a, b)
)
);
for (const callback of this.#sortedCallbacks.get(field) ?? []) {
callback(this.getSortedBy(field));
}
this.#events.trigger(
`fantasy-statblocks:bestiary:sorted:${field}`,
this.getSortedBy(field)
);
}
}, 0);
}
Expand All @@ -83,21 +101,24 @@ class BestiaryClass {
}

onIndexUpdated(index: string, callback: () => void): () => void {
if (!this.#indices.has(index)) return;
if (!this.#indexCallbacks.has(index)) {
this.#indexCallbacks.set(index, []);
}
this.#indexCallbacks.get(index)?.push(callback);
if (!this.#indices.has(index)) return () => {};
let ref: EventRef = this.#events.on(
`fantasy-statblocks:bestiary:indexed:${index}`,
() => callback()
);

return () => {
this.#indexCallbacks.get(index)?.remove(callback);
this.#events.offref(ref);
};
}

#events: Workspace;
initialize(plugin: StatBlockPlugin) {
this.registerIndex("source");
this.registerSorter("name", (a, b) => a.name.localeCompare(b.name));

Watcher.initialize(plugin).load();

this.#events = plugin.app.workspace;
plugin.addCommand({
id: "parse-frontmatter",
name: "Parse Frontmatter for Creatures",
Expand Down Expand Up @@ -143,9 +164,9 @@ class BestiaryClass {
map.get(value).add(creature.name);
}

for (const cb of this.#indexCallbacks?.get(field) ?? []) {
cb();
}
this.#events.trigger(
`fantasy-statblocks:bestiary:indexed:${field}`
);
}
}
}, 0);
Expand All @@ -158,9 +179,9 @@ class BestiaryClass {
if (map.has(value)) {
map.get(value).delete(creature.name);
}
for (const cb of this.#indexCallbacks?.get(field) ?? []) {
cb();
}
this.#events.trigger(
`fantasy-statblocks:bestiary:indexed:${field}`
);
}
}
}, 0);
Expand Down Expand Up @@ -217,37 +238,52 @@ class BestiaryClass {
setResolved(resolved: boolean) {
this.#resolved = resolved;
if (resolved) {
for (const callback of this.#resolveCallbacks) {
callback();
}
/* for (const callback of this.#resolveCallbacks) {
try {
callback();
} catch (e) {
console.log("🚀 ~ file: bestiary.ts:224 ~ e:", e);
}
} */
this.#events.trigger("fantasy-statblocks:bestiary:resolved");

this.#triggerUpdatedCallbacks();
this.#triggerSort();
}
}

onResolved(callback: () => void): () => void {
let ref: EventRef;
if (this.isResolved()) {
callback();
} else {
this.#resolveCallbacks.push(callback);
ref = this.#events.on("fantasy-statblocks:bestiary:resolved", () =>
callback()
);
}
return () => {
this.#resolveCallbacks?.remove(callback);
if (!ref) return;
this.#events.offref(ref);
};
}
onUpdated(callback: () => void): () => void {
this.#updatedCallbacks.push(callback);
let ref: EventRef;
if (this.isResolved()) {
callback();
} else {
ref = this.#events.on("fantasy-statblocks:bestiary:updated", () =>
callback()
);
}
return () => {
this.#updatedCallbacks?.remove(callback);
if (!ref) return;
this.#events.offref(ref);
};
}

#triggerUpdatedCallbacks() {
if (this.isResolved()) {
for (const callback of this.#updatedCallbacks) {
callback();
}
this.#events.trigger("fantasy-statblocks:bestiary:updated");
}
}
size() {
Expand Down
9 changes: 8 additions & 1 deletion src/settings/creatures/Creatures.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import { Setting, prepareSimpleSearch } from "obsidian";
import type { Monster } from "index";
import { derived, writable } from "svelte/store";
import { onDestroy } from "svelte";
export let plugin: StatBlockPlugin;
Expand All @@ -18,7 +19,13 @@
export let paddingTop: string;
const creatures = writable(Bestiary.getBestiaryCreatures());
Bestiary.onSortedBy("name", (values) => ($creatures = values));
let ref = Bestiary.onSortedBy("name", (values) => {
$creatures = values;
});
onDestroy(() => {
ref();
});
const slice = writable(50);
const page = writable(1);
Expand Down
6 changes: 5 additions & 1 deletion src/settings/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ export default class StatblockSettingTab extends PluginSettingTab {
importer: Importer;
results: Partial<Monster>[] = [];
filter: Setting;
$UI: Creatures;
constructor(app: App, private plugin: StatBlockPlugin) {
super(app, plugin);
this.importer = new Importer(this.plugin);
Expand Down Expand Up @@ -983,7 +984,7 @@ export default class StatblockSettingTab extends PluginSettingTab {
const ancestor = this.containerEl.closest(".statblock-settings");
const { backgroundColor, paddingTop } = getComputedStyle(ancestor);

new Creatures({
this.$UI = new Creatures({
target: additionalContainer,
props: {
plugin: this.plugin,
Expand All @@ -992,6 +993,9 @@ export default class StatblockSettingTab extends PluginSettingTab {
}
});
}
override hide() {
this.$UI.$destroy();
}
}

class CreateStatblockModal extends FantasyStatblockModal {
Expand Down

0 comments on commit a0870e3

Please sign in to comment.