Make boards take state and link overrides
This commit is contained in:
parent
7984f525d7
commit
65071760ec
1 changed files with 51 additions and 27 deletions
|
@ -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) {
|
||||||
|
|
Loading…
Reference in a new issue