104 lines
2.2 KiB
TypeScript
104 lines
2.2 KiB
TypeScript
import type { EncounterStore } from "@initiative/application";
|
|
import {
|
|
addCombatantUseCase,
|
|
advanceTurnUseCase,
|
|
editCombatantUseCase,
|
|
removeCombatantUseCase,
|
|
} from "@initiative/application";
|
|
import type { CombatantId, DomainEvent, Encounter } from "@initiative/domain";
|
|
import {
|
|
combatantId,
|
|
createEncounter,
|
|
isDomainError,
|
|
} from "@initiative/domain";
|
|
import { useCallback, useRef, useState } from "react";
|
|
|
|
function createDemoEncounter(): Encounter {
|
|
const result = createEncounter([
|
|
{ id: combatantId("1"), name: "Aria" },
|
|
{ id: combatantId("2"), name: "Brak" },
|
|
{ id: combatantId("3"), name: "Cael" },
|
|
]);
|
|
|
|
if (isDomainError(result)) {
|
|
throw new Error(`Failed to create demo encounter: ${result.message}`);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
export function useEncounter() {
|
|
const [encounter, setEncounter] = useState<Encounter>(createDemoEncounter);
|
|
const [events, setEvents] = useState<DomainEvent[]>([]);
|
|
const encounterRef = useRef(encounter);
|
|
encounterRef.current = encounter;
|
|
|
|
const makeStore = useCallback((): EncounterStore => {
|
|
return {
|
|
get: () => encounterRef.current,
|
|
save: (e) => setEncounter(e),
|
|
};
|
|
}, []);
|
|
|
|
const advanceTurn = useCallback(() => {
|
|
const result = advanceTurnUseCase(makeStore());
|
|
|
|
if (isDomainError(result)) {
|
|
return;
|
|
}
|
|
|
|
setEvents((prev) => [...prev, ...result]);
|
|
}, [makeStore]);
|
|
|
|
const nextId = useRef(0);
|
|
|
|
const addCombatant = useCallback(
|
|
(name: string) => {
|
|
const id = combatantId(`c-${++nextId.current}`);
|
|
const result = addCombatantUseCase(makeStore(), id, name);
|
|
|
|
if (isDomainError(result)) {
|
|
return;
|
|
}
|
|
|
|
setEvents((prev) => [...prev, ...result]);
|
|
},
|
|
[makeStore],
|
|
);
|
|
|
|
const removeCombatant = useCallback(
|
|
(id: CombatantId) => {
|
|
const result = removeCombatantUseCase(makeStore(), id);
|
|
|
|
if (isDomainError(result)) {
|
|
return;
|
|
}
|
|
|
|
setEvents((prev) => [...prev, ...result]);
|
|
},
|
|
[makeStore],
|
|
);
|
|
|
|
const editCombatant = useCallback(
|
|
(id: CombatantId, newName: string) => {
|
|
const result = editCombatantUseCase(makeStore(), id, newName);
|
|
|
|
if (isDomainError(result)) {
|
|
return;
|
|
}
|
|
|
|
setEvents((prev) => [...prev, ...result]);
|
|
},
|
|
[makeStore],
|
|
);
|
|
|
|
return {
|
|
encounter,
|
|
events,
|
|
advanceTurn,
|
|
addCombatant,
|
|
removeCombatant,
|
|
editCombatant,
|
|
} as const;
|
|
}
|