Converted draw actions storage to collapsed representation

Moved to command pattern for action application
This commit is contained in:
Mitchell McCaffrey
2021-02-04 09:11:27 +11:00
parent 2fc7f4f162
commit fa1f6fe18f
16 changed files with 366 additions and 137 deletions

View File

@@ -17,6 +17,13 @@ import Session from "./Session";
import Map from "../components/map/Map";
import Tokens from "../components/token/Tokens";
const defaultMapActions = {
mapDrawActions: [],
mapDrawActionIndex: -1,
fogDrawActions: [],
fogDrawActionIndex: -1,
};
/**
* @typedef {object} NetworkedMapProps
* @property {Session} session
@@ -225,58 +232,115 @@ function NetworkedMapAndTokens({ session }) {
setCurrentMapState(newMapState, true, true);
}
function addMapDrawActions(actions, indexKey, actionsKey) {
setCurrentMapState((prevMapState) => {
const [mapActions, setMapActions] = useState(defaultMapActions);
function addMapActions(actions, indexKey, actionsKey, shapesKey) {
setMapActions((prevMapActions) => {
const newActions = [
...prevMapState[actionsKey].slice(0, prevMapState[indexKey] + 1),
...prevMapActions[actionsKey].slice(0, prevMapActions[indexKey] + 1),
...actions,
];
const newIndex = newActions.length - 1;
return {
...prevMapState,
...prevMapActions,
[actionsKey]: newActions,
[indexKey]: newIndex,
};
});
// Update map state by performing the actions on it
setCurrentMapState((prevMapState) => {
if (prevMapState) {
let shapes = prevMapState[shapesKey];
for (let action of actions) {
shapes = action.execute(shapes);
}
return {
...prevMapState,
[shapesKey]: shapes,
};
}
});
}
function updateDrawActionIndex(change, indexKey, actionsKey) {
function updateActionIndex(change, indexKey, actionsKey, shapesKey) {
const prevIndex = mapActions[indexKey];
const newIndex = Math.min(
Math.max(currentMapState[indexKey] + change, -1),
currentMapState[actionsKey].length - 1
Math.max(mapActions[indexKey] + change, -1),
mapActions[actionsKey].length - 1
);
setCurrentMapState((prevMapState) => ({
...prevMapState,
setMapActions((prevMapActions) => ({
...prevMapActions,
[indexKey]: newIndex,
}));
// Update map state by either performing the actions or undoing them
setCurrentMapState((prevMapState) => {
if (prevMapState) {
let shapes = prevMapState[shapesKey];
if (prevIndex < newIndex) {
// Redo
for (let i = prevIndex + 1; i < newIndex + 1; i++) {
let action = mapActions[actionsKey][i];
shapes = action.execute(shapes);
}
} else {
// Undo
for (let i = prevIndex; i > newIndex; i--) {
let action = mapActions[actionsKey][i];
shapes = action.undo(shapes);
}
}
return {
...prevMapState,
[shapesKey]: shapes,
};
}
});
return newIndex;
}
function handleMapDraw(action) {
addMapDrawActions([action], "mapDrawActionIndex", "mapDrawActions");
addMapActions(
[action],
"mapDrawActionIndex",
"mapDrawActions",
"drawShapes"
);
}
function handleMapDrawUndo() {
updateDrawActionIndex(-1, "mapDrawActionIndex", "mapDrawActions");
updateActionIndex(-1, "mapDrawActionIndex", "mapDrawActions", "drawShapes");
}
function handleMapDrawRedo() {
updateDrawActionIndex(1, "mapDrawActionIndex", "mapDrawActions");
updateActionIndex(1, "mapDrawActionIndex", "mapDrawActions", "drawShapes");
}
function handleFogDraw(action) {
addMapDrawActions([action], "fogDrawActionIndex", "fogDrawActions");
addMapActions(
[action],
"fogDrawActionIndex",
"fogDrawActions",
"fogShapes"
);
}
function handleFogDrawUndo() {
updateDrawActionIndex(-1, "fogDrawActionIndex", "fogDrawActions");
updateActionIndex(-1, "fogDrawActionIndex", "fogDrawActions", "fogShapes");
}
function handleFogDrawRedo() {
updateDrawActionIndex(1, "fogDrawActionIndex", "fogDrawActions");
updateActionIndex(1, "fogDrawActionIndex", "fogDrawActions", "fogShapes");
}
useEffect(() => {
if (!currentMapState) {
setMapActions(defaultMapActions);
}
}, [currentMapState]);
function handleNoteChange(note) {
setCurrentMapState((prevMapState) => ({
...prevMapState,
@@ -495,6 +559,7 @@ function NetworkedMapAndTokens({ session }) {
<Map
map={currentMap}
mapState={currentMapState}
mapActions={mapActions}
onMapTokenStateChange={handleMapTokenStateChange}
onMapTokenStateRemove={handleMapTokenStateRemove}
onMapChange={handleMapChange}