import { DepTree } from './depTree' import update from 'immutability-helper' import { combineReducers } from 'redux'; const defaultTreeState = { byId: {}, allIds: [], tree: {}, order: {}, visible: {}, } let cache export function treeEntries(state = defaultTreeState, action) { switch (action.type) { case 'rx-sketch': return update(state, { byId: { [action.obj.obj3d.name]: { $set: action.obj } }, allIds: { $push: [action.obj.obj3d.name] }, tree: { [action.obj.obj3d.name]: { $set: {} } }, order: { [action.obj.obj3d.name]: { $set: state.allIds.length } }, visible: { [action.obj.obj3d.name]: { $set: true } }, }) case 'set-entry-visibility': { return update(state, { visible: { $merge: action.obj }, }) } case 'set-active-sketch': cache = JSON.stringify(action.sketch) return update(state, { visible: { [action.sketch.obj3d.name]: { $set: true } }, }) case 'finish-sketch': return update(state, { visible: { [sce.activeSketch.obj3d.name]: { $set: false } }, }) case 'restore-sketch': const sketch = sce.loadSketch(cache) const deletedObj = sce.obj3d.children.splice(state.order[sce.activeSketch.obj3d.name] + 1, 1, sketch.obj3d )[0] deletedObj.traverse((obj) => { if (obj.geometry) obj.geometry.dispose() if (obj.material) obj.material.dispose() }) sce.activeSketch = sketch return update(state, { byId: { [sce.activeSketch.obj3d.name]: { $set: sketch } }, }) case 'rx-extrusion': return update(state, { byId: { [action.mesh.name]: { $set: action.mesh } }, allIds: { $push: [action.mesh.name] }, tree: { [action.sketchId]: { [action.mesh.name]: { $set: true } }, [action.mesh.name]: { $set: {} } }, order: { [action.mesh.name]: { $set: state.allIds.length } }, visible: { [action.mesh.name]: { $set: true } } }) case 'rx-boolean': return update(state, { byId: { [action.mesh.name]: { $set: action.mesh } }, allIds: { $push: [action.mesh.name] }, tree: { [action.deps[0]]: { [action.mesh.name]: { $set: true } }, [action.deps[1]]: { [action.mesh.name]: { $set: true } }, [action.mesh.name]: { $set: {} } }, order: { [action.mesh.name]: { $set: state.allIds.length } } }) case 'delete-node': const depTree = new DepTree(state) const obj = depTree.deleteNode(action.id) return update(state, { $merge: obj }) case 'restore-state': return action.state case 'new-part': return defaultTreeState default: return state } } const defaultUIState = { dialog: {}, fileHandle: null, fileName: 'Untitled', selectedList: [], selectedSet: {}, help: false } export function ui(state = defaultUIState, action) { switch (action.type) { case 'set-active-sketch': case 'rx-sketch': return update(state, { sketchActive: { $set: true }, }) case 'finish-sketch': return update(state, { sketchActive: { $set: false }, }) case 'set-dialog': return update(state, { dialog: { $set: { target: action.target, action: action.action } }, mode: { $set: "" } // we clear the existing mode when entering dialog }) case 'clear-dialog': return update(state, { dialog: { $set: {} }, mode: { $set: "" } }) case 'set-file-handle': return update(state, { fileHandle: { $set: action.fileHandle }, modified: { $set: false }, }) case 'new-part': return defaultUIState case 'set-modified': return update(state, { modified: { $set: action.status }, }) case 'delete-node': case 'rx-extrusion': return update(state, { modified: { $set: true }, }) case 'restore-state': return update(state, { fileName: { $set: action.fileName }, }) case 'on-pick': const idx = state.selectedList.indexOf(action.obj) const setNeedsUpdate = action.obj.userData.type == 'mesh' || action.obj.userData.type == 'sketch' if (idx == -1) { return update(state, { selectedList: { $push: [action.obj] }, // selectedSet: { [action.obj.name]: { $set: true } } selectedSet: (curr) => setNeedsUpdate ? { ...curr, [action.obj.name]: true } : curr }) } else { if (action.obj.userData.type != 'selpoint') { return update(state, { selectedList: { $splice: [[idx, 1]] }, // selectedSet: { [action.obj.name]: { $set: false } } selectedSet: (curr) => setNeedsUpdate ? { ...curr, [action.obj.name]: false } : curr }) } else { return state } } case 'clear-selection': if (state.selectedList.length) { return update(state, { selectedList: { $set: [] }, selectedSet: { $set: {} } }) } else { return state } case 'set-mode': return update(state, { mode: { $set: action.mode } }) case 'set-help': return update(state, { help: { $set: action.status } }) case 'toggle-help': return update(state, { help: { $set: !state.help } }) default: return state } } export const reducer = combineReducers({ ui, treeEntries })