Make boards take state and link overrides

This commit is contained in:
thepaperpilot 2022-12-23 11:27:35 -06:00
parent 7984f525d7
commit 65071760ec

View file

@ -9,7 +9,7 @@ import {
Visibility Visibility
} from "features/feature"; } from "features/feature";
import { globalBus } from "game/events"; import { globalBus } from "game/events";
import type { Persistent, State } from "game/persistence"; import { DefaultValue, deletePersistent, Persistent, State } from "game/persistence";
import { persistent } from "game/persistence"; import { persistent } from "game/persistence";
import type { Unsubscribe } from "nanoevents"; import type { Unsubscribe } from "nanoevents";
import { isFunction } from "util/common"; import { isFunction } from "util/common";
@ -167,12 +167,12 @@ export interface BoardOptions {
style?: Computable<StyleValue>; style?: Computable<StyleValue>;
startNodes: () => Omit<BoardNode, "id">[]; startNodes: () => Omit<BoardNode, "id">[];
types: Record<string, NodeTypeOptions>; types: Record<string, NodeTypeOptions>;
state?: Computable<BoardData>;
links?: Computable<BoardNodeLink[] | null>;
} }
export interface BaseBoard { export interface BaseBoard {
id: string; id: string;
state: Persistent<BoardData>;
links: Ref<BoardNodeLink[] | null>;
nodes: Ref<BoardNode[]>; nodes: Ref<BoardNode[]>;
selectedNode: Ref<BoardNode | null>; selectedNode: Ref<BoardNode | null>;
selectedAction: Ref<GenericBoardNodeAction | null>; selectedAction: Ref<GenericBoardNodeAction | null>;
@ -191,6 +191,8 @@ export type Board<T extends BoardOptions> = Replace<
width: GetComputableType<T["width"]>; width: GetComputableType<T["width"]>;
classes: GetComputableType<T["classes"]>; classes: GetComputableType<T["classes"]>;
style: GetComputableType<T["style"]>; style: GetComputableType<T["style"]>;
state: GetComputableTypeWithDefault<T["state"], Persistent<BoardData>>;
links: GetComputableTypeWithDefault<T["links"], Ref<BoardNodeLink[] | null>>;
} }
>; >;
@ -198,31 +200,46 @@ export type GenericBoard = Replace<
Board<BoardOptions>, Board<BoardOptions>,
{ {
visibility: ProcessedComputable<Visibility>; visibility: ProcessedComputable<Visibility>;
state: ProcessedComputable<BoardData>;
links: ProcessedComputable<BoardNodeLink[] | null>;
} }
>; >;
export function createBoard<T extends BoardOptions>( export function createBoard<T extends BoardOptions>(
optionsFunc: OptionsFunc<T, BaseBoard, GenericBoard> optionsFunc: OptionsFunc<T, BaseBoard, GenericBoard>
): Board<T> { ): Board<T> {
const state = persistent<BoardData>({
nodes: [],
selectedNode: null,
selectedAction: null
});
return createLazyProxy(() => { return createLazyProxy(() => {
const board = optionsFunc(); const board = optionsFunc();
board.id = getUniqueID("board-"); board.id = getUniqueID("board-");
board.type = BoardType; board.type = BoardType;
board[Component] = BoardComponent; board[Component] = BoardComponent;
board.state = persistent<BoardData>({ if (board.state) {
deletePersistent(state);
processComputable(board as T, "state");
} else {
state[DefaultValue] = {
nodes: board.startNodes().map((n, i) => { nodes: board.startNodes().map((n, i) => {
(n as BoardNode).id = i; (n as BoardNode).id = i;
return n as BoardNode; return n as BoardNode;
}), }),
selectedNode: null, selectedNode: null,
selectedAction: null selectedAction: null
}); };
board.nodes = computed(() => processedBoard.state.value.nodes); board.state = state;
}
board.nodes = computed(() => unref(processedBoard.state).nodes);
board.selectedNode = computed( board.selectedNode = computed(
() => () =>
processedBoard.nodes.value.find( processedBoard.nodes.value.find(
node => node.id === processedBoard.state.value.selectedNode node => node.id === unref(processedBoard.state).selectedNode
) || null ) || null
); );
board.selectedAction = computed(() => { board.selectedAction = computed(() => {
@ -236,16 +253,22 @@ export function createBoard<T extends BoardOptions>(
} }
return ( return (
type.actions.find( type.actions.find(
action => action.id === processedBoard.state.value.selectedAction action => action.id === unref(processedBoard.state).selectedAction
) || null ) || null
); );
}); });
board.mousePosition = ref(null); board.mousePosition = ref(null);
if (board.links) {
processComputable(board as T, "links");
} else {
board.links = computed(() => { board.links = computed(() => {
if (processedBoard.selectedAction.value == null) { if (processedBoard.selectedAction.value == null) {
return null; return null;
} }
if (processedBoard.selectedAction.value.links && processedBoard.selectedNode.value) { if (
processedBoard.selectedAction.value.links &&
processedBoard.selectedNode.value
) {
return getNodeProperty( return getNodeProperty(
processedBoard.selectedAction.value.links, processedBoard.selectedAction.value.links,
processedBoard.selectedNode.value processedBoard.selectedNode.value
@ -253,6 +276,7 @@ export function createBoard<T extends BoardOptions>(
} }
return null; return null;
}); });
}
processComputable(board as T, "visibility"); processComputable(board as T, "visibility");
setDefault(board, "visibility", Visibility.Visible); setDefault(board, "visibility", Visibility.Visible);
processComputable(board as T, "width"); processComputable(board as T, "width");
@ -286,10 +310,10 @@ export function createBoard<T extends BoardOptions>(
processComputable(nodeType as NodeTypeOptions, "actionDistance"); processComputable(nodeType as NodeTypeOptions, "actionDistance");
setDefault(nodeType, "actionDistance", Math.PI / 6); setDefault(nodeType, "actionDistance", Math.PI / 6);
nodeType.nodes = computed(() => nodeType.nodes = computed(() =>
processedBoard.state.value.nodes.filter(node => node.type === type) unref(processedBoard.state).nodes.filter(node => node.type === type)
); );
setDefault(nodeType, "onClick", function (node: BoardNode) { setDefault(nodeType, "onClick", function (node: BoardNode) {
processedBoard.state.value.selectedNode = node.id; unref(processedBoard.state).selectedNode = node.id;
}); });
if (nodeType.actions) { if (nodeType.actions) {