From 85141faae18338cde1e8a957f8f5df0d3039fcdc Mon Sep 17 00:00:00 2001 From: Florian Demmer Date: Tue, 31 Dec 2024 15:24:16 +0000 Subject: [PATCH 1/3] use instanceId as string rather than interpreting it constantly as integer index value --- src/actions/editor.ts | 4 +- src/actions/graph.ts | 22 ++-- src/actions/patchers.ts | 90 ++++++++-------- src/actions/sets.ts | 24 ++--- src/components/editor/index.tsx | 2 +- src/components/editor/patcherNode.tsx | 2 +- src/components/midi/mappedParameterItem.tsx | 4 +- src/components/midi/mappedParameterList.tsx | 8 +- src/components/nav/index.tsx | 10 +- .../parameter/withSetViewActions.tsx | 2 +- src/controller/oscqueryBridgeController.ts | 81 +++++++------- src/lib/constants.ts | 2 +- src/lib/util.ts | 2 +- src/models/graph.ts | 8 +- src/models/instance.ts | 12 +-- src/models/messageport.ts | 14 +-- src/models/parameter.ts | 16 +-- src/models/set.ts | 16 ++- src/pages/instances/[index].tsx | 24 +++-- src/pages/midimappings.tsx | 13 ++- src/reducers/graph.ts | 16 +-- src/reducers/patchers.ts | 14 +-- src/selectors/graph.ts | 32 +++--- src/selectors/patchers.ts | 102 +++++++----------- src/selectors/sets.ts | 9 +- 25 files changed, 250 insertions(+), 279 deletions(-) diff --git a/src/actions/editor.ts b/src/actions/editor.ts index 0858c7bc..b0e46383 100644 --- a/src/actions/editor.ts +++ b/src/actions/editor.ts @@ -11,7 +11,7 @@ import { oscQueryBridge } from "../controller/oscqueryBridgeController"; import { isValidConnection } from "../lib/editorUtils"; import throttle from "lodash.throttle"; import { OSCQuerySetMeta } from "../lib/types"; -import { setConnection, setNode, setNodes, unloadPatcherNodeByIndexOnRemote } from "./graph"; +import { setConnection, setNode, setNodes, unloadPatcherNodeOnRemote } from "./graph"; import { getGraphEditorInstance, getGraphEditorLockedState } from "../selectors/editor"; import { defaultNodeGap } from "../lib/constants"; @@ -191,7 +191,7 @@ export const removeEditorNodeById = (id: GraphNode["id"], updateSetMeta = true): throw new Error(`System nodes cannot be removed (id: ${id}).`); } - dispatch(unloadPatcherNodeByIndexOnRemote(node.index)); + dispatch(unloadPatcherNodeOnRemote(node.instanceId)); if (updateSetMeta) doUpdateNodesMeta(getNodes(state).delete(node.id)); } catch (err) { diff --git a/src/actions/graph.ts b/src/actions/graph.ts index 66c2f8a8..e1eaf2dd 100644 --- a/src/actions/graph.ts +++ b/src/actions/graph.ts @@ -4,7 +4,7 @@ import { oscQueryBridge } from "../controller/oscqueryBridgeController"; import { ActionBase, AppThunk, RootStateType } from "../lib/store"; import { OSCQueryRNBOInstance, OSCQueryRNBOInstancesState, OSCQueryRNBOJackConnections, OSCQueryRNBOJackPortInfo, OSCQuerySetMeta, OSCQuerySetNodeMeta } from "../lib/types"; import { ConnectionType, GraphConnectionRecord, GraphControlNodeRecord, GraphNodeRecord, GraphPatcherNodeRecord, GraphPortRecord, GraphSystemNodeRecord, NodeType, PortDirection, calculateNodeContentHeight, createNodePorts } from "../models/graph"; -import { getConnectionsForSourceNodeAndPort, getNode, getPatcherNodeByIndex, getNodes, getSystemNodeByJackNameAndDirection, getConnections, getPatcherNodes, getSystemNodes, getControlNodes } from "../selectors/graph"; +import { getConnectionsForSourceNodeAndPort, getNode, getPatcherNodeByInstanceId, getNodes, getSystemNodeByJackNameAndDirection, getConnections, getPatcherNodes, getSystemNodes, getControlNodes } from "../selectors/graph"; import { showNotification } from "./notifications"; import { NotificationLevel } from "../models/notification"; import { PatcherInstanceRecord } from "../models/instance"; @@ -362,9 +362,9 @@ export const initNodes = (jackPortsInfo: OSCQueryRNBOJackPortInfo, instanceInfo: patcherAndControlNodes.push(node); const instance = PatcherInstanceRecord.fromDescription(info); instances.push(instance); - instanceParameters.push(...ParameterRecord.fromDescription(instance.index, info.CONTENTS.params)); - instanceMessageInports.push(...MessagePortRecord.fromDescription(instance.index, info.CONTENTS.messages?.CONTENTS?.in)); - instanceMessageOutports.push(...MessagePortRecord.fromDescription(instance.index, info.CONTENTS.messages?.CONTENTS?.out)); + instanceParameters.push(...ParameterRecord.fromDescription(instance.id, info.CONTENTS.params)); + instanceMessageInports.push(...MessagePortRecord.fromDescription(instance.id, info.CONTENTS.messages?.CONTENTS?.in)); + instanceMessageOutports.push(...MessagePortRecord.fromDescription(instance.id, info.CONTENTS.messages?.CONTENTS?.out)); } // Build a list of all Jack generated names that have not been used for PatcherNodes above @@ -607,14 +607,14 @@ export const updateSystemOrControlPortInfo = (type: ConnectionType, direction: P }; // Trigger Updates on remote OSCQuery Runner -export const unloadPatcherNodeByIndexOnRemote = (instanceIndex: number): AppThunk => +export const unloadPatcherNodeOnRemote = (instanceId: string): AppThunk => (dispatch) => { try { const message = { address: "/rnbo/inst/control/unload", args: [ - { type: "i", value: instanceIndex } + { type: "i", value: parseInt(instanceId, 10) } ] }; oscQueryBridge.sendPacket(writePacket(message)); @@ -695,9 +695,9 @@ export const addPatcherNode = (desc: OSCQueryRNBOInstance, metaString: string): // Create Instance State const instance = PatcherInstanceRecord.fromDescription(desc); - const parameters = ParameterRecord.fromDescription(instance.index, desc.CONTENTS.params); - const messageInports = MessagePortRecord.fromDescription(instance.index, desc.CONTENTS.messages?.CONTENTS?.in); - const messageOutports = MessagePortRecord.fromDescription(instance.index, desc.CONTENTS.messages?.CONTENTS?.out); + const parameters = ParameterRecord.fromDescription(instance.id, desc.CONTENTS.params); + const messageInports = MessagePortRecord.fromDescription(instance.id, desc.CONTENTS.messages?.CONTENTS?.in); + const messageOutports = MessagePortRecord.fromDescription(instance.id, desc.CONTENTS.messages?.CONTENTS?.out); dispatch(setInstance(instance)); dispatch(setInstanceParameters(parameters)); @@ -705,12 +705,12 @@ export const addPatcherNode = (desc: OSCQueryRNBOInstance, metaString: string): dispatch(setInstanceMessageOutports(messageOutports)); }; -export const removePatcherNode = (index: number): AppThunk => +export const removePatcherNode = (instanceId: string): AppThunk => (dispatch, getState) => { try { const state = getState(); - const node = getPatcherNodeByIndex(state, index); + const node = getPatcherNodeByInstanceId(state, instanceId); if (node?.type !== NodeType.Patcher) return; dispatch(deleteNode(node)); diff --git a/src/actions/patchers.ts b/src/actions/patchers.ts index ba1135b0..a7d18b91 100644 --- a/src/actions/patchers.ts +++ b/src/actions/patchers.ts @@ -2,7 +2,7 @@ import Router from "next/router"; import { ActionBase, AppThunk } from "../lib/store"; import { MIDIMetaMapping, OSCQueryRNBOInstance, OSCQueryRNBOInstancePresetEntries, OSCQueryRNBOPatchersState, OSCValue, ParameterMetaJsonMap } from "../lib/types"; import { PatcherInstanceRecord } from "../models/instance"; -import { getPatcherInstanceByIndex, getPatcherInstance, getPatcherInstanceParametersByInstanceIndex, getPatcherInstanceMessageInportsByInstanceIndex, getPatcherInstanceMesssageOutportsByInstanceIndex, getPatcherInstanceMessageInportByPath, getPatcherInstanceMessageOutportByPath, getPatcherInstanceMesssageOutportsByInstanceIndexAndTag, getPatcherInstanceParameterByPath, getPatcherInstanceParametersByInstanceIndexAndName, getPatcherInstanceMessageInportsByInstanceIndexAndTag } from "../selectors/patchers"; +import { getPatcherInstance, getPatcherInstanceParametersByInstanceId, getPatcherInstanceMessageInportsByInstanceId, getPatcherInstanceMesssageOutportsByInstanceId, getPatcherInstanceMessageInportByPath, getPatcherInstanceMessageOutportByPath, getPatcherInstanceMesssageOutportsByInstanceIdAndTag, getPatcherInstanceParameterByPath, getPatcherInstanceParametersByInstanceIdAndName, getPatcherInstanceMessageInportsByInstanceIdAndTag } from "../selectors/patchers"; import { getAppSetting } from "../selectors/settings"; import { ParameterRecord } from "../models/parameter"; import { MessagePortRecord } from "../models/messageport"; @@ -455,7 +455,7 @@ export const sendInstanceMessageToRemote = (instance: PatcherInstanceRecord, inp const message = { - address: `/rnbo/inst/${instance.index}/messages/in/${inportId}`, + address: `/rnbo/inst/${instance.id}/messages/in/${inportId}`, args: values }; oscQueryBridge.sendPacket(writePacket(message)); @@ -547,7 +547,7 @@ export const activateParameterMIDIMappingFocus = (param: ParameterRecord): AppTh (dispatch, getState) => { const state = getState(); - const params = getPatcherInstanceParametersByInstanceIndex(state, param.instanceIndex); + const params = getPatcherInstanceParametersByInstanceId(state, param.instanceId); dispatch(setInstanceParameters( params.valueSeq().toArray().map(p => p.setWaitingForMidiMapping(p.id === param.id)) @@ -640,11 +640,11 @@ export const restoreDefaultMessagePortMetaOnRemote = (_instance: PatcherInstance }; // Updates in response to remote OSCQuery Updates -export const updateInstancePresetEntries = (index: number, entries: OSCQueryRNBOInstancePresetEntries): AppThunk => +export const updateInstancePresetEntries = (instanceId: string, entries: OSCQueryRNBOInstancePresetEntries): AppThunk => (dispatch, getState) => { try { const state = getState(); - const instance = getPatcherInstanceByIndex(state, index); + const instance = getPatcherInstance(state, instanceId); if (!instance) return; dispatch(setInstance(instance.updatePresets(entries))); @@ -653,11 +653,11 @@ export const updateInstancePresetEntries = (index: number, entries: OSCQueryRNBO } }; -export const updateInstancePresetLatest = (index: number, name: string): AppThunk => +export const updateInstancePresetLatest = (instanceId: string, name: string): AppThunk => (dispatch, getState) => { try { const state = getState(); - const instance = getPatcherInstanceByIndex(state, index); + const instance = getPatcherInstance(state, instanceId); if (!instance) return; dispatch(setInstance(instance.setPresetLatest(name))); @@ -666,11 +666,11 @@ export const updateInstancePresetLatest = (index: number, name: string): AppThun } }; -export const updateInstancePresetInitial = (index: number, name: string): AppThunk => +export const updateInstancePresetInitial = (instanceId: string, name: string): AppThunk => (dispatch, getState) => { try { const state = getState(); - const instance = getPatcherInstanceByIndex(state, index); + const instance = getPatcherInstance(state, instanceId); if (!instance) return; dispatch(setInstance(instance.setPresetInitial(name))); @@ -679,22 +679,22 @@ export const updateInstancePresetInitial = (index: number, name: string): AppThu } }; -export const updateInstanceMessages = (index: number, desc: OSCQueryRNBOInstance["CONTENTS"]["messages"]): AppThunk => +export const updateInstanceMessages = (instanceId: string, desc: OSCQueryRNBOInstance["CONTENTS"]["messages"]): AppThunk => (dispatch, getState) => { try { if (!desc) return; const state = getState(); - const instance = getPatcherInstanceByIndex(state, index); + const instance = getPatcherInstance(state, instanceId); if (!instance) return; - const currentMessageInports = getPatcherInstanceMessageInportsByInstanceIndex(state, instance.index); - const currentMessageOutports = getPatcherInstanceMesssageOutportsByInstanceIndex(state, instance.index); + const currentMessageInports = getPatcherInstanceMessageInportsByInstanceId(state, instance.id); + const currentMessageOutports = getPatcherInstanceMesssageOutportsByInstanceId(state, instance.id); dispatch(deleteInstanceMessageInports(currentMessageInports.valueSeq().toArray())); dispatch(deleteInstanceMessageOutports(currentMessageOutports.valueSeq().toArray())); - const messageInports = MessagePortRecord.fromDescription(instance.index, desc.CONTENTS?.in); - const messageOutports = MessagePortRecord.fromDescription(instance.index, desc.CONTENTS?.out); + const messageInports = MessagePortRecord.fromDescription(instance.id, desc.CONTENTS?.in); + const messageOutports = MessagePortRecord.fromDescription(instance.id, desc.CONTENTS?.out); dispatch(setInstanceMessageInports(messageInports)); dispatch(setInstanceMessageOutports(messageOutports)); @@ -730,7 +730,7 @@ export const removeInstanceMessageOutportByPath = (path: string): AppThunk => } }; -export const updateInstanceMessageOutportValue = (index: number, tag: MessagePortRecord["tag"], value: OSCValue | OSCValue[]): AppThunk => +export const updateInstanceMessageOutportValue = (instanceId: string, tag: MessagePortRecord["tag"], value: OSCValue | OSCValue[]): AppThunk => (dispatch, getState) => { try { @@ -741,12 +741,12 @@ export const updateInstanceMessageOutportValue = (index: number, tag: MessagePor if (!enabled) return; // Active Instance view?! - if (Router.pathname !== "/instances/[index]" || Router.query.index !== `${index}`) return; + if (Router.pathname !== "/instances/[index]" || Router.query.index !== `${instanceId}`) return; - const instance = getPatcherInstanceByIndex(state, index); + const instance = getPatcherInstance(state, instanceId); if (!instance) return; - const port = getPatcherInstanceMesssageOutportsByInstanceIndexAndTag(state, instance.index, tag); + const port = getPatcherInstanceMesssageOutportsByInstanceIdAndTag(state, instance.id, tag); if (!port) return; dispatch(setInstanceMessageOutport(port.setValue(Array.isArray(value) ? value.join(", ") : `${value}`))); @@ -768,31 +768,31 @@ export const removeInstanceParameterByPath = (path: string): AppThunk => } }; -export const updateInstanceParameters = (index: number, desc: OSCQueryRNBOInstance["CONTENTS"]["params"]): AppThunk => +export const updateInstanceParameters = (instanceId: string, desc: OSCQueryRNBOInstance["CONTENTS"]["params"]): AppThunk => (dispatch, getState) => { try { if (!desc) return; const state = getState(); - const instance = getPatcherInstanceByIndex(state, index); + const instance = getPatcherInstance(state, instanceId); if (!instance) return; - const currentParams = getPatcherInstanceParametersByInstanceIndex(state, instance.index); + const currentParams = getPatcherInstanceParametersByInstanceId(state, instance.id); dispatch(deleteInstanceParameters(currentParams.valueSeq().toArray())); - const newParams = ParameterRecord.fromDescription(instance.index, desc); + const newParams = ParameterRecord.fromDescription(instance.id, desc); dispatch(setInstanceParameters(newParams)); } catch (e) { console.log(e); } }; -export const updateInstanceDataRefValue = (index: number, name: string, value: string): AppThunk => +export const updateInstanceDataRefValue = (instanceId: string, name: string, value: string): AppThunk => (dispatch, getState) => { try { const state = getState(); - const instance = getPatcherInstanceByIndex(state, index); + const instance = getPatcherInstance(state, instanceId); if (!instance) return; dispatch(setInstance( @@ -803,11 +803,11 @@ export const updateInstanceDataRefValue = (index: number, name: string, value: s } }; -export const updateInstanceParameterValue = (index: number, name: ParameterRecord["name"], value: number): AppThunk => +export const updateInstanceParameterValue = (instanceId: string, name: ParameterRecord["name"], value: number): AppThunk => (dispatch, getState) => { try { const state = getState(); - const param = getPatcherInstanceParametersByInstanceIndexAndName(state, index, name); + const param = getPatcherInstanceParametersByInstanceIdAndName(state, instanceId, name); if (!param) return; dispatch(setInstanceParameter(param.setValue(value))); @@ -816,11 +816,11 @@ export const updateInstanceParameterValue = (index: number, name: ParameterRecor } }; -export const updateInstanceParameterValueNormalized = (index: number, name: ParameterRecord["name"], value: number): AppThunk => +export const updateInstanceParameterValueNormalized = (instanceId: string, name: ParameterRecord["name"], value: number): AppThunk => (dispatch, getState) => { try { const state = getState(); - const param = getPatcherInstanceParametersByInstanceIndexAndName(state, index, name); + const param = getPatcherInstanceParametersByInstanceIdAndName(state, instanceId, name); if (!param) return; dispatch(setInstanceParameter(param.setNormalizedValue(value))); @@ -837,7 +837,7 @@ export const setInstanceWaitingForMidiMappingOnRemote = (id: PatcherInstanceReco if (!instance) return; dispatch(setInstance(instance.setWaitingForMapping(value))); - const params = getPatcherInstanceParametersByInstanceIndex(state, instance.index).valueSeq().map(p => p.setWaitingForMidiMapping(false)); + const params = getPatcherInstanceParametersByInstanceId(state, instance.id).valueSeq().map(p => p.setWaitingForMidiMapping(false)); dispatch(setInstanceParameters(params.toArray())); try { @@ -861,34 +861,34 @@ export const setInstanceWaitingForMidiMappingOnRemote = (id: PatcherInstanceReco } }; -export const updateInstanceMIDIReport = (index: number, value: boolean): AppThunk => +export const updateInstanceMIDIReport = (instanceId: string, value: boolean): AppThunk => (dispatch, getState) => { try { const state = getState(); - const instance = getPatcherInstanceByIndex(state, index); + const instance = getPatcherInstance(state, instanceId); if (!instance) return; dispatch(setInstance(instance.setWaitingForMapping(value))); - const params = getPatcherInstanceParametersByInstanceIndex(state, instance.index).valueSeq().map(p => p.setWaitingForMidiMapping(false)); + const params = getPatcherInstanceParametersByInstanceId(state, instance.id).valueSeq().map(p => p.setWaitingForMidiMapping(false)); dispatch(setInstanceParameters(params.toArray())); } catch (e) { console.log(e); } }; -export const updateInstanceMIDILastValue = (index: number, value: string): AppThunk => +export const updateInstanceMIDILastValue = (instanceId: string, value: string): AppThunk => (dispatch, getState) => { try { const state = getState(); - const instance = getPatcherInstanceByIndex(state, index); + const instance = getPatcherInstance(state, instanceId); if (!instance?.waitingForMidiMapping) return; const midiMeta = JSON.parse(value); // find waiting, update their meta, set them no longer waiting and update map const parameters: ParameterRecord[] = []; - getPatcherInstanceParametersByInstanceIndex(state, instance.index).forEach(param => { + getPatcherInstanceParametersByInstanceId(state, instance.id).forEach(param => { if (param.waitingForMidiMapping) { const meta = cloneJSON(param.meta); meta.midi = midiMeta; @@ -912,11 +912,11 @@ export const updateInstanceMIDILastValue = (index: number, value: string): AppTh } }; -export const updateInstanceParameterMeta = (index: number, name: ParameterRecord["name"], value: string): AppThunk => +export const updateInstanceParameterMeta = (instanceId: string, name: ParameterRecord["name"], value: string): AppThunk => (dispatch, getState) => { try { const state = getState(); - const param = getPatcherInstanceParametersByInstanceIndexAndName(state, index, name); + const param = getPatcherInstanceParametersByInstanceIdAndName(state, instanceId, name); if (!param) return; dispatch(setInstanceParameter(param.setMeta(value))); @@ -925,15 +925,15 @@ export const updateInstanceParameterMeta = (index: number, name: ParameterRecord } }; -export const updateInstanceMessageOutportMeta = (index: number, tag: MessagePortRecord["tag"], value: string): AppThunk => +export const updateInstanceMessageOutportMeta = (instanceId: string, tag: MessagePortRecord["tag"], value: string): AppThunk => (dispatch, getState) => { try { const state = getState(); - const instance = getPatcherInstanceByIndex(state, index); + const instance = getPatcherInstance(state, instanceId); if (!instance) return; - const port = getPatcherInstanceMessageInportsByInstanceIndexAndTag(state, instance.index, tag); + const port = getPatcherInstanceMessageInportsByInstanceIdAndTag(state, instance.id, tag); if (!port) return; dispatch(setInstanceMessageOutport(port.setMeta(value))); @@ -942,14 +942,14 @@ export const updateInstanceMessageOutportMeta = (index: number, tag: MessagePort } }; -export const updateInstanceMessageInportMeta = (index: number, tag: MessagePortRecord["tag"], value: string): AppThunk => +export const updateInstanceMessageInportMeta = (instanceId: string, tag: MessagePortRecord["tag"], value: string): AppThunk => (dispatch, getState) => { try { const state = getState(); - const instance = getPatcherInstanceByIndex(state, index); + const instance = getPatcherInstance(state, instanceId); if (!instance) return; - const port = getPatcherInstanceMessageInportsByInstanceIndexAndTag(state, instance.index, tag); + const port = getPatcherInstanceMessageInportsByInstanceIdAndTag(state, instance.id, tag); if (!port) return; dispatch(setInstanceMessageInport(port.setMeta(value))); @@ -957,5 +957,3 @@ export const updateInstanceMessageInportMeta = (index: number, tag: MessagePortR console.log(e); } }; - -// Events from remote diff --git a/src/actions/sets.ts b/src/actions/sets.ts index 2c3bb44b..dff97fa2 100644 --- a/src/actions/sets.ts +++ b/src/actions/sets.ts @@ -6,7 +6,7 @@ import { PresetRecord } from "../models/preset"; import { showNotification } from "./notifications"; import { NotificationLevel } from "../models/notification"; import { ParameterRecord } from "../models/parameter"; -import { getPatcherInstanceByIndex, getPatcherInstanceParamtersSortedByIndex } from "../selectors/patchers"; +import { getPatcherInstance, getPatcherInstanceParamtersSortedByInstanceIdAndIndex } from "../selectors/patchers"; import { OSCQueryRNBOSetView, OSCQueryRNBOSetViewListState } from "../lib/types"; import { getGraphSetView, getGraphSetViews } from "../selectors/sets"; import { clamp, getUniqueName, instanceAndParamIndicesToSetViewEntry } from "../lib/util"; @@ -333,7 +333,7 @@ export const createSetViewOnRemote = (givenName: string): AppThunk => (dispatch, getState) => { try { const state = getState(); - const params = getPatcherInstanceParamtersSortedByIndex(state); + const params = getPatcherInstanceParamtersSortedByInstanceIdAndIndex(state); const existingViews = getGraphSetViews(state); const name = getUniqueName(givenName, existingViews.valueSeq().map(v => v.name).toArray()); @@ -473,15 +473,15 @@ export const updateSetViewParameterListOnRemote = (setView: GraphSetViewRecord, export const offsetParameterIndexInSetView = (setView: GraphSetViewRecord, param: ParameterRecord, offset: number): AppThunk => (dispatch) => { try { - const currentIndex = setView.params.findIndex(entry => entry.instanceIndex === param.instanceIndex && entry.paramIndex === param.index); + const currentIndex = setView.params.findIndex(entry => entry.instanceId === param.instanceId && entry.paramIndex === param.index); const newIndex = clamp(currentIndex + offset, 0, setView.params.size - 1); const newList = setView.params .delete(currentIndex) - .insert(newIndex, { instanceIndex: param.instanceIndex, paramIndex: param.index }); + .insert(newIndex, { instanceId: param.instanceId, paramIndex: param.index }); const message = { address: `/rnbo/inst/control/sets/views/list/${setView.id}/params`, - args: newList.toArray().map(p => ({ type: "s", value: instanceAndParamIndicesToSetViewEntry(p.instanceIndex, p.paramIndex) })) + args: newList.toArray().map(p => ({ type: "s", value: instanceAndParamIndicesToSetViewEntry(p.instanceId, p.paramIndex) })) }; oscQueryBridge.sendPacket(writePacket(message)); } catch (err) { @@ -550,7 +550,7 @@ export const addParameterToSetView = (setView: GraphSetViewRecord, param: Parame try { if (setView.paramIds.has(param.setViewId)) return; const params = setView.paramIds.toArray().map(pId => ({ type: "s", value: pId })); - params.push({ type: "s", value: instanceAndParamIndicesToSetViewEntry(param.instanceIndex, param.index) }); + params.push({ type: "s", value: instanceAndParamIndicesToSetViewEntry(param.instanceId, param.index) }); const message = { address: `/rnbo/inst/control/sets/views/list/${setView.id}/params`, @@ -572,10 +572,10 @@ export const addAllParamtersToSetView = (setView: GraphSetViewRecord): AppThunk try { const state = getState(); const params = setView.params.withMutations(list => { - getPatcherInstanceParamtersSortedByIndex(state) + getPatcherInstanceParamtersSortedByInstanceIdAndIndex(state) .forEach(param => { if (!setView.paramIds.has(param.setViewId)) { - list.push({ instanceIndex: param.instanceIndex, paramIndex: param.index }); + list.push({ instanceId: param.instanceId, paramIndex: param.index }); } }); }).toArray(); @@ -583,7 +583,7 @@ export const addAllParamtersToSetView = (setView: GraphSetViewRecord): AppThunk const message = { address: `/rnbo/inst/control/sets/views/list/${setView.id}/params`, - args: params.map(p => ({ type: "s", value: instanceAndParamIndicesToSetViewEntry(p.instanceIndex, p.paramIndex) })) + args: params.map(p => ({ type: "s", value: instanceAndParamIndicesToSetViewEntry(p.instanceId, p.paramIndex) })) }; oscQueryBridge.sendPacket(writePacket(message)); } catch (err) { @@ -638,10 +638,10 @@ export const setViewContainedInstancesWaitingForMidiMappingOnRemote = (setView: (dispatch, getState) => { const state = getState(); - const instanceIndices = setView.instanceIndices.toArray(); + const ids = setView.instanceIds.toArray(); - for (const index of instanceIndices) { - const instance = getPatcherInstanceByIndex(state, index); + for (const instanceId of ids) { + const instance = getPatcherInstance(state, instanceId); if (!instance) continue; dispatch(setInstanceWaitingForMidiMappingOnRemote(instance.id, value)); } diff --git a/src/components/editor/index.tsx b/src/components/editor/index.tsx index 9c5af6a0..4bcf8400 100644 --- a/src/components/editor/index.tsx +++ b/src/components/editor/index.tsx @@ -85,7 +85,7 @@ const GraphEditor: FunctionComponent = memo(function WrappedFl const onNodeDoubleClick = useCallback((e: React.MouseEvent, node: Node) => { if (node.type !== NodeType.Patcher) return; - push({ pathname: "/instances/[index]", query: { ...query, index: (node.data.node as GraphPatcherNodeRecord).index }}); + push({ pathname: "/instances/[index]", query: { ...query, index: (node.data.node as GraphPatcherNodeRecord).instanceId }}); }, [query, push]); const flowNodes: Node[] = nodes.valueSeq().toArray().map(node => ({ diff --git a/src/components/editor/patcherNode.tsx b/src/components/editor/patcherNode.tsx index 6cd64420..9b6b65e9 100644 --- a/src/components/editor/patcherNode.tsx +++ b/src/components/editor/patcherNode.tsx @@ -31,7 +31,7 @@ const EditorPatcherNode: FunctionComponent = memo(function Wrap diff --git a/src/components/midi/mappedParameterItem.tsx b/src/components/midi/mappedParameterItem.tsx index 8366fa54..720846c0 100644 --- a/src/components/midi/mappedParameterItem.tsx +++ b/src/components/midi/mappedParameterItem.tsx @@ -81,7 +81,7 @@ const MIDIMappedParameter: FC = memo(function WrappedMIDIM /> { param.name } - { instance.index } + { instance.id } : {instance.name} { formatParamValueForDisplay(param.value) } @@ -100,7 +100,7 @@ const MIDIMappedParameter: FC = memo(function WrappedMIDIM } component={ Link } - href={{ pathname: "/instances/[index]", query: { ...restQuery, index: instance.index } }} + href={{ pathname: "/instances/[index]", query: { ...restQuery, index: instance.id } }} > Show Instance diff --git a/src/components/midi/mappedParameterList.tsx b/src/components/midi/mappedParameterList.tsx index 1b137463..7a5a9fa4 100644 --- a/src/components/midi/mappedParameterList.tsx +++ b/src/components/midi/mappedParameterList.tsx @@ -10,7 +10,7 @@ import { MIDIMappedParameterSortAttr, SortOrder } from "../../lib/constants"; export type MIDIMappedParameterListProps = { parameters: ImmuOrderedSet; - patcherInstances: ImmuMap; + patcherInstances: ImmuMap; onClearParameterMIDIMapping: (param: ParameterRecord) => void; onUpdateParameterMIDIMapping: (param: ParameterRecord, value: string) => void; onSort: (sortAttr: MIDIMappedParameterSortAttr) => void; @@ -56,9 +56,9 @@ const MIDIMappedParameterList: FC = memo(function className={ classes.patcherInstanceColumnHeader } fz="xs" onSort={ onSort } - sortKey={ MIDIMappedParameterSortAttr.InstanceIndex } + sortKey={ MIDIMappedParameterSortAttr.InstanceId } sortOrder={ sortOrder } - sorted={ sortAttr === MIDIMappedParameterSortAttr.InstanceIndex } + sorted={ sortAttr === MIDIMappedParameterSortAttr.InstanceId } > Instance @@ -71,7 +71,7 @@ const MIDIMappedParameterList: FC = memo(function { parameters.map(p => { - const pInstance = patcherInstances.get(p.instanceIndex); + const pInstance = patcherInstances.get(p.instanceId); if (!pInstance) return null; return ( dispatch(toggleShowSettings()), [dispatch]); const [ settingsAreShown, - instanceIndex + instanceId ] = useAppSelector((state: RootStateType) => [ getShowSettingsModal(state), - getFirstPatcherNodeIndex(state) + getFirstPatcherNodeId(state) ]); // eslint-disable-next-line @typescript-eslint/no-unused-vars @@ -39,10 +39,10 @@ const AppNav: FunctionComponent = memo(function WrappedNav() { isActive={ pathname === "/" } /> audio|midi)\/(?sources|sinks)$/; const portAliasPathMatcher = /^\/rnbo\/jack\/info\/ports\/aliases\/(?.+)$/; const patchersPathMatcher = /^\/rnbo\/patchers/; -const instancePathMatcher = /^\/rnbo\/inst\/(?\d+)$/; -const instanceStatePathMatcher = /^\/rnbo\/inst\/(?\d+)\/(?params|messages\/in|messages\/out|presets|data_refs|midi\/last)\/(?\S+)/; -const instancePresetPathMatcher = /^\/rnbo\/inst\/(?\d+)\/presets\/(?loaded|initial)$/; +const instancePathMatcher = /^\/rnbo\/inst\/(?\d+)$/; +const instanceStatePathMatcher = /^\/rnbo\/inst\/(?\d+)\/(?params|messages\/in|messages\/out|presets|data_refs|midi\/last)\/(?\S+)/; +const instancePresetPathMatcher = /^\/rnbo\/inst\/(?\d+)\/presets\/(?loaded|initial)$/; const connectionsPathMatcher = /^\/rnbo\/jack\/connections\/(?audio|midi)\/(?.+)$/; const setMetaPathMatcher = /^\/rnbo\/inst\/control\/sets\/meta/; const setViewPathMatcher = /^\/rnbo\/inst\/control\/sets\/views\/list\/(?\d+)(?\/\S+)?/; @@ -94,8 +94,8 @@ export class OSCQueryBridgeControllerPrivate { private _hasIsActive: boolean = false; - private static instanceExists(index: number): boolean { - return !!getPatcherNodeByIndex(store.getState(), index); + private static instanceExists(instanceId: string): boolean { + return !!getPatcherInstance(store.getState(), instanceId); } private _ws: ReconnectingWebsocket | null = null; @@ -356,33 +356,33 @@ export class OSCQueryBridgeControllerPrivate { // Parse out if instance path? const instInfoMatch = path.match(instanceStatePathMatcher); - if (!instInfoMatch?.groups?.index) return; + if (!instInfoMatch?.groups?.id) return; // Known Instance? - const index = parseInt(instInfoMatch.groups.index, 10); - if (isNaN(index) || !OSCQueryBridgeControllerPrivate.instanceExists(index)) return; + const instanceId = instInfoMatch.groups.id; + if (!OSCQueryBridgeControllerPrivate.instanceExists(instanceId)) return; if ( instInfoMatch.groups.content === "presets" && instInfoMatch.groups.rest === "entries" ) { // Updated Preset Entries - const presetInfo = await this._requestState< OSCQueryRNBOInstance["CONTENTS"]["presets"]>(`/rnbo/inst/${index}/presets`); - return void dispatch(updateInstancePresetEntries(index, presetInfo.CONTENTS.entries)); + const presetInfo = await this._requestState< OSCQueryRNBOInstance["CONTENTS"]["presets"]>(`/rnbo/inst/${instanceId}/presets`); + return void dispatch(updateInstancePresetEntries(instanceId, presetInfo.CONTENTS.entries)); } else if ( instInfoMatch.groups.content === "params" && !instInfoMatch.groups.rest.endsWith("/normalized") && !instInfoMatch.groups.rest.endsWith("/meta") ) { // Add Parameter - const paramInfo = await this._requestState< OSCQueryRNBOInstance["CONTENTS"]["params"]>(`/rnbo/inst/${index}/params`); - return void dispatch(updateInstanceParameters(index, paramInfo)); + const paramInfo = await this._requestState< OSCQueryRNBOInstance["CONTENTS"]["params"]>(`/rnbo/inst/${instanceId}/params`); + return void dispatch(updateInstanceParameters(instanceId, paramInfo)); } else if ( instInfoMatch.groups.content === "messages/in" || instInfoMatch.groups.content === "messages/out" ) { // Add Message Inputs & Outputs - const messagesInfo = await this._requestState(`/rnbo/inst/${index}/messages`); - return void dispatch(updateInstanceMessages(index, messagesInfo)); + const messagesInfo = await this._requestState(`/rnbo/inst/${instanceId}/messages`); + return void dispatch(updateInstanceMessages(instanceId, messagesInfo)); } } @@ -409,27 +409,26 @@ export class OSCQueryBridgeControllerPrivate { // Removed Instance const instMatch = path.match(instancePathMatcher); - if (instMatch?.groups?.index) { - const index = parseInt(instMatch.groups.index, 10); - if (isNaN(index)) return; - return void dispatch(removePatcherNode(index)); + if (instMatch?.groups?.id) { + const instanceId = instMatch.groups.id; + return void dispatch(removePatcherNode(instanceId)); } // Parse out if instance path? const instInfoMatch = path.match(instanceStatePathMatcher); - if (!instInfoMatch?.groups?.index) return; + if (!instInfoMatch?.groups?.id) return; // Known Instance? - const index = parseInt(instInfoMatch.groups.index, 10); - if (isNaN(index) || !OSCQueryBridgeControllerPrivate.instanceExists(index)) return; + const instanceId = instInfoMatch.groups.id; + if (!OSCQueryBridgeControllerPrivate.instanceExists(instanceId)) return; // Updated Preset Entries if ( instInfoMatch.groups.content === "presets" && instInfoMatch.groups.rest === "entries" ) { - const presetInfo = await this._requestState< OSCQueryRNBOInstance["CONTENTS"]["presets"]>(`/rnbo/inst/${index}/presets`); - return void dispatch(updateInstancePresetEntries(index, presetInfo.CONTENTS.entries)); + const presetInfo = await this._requestState< OSCQueryRNBOInstance["CONTENTS"]["presets"]>(`/rnbo/inst/${instanceId}/presets`); + return void dispatch(updateInstancePresetEntries(instanceId, presetInfo.CONTENTS.entries)); } // Removed Parameter @@ -580,12 +579,12 @@ export class OSCQueryBridgeControllerPrivate { if (instancePresetMatch) { if (packet.args.length === 1) { const name: string = packet.args[0] as unknown as string; - const index: number = parseInt(instancePresetMatch.groups.index, 10); + const instanceId: string = instancePresetMatch.groups.id; switch (instancePresetMatch.groups.property) { case "initial": - return void dispatch(updateInstancePresetInitial(index, name)); + return void dispatch(updateInstancePresetInitial(instanceId, name)); case "loaded": - return void dispatch(updateInstancePresetLatest(index, name)); + return void dispatch(updateInstancePresetLatest(instanceId, name)); default: break; } @@ -618,10 +617,10 @@ export class OSCQueryBridgeControllerPrivate { } const packetMatch = packet.address.match(instanceStatePathMatcher); - if (!packetMatch?.groups?.index) return; + if (!packetMatch?.groups?.id) return; - const index = parseInt(packetMatch.groups.index, 10); - if (isNaN(index)) return; + const instanceId = packetMatch.groups.id; + if (!OSCQueryBridgeControllerPrivate.instanceExists(instanceId)) return; // Parameter Changes if ( @@ -630,20 +629,20 @@ export class OSCQueryBridgeControllerPrivate { // Normalized Value Update const name = packetMatch.groups.rest.split("/").slice(0, -1).join("/"); if (!name || !packet.args.length || typeof packet.args[0] !== "number") return; - return void dispatch(updateInstanceParameterValueNormalized(index, name, packet.args[0])); + return void dispatch(updateInstanceParameterValueNormalized(instanceId, name, packet.args[0])); } else if ( packetMatch.groups.content === "params" && packetMatch.groups.rest.endsWith("/meta") ) { // Meta Update const name = packetMatch.groups.rest.split("/").slice(0, -1).join("/"); - return void dispatch(updateInstanceParameterMeta(index, name, packet.args[0] as unknown as string)); + return void dispatch(updateInstanceParameterMeta(instanceId, name, packet.args[0] as unknown as string)); } else if ( packetMatch.groups.content === "params" ) { // Value Update const name = packetMatch.groups.rest; if (!name || !packet.args.length || typeof packet.args[0] !== "number") return; - return void dispatch(updateInstanceParameterValue(index, name, packet.args[0])); + return void dispatch(updateInstanceParameterValue(instanceId, name, packet.args[0])); } // Preset changes @@ -651,16 +650,16 @@ export class OSCQueryBridgeControllerPrivate { packetMatch.groups.content === "presets" && packetMatch.groups.rest === "entries" ) { - const presetInfo = await this._requestState< OSCQueryRNBOInstance["CONTENTS"]["presets"]>(`/rnbo/inst/${index}/presets`); - return void dispatch(updateInstancePresetEntries(index, presetInfo.CONTENTS.entries)); + const presetInfo = await this._requestState< OSCQueryRNBOInstance["CONTENTS"]["presets"]>(`/rnbo/inst/${instanceId}/presets`); + return void dispatch(updateInstancePresetEntries(instanceId, presetInfo.CONTENTS.entries)); } // Port meta if (packetMatch.groups.rest.endsWith("/meta")) { if (packetMatch.groups.content === "messages/out") { - return void dispatch(updateInstanceMessageOutportMeta(index, packetMatch.groups.rest.replace(/\/meta$/, ""), packet.args[0] as unknown as string)); + return void dispatch(updateInstanceMessageOutportMeta(instanceId, packetMatch.groups.rest.replace(/\/meta$/, ""), packet.args[0] as unknown as string)); } else if (packetMatch.groups.content === "messages/in") { - return void dispatch(updateInstanceMessageInportMeta(index, packetMatch.groups.rest.replace(/\/meta$/, ""), packet.args[0] as unknown as string)); + return void dispatch(updateInstanceMessageInportMeta(instanceId, packetMatch.groups.rest.replace(/\/meta$/, ""), packet.args[0] as unknown as string)); } } @@ -670,7 +669,7 @@ export class OSCQueryBridgeControllerPrivate { packetMatch.groups.rest?.length ) { // groups.rest might not actually be a valid id but that should be okay - return void dispatch(updateInstanceMessageOutportValue(index, packetMatch.groups.rest, packet.args as any as OSCValue | OSCValue[])); + return void dispatch(updateInstanceMessageOutportValue(instanceId, packetMatch.groups.rest, packet.args as any as OSCValue | OSCValue[])); } if ( @@ -679,7 +678,7 @@ export class OSCQueryBridgeControllerPrivate { ) { if (packet.args.length >= 1 && typeof packet.args[0] === "string") { - return void dispatch(updateInstanceDataRefValue(index, packetMatch.groups.rest, packet.args[0] as string)); + return void dispatch(updateInstanceDataRefValue(instanceId, packetMatch.groups.rest, packet.args[0] as string)); } console.log("unexpected dataref OSC packet format", { packet }); @@ -688,9 +687,9 @@ export class OSCQueryBridgeControllerPrivate { if (packetMatch.groups.content === "midi/last") { switch (packetMatch.groups.rest) { case "value": - return void dispatch(updateInstanceMIDILastValue(index, packet.args[0] as unknown as string)); + return void dispatch(updateInstanceMIDILastValue(instanceId, packet.args[0] as unknown as string)); case "report": - return void dispatch(updateInstanceMIDIReport(index, packet.args[0] as unknown as boolean)); + return void dispatch(updateInstanceMIDIReport(instanceId, packet.args[0] as unknown as boolean)); default: return; } diff --git a/src/lib/constants.ts b/src/lib/constants.ts index 1788f331..9cefa8b2 100644 --- a/src/lib/constants.ts +++ b/src/lib/constants.ts @@ -73,7 +73,7 @@ export enum SortOrder { export enum MIDIMappedParameterSortAttr { MIDISource = "midi_source", - InstanceIndex = "instance_index", + InstanceId = "instance_id", ParameterName = "param_name" } diff --git a/src/lib/util.ts b/src/lib/util.ts index 97e6fad0..4f5a1786 100644 --- a/src/lib/util.ts +++ b/src/lib/util.ts @@ -77,7 +77,7 @@ export const formatParamValueForDisplay = (value: number | string) => { return value; }; -export const instanceAndParamIndicesToSetViewEntry = (instanceIndex: number, paramIndex: number) => `${instanceIndex}:${paramIndex}`; +export const instanceAndParamIndicesToSetViewEntry = (instanceId: string, paramIndex: number) => `${instanceId}:${paramIndex}`; export const cloneJSON = (value: JsonMap): JsonMap => JSON.parse(JSON.stringify(value)); diff --git a/src/models/graph.ts b/src/models/graph.ts index ec9980f8..fe52560d 100644 --- a/src/models/graph.ts +++ b/src/models/graph.ts @@ -64,7 +64,7 @@ export type GraphSystemNodeProps = CommonGraphNodeProps & { } export type GraphPatcherNodeProps = CommonGraphNodeProps & { - index: number; + instanceId: string; patcher: string; path: string; } @@ -92,7 +92,7 @@ export interface GraphControlNode extends GraphNode { export class GraphPatcherNodeRecord extends ImmuRecord({ - index: 0, + instanceId: "0", jackName: "", patcher: "", path: "", @@ -113,7 +113,7 @@ export class GraphPatcherNodeRecord extends ImmuRecord({ } public get displayName(): string { - return `${this.index}: ${this.patcher}`; + return `${this.instanceId}: ${this.patcher}`; } public get id(): string { @@ -215,7 +215,7 @@ export class GraphPatcherNodeRecord extends ImmuRecord({ const ports = this.portsFromDescription(desc.CONTENTS.jack); return new GraphPatcherNodeRecord({ - index: parseInt(desc.FULL_PATH.split("/").pop(), 10), + instanceId: desc.FULL_PATH.split("/").pop(), jackName: this.getJackName(desc.CONTENTS.jack), patcher: desc.CONTENTS.name.VALUE, path: desc.FULL_PATH, diff --git a/src/models/instance.ts b/src/models/instance.ts index 610a023d..52ac8044 100644 --- a/src/models/instance.ts +++ b/src/models/instance.ts @@ -4,7 +4,7 @@ import { DataRefRecord } from "./dataref"; import { OSCQueryRNBOInstance, OSCQueryRNBOInstancePresetEntries } from "../lib/types"; export type PatcherInstanceProps = { - index: number; + id: string; patcher: string; path: string; name: string; @@ -32,7 +32,7 @@ function sortPresets(left: PresetRecord, right: PresetRecord) : number { export class PatcherInstanceRecord extends ImmuRecord({ - index: 0, + id: "0", name: "", patcher: "", path: "", @@ -46,11 +46,7 @@ export class PatcherInstanceRecord extends ImmuRecord({ }) { public get displayName(): string { - return `${this.index}: ${this.name}`; - } - - public get id(): string { - return this.name; + return `${this.id}: ${this.name}`; } public setWaitingForMapping(value: boolean): PatcherInstanceRecord { @@ -104,7 +100,7 @@ export class PatcherInstanceRecord extends ImmuRecord({ const latestPreset: string = desc.CONTENTS.presets.CONTENTS?.loaded?.VALUE || ""; return new PatcherInstanceRecord({ - index: parseInt(desc.FULL_PATH.split("/").pop(), 10), + id: desc.FULL_PATH.split("/").pop(), name: this.getJackName(desc.CONTENTS.jack), patcher: desc.CONTENTS.name.VALUE, path: desc.FULL_PATH, diff --git a/src/models/messageport.ts b/src/models/messageport.ts index 8b5a691a..c8a55f69 100644 --- a/src/models/messageport.ts +++ b/src/models/messageport.ts @@ -4,7 +4,7 @@ import { PatcherInstanceRecord } from "./instance"; import { parseMetaJSONString } from "../lib/util"; export type MessagePortRecordProps = { - instanceIndex: number; + instanceId: string; tag: string; meta: JsonMap; metaString: string; @@ -14,7 +14,7 @@ export type MessagePortRecordProps = { export class MessagePortRecord extends ImmuRecord({ - instanceIndex: 0, + instanceId: "0", tag: "", meta: {}, metaString: "", @@ -22,11 +22,11 @@ export class MessagePortRecord extends ImmuRecord({ path: "" }) { - private static messagesArrayFromDescription(instanceIndex: PatcherInstanceRecord["index"], desc: OSCQueryRNBOInstanceMessageInfo, name: string): MessagePortRecord[] { + private static messagesArrayFromDescription(instanceId: PatcherInstanceRecord["id"], desc: OSCQueryRNBOInstanceMessageInfo, name: string): MessagePortRecord[] { if (typeof desc.VALUE !== "undefined") { return [ new MessagePortRecord({ - instanceIndex, + instanceId, tag: name, path: (desc as OSCQueryRNBOInstanceMessageValue).FULL_PATH }).setMeta((desc as OSCQueryRNBOInstanceMessageValue).CONTENTS?.meta?.VALUE || "") @@ -36,15 +36,15 @@ export class MessagePortRecord extends ImmuRecord({ const result: MessagePortRecord[] = []; for (const [subKey, subDesc] of Object.entries(desc.CONTENTS)) { const subPrefix = name ? `${name}/${subKey}` : subKey; - result.push(...this.messagesArrayFromDescription(instanceIndex, subDesc, subPrefix)); + result.push(...this.messagesArrayFromDescription(instanceId, subDesc, subPrefix)); } return result; } - public static fromDescription(instanceIndex: PatcherInstanceRecord["index"], messagesDesc?: OSCQueryRNBOInstanceMessages): MessagePortRecord[] { + public static fromDescription(instanceId: PatcherInstanceRecord["id"], messagesDesc?: OSCQueryRNBOInstanceMessages): MessagePortRecord[] { const ports: MessagePortRecord[] = []; for (const [name, desc] of Object.entries(messagesDesc?.CONTENTS || {})) { - ports.push(...this.messagesArrayFromDescription(instanceIndex, desc, name)); + ports.push(...this.messagesArrayFromDescription(instanceId, desc, name)); } return ports; } diff --git a/src/models/parameter.ts b/src/models/parameter.ts index 865071c0..e130d12f 100644 --- a/src/models/parameter.ts +++ b/src/models/parameter.ts @@ -7,7 +7,7 @@ export type ParameterRecordProps = { enumVals: Array; index: number; - instanceIndex: number; + instanceId: string; min: number; max: number; meta: ParameterMetaJsonMap; @@ -25,7 +25,7 @@ export class ParameterRecord extends ImmuRecord({ enumVals: [], index: 0, - instanceIndex: 0, + instanceId: "0", min: 0, max: 1, meta: {}, @@ -41,7 +41,7 @@ export class ParameterRecord extends ImmuRecord({ }) { private static arrayFromDescription( - instanceIndex: number, + instanceId: string, desc: OSCQueryRNBOInstanceParameterInfo, name?: string ): ParameterRecord[] { @@ -53,7 +53,7 @@ export class ParameterRecord extends ImmuRecord({ result.push((new ParameterRecord({ enumVals: paramInfo.RANGE?.[0]?.VALS || [], index: paramInfo.CONTENTS?.index?.VALUE || 0, - instanceIndex, + instanceId, min: paramInfo.RANGE?.[0]?.MIN, max: paramInfo.RANGE?.[0]?.MAX, name, @@ -66,16 +66,16 @@ export class ParameterRecord extends ImmuRecord({ // Polyphonic params for (const [subParamName, subDesc] of Object.entries(desc.CONTENTS) as Array<[string, OSCQueryRNBOInstanceParameterInfo]>) { const subPrefix = name ? `${name}/${subParamName}` : subParamName; - result.push(...this.arrayFromDescription(instanceIndex, subDesc, subPrefix)); + result.push(...this.arrayFromDescription(instanceId, subDesc, subPrefix)); } } return result; } - public static fromDescription(instanceIndex: number, paramsDesc: OSCQueryRNBOInstance["CONTENTS"]["params"]): ParameterRecord[] { + public static fromDescription(instanceId: string, paramsDesc: OSCQueryRNBOInstance["CONTENTS"]["params"]): ParameterRecord[] { const params: ParameterRecord[] = []; for (const [name, desc] of Object.entries(paramsDesc.CONTENTS || {})) { - params.push(...ParameterRecord.arrayFromDescription(instanceIndex, desc, name)); + params.push(...ParameterRecord.arrayFromDescription(instanceId, desc, name)); } return params; } @@ -89,7 +89,7 @@ export class ParameterRecord extends ImmuRecord({ } public get setViewId(): string { - return instanceAndParamIndicesToSetViewEntry(this.instanceIndex, this.index); + return instanceAndParamIndicesToSetViewEntry(this.instanceId, this.index); } public getValueForNormalizedValue(nv: number): string | number { diff --git a/src/models/set.ts b/src/models/set.ts index 4e3113e8..21ac1ded 100644 --- a/src/models/set.ts +++ b/src/models/set.ts @@ -27,7 +27,7 @@ export class GraphSetRecord extends ImmuRecord({ } export type GraphSetViewParameterEntry = { - instanceIndex: PatcherInstanceRecord["index"]; + instanceId: PatcherInstanceRecord["id"]; paramIndex: ParameterRecord["index"]; } @@ -50,12 +50,10 @@ export class GraphSetViewRecord extends ImmuRecord({ private static getParamListFromDesc(params: string[]): ImmuList { return ImmuList().withMutations(list => { for (const p of params) { - const [iIndex, pIndex] = p.split(":"); - - const instanceIndex = parseInt(iIndex, 10); + const [instanceId, pIndex] = p.split(":"); const paramIndex = parseInt(pIndex, 10); - if (!isNaN(instanceIndex) && !isNaN(paramIndex)) { - list.push({ instanceIndex, paramIndex }); + if (!instanceId.length && !isNaN(paramIndex)) { + list.push({ instanceId, paramIndex }); } } }); @@ -81,10 +79,10 @@ export class GraphSetViewRecord extends ImmuRecord({ }); } - public get instanceIndices(): ImmuOrderedSet { - return ImmuOrderedSet() + public get instanceIds(): ImmuOrderedSet { + return ImmuOrderedSet() .withMutations(set => { - this.params.forEach(p => set.add(p.instanceIndex)); + this.params.forEach(p => set.add(p.instanceId)); }); } diff --git a/src/pages/instances/[index].tsx b/src/pages/instances/[index].tsx index 1fb82e31..740020d8 100644 --- a/src/pages/instances/[index].tsx +++ b/src/pages/instances/[index].tsx @@ -8,8 +8,8 @@ import classes from "../../components/instance/instance.module.css"; import { getAppStatus } from "../../selectors/appStatus"; import { AppStatus, SortOrder } from "../../lib/constants"; import Link from "next/link"; -import { getPatcherInstanceByIndex, getPatcherInstanceParametersByInstanceIndex, getPatcherInstances, getPatcherInstanceMessageInportsByInstanceIndex, getPatcherInstanceMesssageOutportsByInstanceIndex } from "../../selectors/patchers"; -import { unloadPatcherNodeByIndexOnRemote } from "../../actions/graph"; +import { getPatcherInstance, getPatcherInstanceParametersByInstanceId, getPatcherInstances, getPatcherInstanceMessageInportsByInstanceId, getPatcherInstanceMesssageOutportsByInstanceId } from "../../selectors/patchers"; +import { unloadPatcherNodeOnRemote } from "../../actions/graph"; import { getAppSetting } from "../../selectors/settings"; import { AppSetting } from "../../models/settings"; import PresetDrawer from "../../components/presets"; @@ -23,6 +23,8 @@ import { IconElement } from "../../components/elements/icon"; import { mdiCamera, mdiChartSankeyVariant, mdiPiano, mdiVectorSquare, mdiVectorSquareRemove } from "@mdi/js"; import { ResponsiveButton } from "../../components/elements/responsiveButton"; +const collator = new Intl.Collator("en-US", { numeric: true }); + export default function Instance() { const { query, isReady, pathname, push } = useRouter(); @@ -30,7 +32,7 @@ export default function Instance() { const [keyboardModalIsOpen, { close: closeKeyboardModal, toggle: toggleKeyboardModal }] = useDisclosure(); const { index, ...restQuery } = query; - const instanceIndex = parseInt(Array.isArray(index) ? index.join("") : index || "0", 10); + const instanceId = Array.isArray(index) ? index.join("") : index || "0"; const dispatch = useAppDispatch(); @@ -47,13 +49,13 @@ export default function Instance() { sortAttr, sortOrder ] = useAppSelector((state: RootStateType) => { - const currentInstance = getPatcherInstanceByIndex(state, instanceIndex); + const currentInstance = getPatcherInstance(state, instanceId); return [ currentInstance, - currentInstance ? getPatcherInstanceParametersByInstanceIndex(state, currentInstance.index) : undefined, - currentInstance ? getPatcherInstanceMessageInportsByInstanceIndex(state, currentInstance.index) : undefined, - currentInstance ? getPatcherInstanceMesssageOutportsByInstanceIndex(state, currentInstance.index) : undefined, + currentInstance ? getPatcherInstanceParametersByInstanceId(state, currentInstance.id) : undefined, + currentInstance ? getPatcherInstanceMessageInportsByInstanceId(state, currentInstance.id) : undefined, + currentInstance ? getPatcherInstanceMesssageOutportsByInstanceId(state, currentInstance.id) : undefined, getAppStatus(state), getPatcherInstances(state), getDataFilesSortedByName(state, SortOrder.Asc), @@ -74,13 +76,13 @@ export default function Instance() { centered: true, children: ( - Are you sure you want to unload the Patcher Instance { currentInstance?.patcher } at index {currentInstance?.index}? + Are you sure you want to unload the Patcher Instance { currentInstance?.displayName }? ), labels: { confirm: "Unload", cancel: "Cancel" }, confirmProps: { color: "red" }, onConfirm: () => { - dispatch(unloadPatcherNodeByIndexOnRemote(currentInstance.index)); + dispatch(unloadPatcherNodeOnRemote(currentInstance.id)); push({ pathname: "/", query: restQuery }); } }); @@ -131,10 +133,10 @@ export default function Instance() {
n.index).toArray().map(d => ({ value: `${d.index}`, label: d.displayName })) } + data={ instances.valueSeq().sort((a, b) => collator.compare(a.id, b.id)).toArray().map(d => ({ value: d.id, label: d.displayName })) } leftSection={ } onChange={ onChangeInstance } - value={ currentInstance.index } + value={ currentInstance.id } style={{ maxWidth: 300, width: "100%" }} />
diff --git a/src/pages/midimappings.tsx b/src/pages/midimappings.tsx index 26aa70ab..9c063cf7 100644 --- a/src/pages/midimappings.tsx +++ b/src/pages/midimappings.tsx @@ -5,13 +5,14 @@ import { RootStateType } from "../lib/store"; import classes from "../components/midi/midi.module.css"; import { MIDIMappedParameterSortAttr, MIDIMetaMappingType, SortOrder } from "../lib/constants"; import { useCallback, useEffect, useState } from "react"; -import { getPatcherInstanceParametersWithMIDIMapping, getPatcherInstancesByIndex } from "../selectors/patchers"; +import { getPatcherInstanceParametersWithMIDIMapping, getPatcherInstances } from "../selectors/patchers"; import MIDIMappedParameterList from "../components/midi/mappedParameterList"; import { ParameterRecord } from "../models/parameter"; import { clearParameterMIDIMappingOnRemote, setParameterMIDIMappingOnRemoteFromDisplayValue } from "../actions/patchers"; import { formatMIDIMappingToDisplay } from "../lib/util"; const collator = new Intl.Collator("en-US", { numeric: true }); + const parameterComparators: Record number>> = { [MIDIMappedParameterSortAttr.MIDISource]: { [SortOrder.Asc]: (a: ParameterRecord, b: ParameterRecord) => { @@ -25,15 +26,13 @@ const parameterComparators: Record { - if (a.instanceIndex < b.instanceIndex) return -1; - if (a.instanceIndex > b.instanceIndex) return 1; + if (a.instanceId !== b.instanceId) return collator.compare(a.instanceId, b.instanceId); return collator.compare(a.name.toLowerCase(), b.name.toLowerCase()); }, [SortOrder.Desc]: (a: ParameterRecord, b: ParameterRecord) => { - if (a.instanceIndex > b.instanceIndex) return -1; - if (a.instanceIndex < b.instanceIndex) return 1; + if (a.instanceId !== b.instanceId) return collator.compare(a.instanceId, b.instanceId) * -1; return collator.compare(a.name.toLowerCase(), b.name.toLowerCase()) * -1; } }, @@ -62,7 +61,7 @@ const MIDIMappings = () => { patcherInstances, parameters ] = useAppSelector((state: RootStateType) => [ - getPatcherInstancesByIndex(state), + getPatcherInstances(state), getPatcherInstanceParametersWithMIDIMapping(state) ]); diff --git a/src/reducers/graph.ts b/src/reducers/graph.ts index a3cccef0..8fcd011a 100644 --- a/src/reducers/graph.ts +++ b/src/reducers/graph.ts @@ -6,7 +6,7 @@ export interface GraphState { connections: ImmuMap; nodes: ImmuMap; - patcherNodeIdByIndex: ImmuMap; + patcherNodeIdByInstanceId: ImmuMap; portAliases: ImmuMap; } @@ -15,7 +15,7 @@ export const graph = (state: GraphState = { connections: ImmuMap(), nodes: ImmuMap(), - patcherNodeIdByIndex: ImmuMap(), + patcherNodeIdByInstanceId: ImmuMap(), portAliases: ImmuMap() }, action: GraphAction): GraphState => { @@ -27,7 +27,7 @@ export const graph = (state: GraphState = { return { ...state, nodes: state.nodes.delete(node.id), - patcherNodeIdByIndex: node.type === NodeType.Patcher ? state.patcherNodeIdByIndex.delete(node.index) : state.patcherNodeIdByIndex, + patcherNodeIdByInstanceId: node.type === NodeType.Patcher ? state.patcherNodeIdByInstanceId.delete(node.instanceId) : state.patcherNodeIdByInstanceId, connections: state.connections .filter(connection => connection.sourceNodeId !== node.id && connection.sinkNodeId !== node.id ) }; @@ -39,9 +39,9 @@ export const graph = (state: GraphState = { return { ...state, nodes: state.nodes.deleteAll(nodeIds), - patcherNodeIdByIndex: state.patcherNodeIdByIndex.deleteAll( + patcherNodeIdByInstanceId: state.patcherNodeIdByInstanceId.deleteAll( (nodes.filter(n => n.type === NodeType.Patcher) as GraphPatcherNodeRecord[]) - .map(n => n .index) + .map(n => n .instanceId) ), connections: state.connections .filter(connection => !nodeIds.includes(connection.sourceNodeId) && !nodeIds.includes(connection.sinkNodeId) ) @@ -53,7 +53,7 @@ export const graph = (state: GraphState = { return { ...state, nodes: state.nodes.set(node.id, node), - patcherNodeIdByIndex: node.type === NodeType.Patcher ? state.patcherNodeIdByIndex.set(node.index, node.id) : state.patcherNodeIdByIndex + patcherNodeIdByInstanceId: node.type === NodeType.Patcher ? state.patcherNodeIdByInstanceId.set(node.instanceId, node.id) : state.patcherNodeIdByInstanceId }; } @@ -66,10 +66,10 @@ export const graph = (state: GraphState = { map.set(node.id, node); } }), - patcherNodeIdByIndex: state.patcherNodeIdByIndex.withMutations(map => { + patcherNodeIdByInstanceId: state.patcherNodeIdByInstanceId.withMutations(map => { for (const node of nodes) { if (node.type === NodeType.Patcher) { - map.set(node.index, node.id); + map.set(node.instanceId, node.id); } } }) diff --git a/src/reducers/patchers.ts b/src/reducers/patchers.ts index d4843699..db19fb8c 100644 --- a/src/reducers/patchers.ts +++ b/src/reducers/patchers.ts @@ -62,22 +62,22 @@ export const patchers = (state: PatcherState = { return { ...state, instances: state.instances.delete(instance.id), - instanceParameters: state.instanceParameters.filter(param => param.instanceIndex !== instance.index), - instanceMessageInports: state.instanceMessageInports.filter(port => port.instanceIndex !== instance.index), - instanceMessageOutports: state.instanceMessageOutports.filter(port => port.instanceIndex !== instance.index) + instanceParameters: state.instanceParameters.filter(param => param.instanceId !== instance.id), + instanceMessageInports: state.instanceMessageInports.filter(port => port.instanceId !== instance.id), + instanceMessageOutports: state.instanceMessageOutports.filter(port => port.instanceId !== instance.id) }; } case PatcherActionType.DELETE_INSTANCES: { const { instances } = action.payload; - const indexSet = new Set(instances.map(i => i.index)); + const idSet = new Set(instances.map(i => i.id)); return { ...state, instances: state.instances.deleteAll(instances.map(d => d.id)), - instanceParameters: state.instanceParameters.filter(param => !indexSet.has(param.instanceIndex)), - instanceMessageInports: state.instanceMessageInports.filter(port => !indexSet.has(port.instanceIndex)), - instanceMessageOutports: state.instanceMessageOutports.filter(port => !indexSet.has(port.instanceIndex)) + instanceParameters: state.instanceParameters.filter(param => !idSet.has(param.instanceId)), + instanceMessageInports: state.instanceMessageInports.filter(port => !idSet.has(port.instanceId)), + instanceMessageOutports: state.instanceMessageOutports.filter(port => !idSet.has(port.instanceId)) }; } diff --git a/src/selectors/graph.ts b/src/selectors/graph.ts index 79b1c2dd..18ad3287 100644 --- a/src/selectors/graph.ts +++ b/src/selectors/graph.ts @@ -4,7 +4,7 @@ import { GraphConnectionRecord, GraphControlNodeRecord, GraphNodeRecord, GraphPa import { createSelector } from "reselect"; export const getNodes = (state: RootStateType): ImmuMap => state.graph.nodes; -export const getPatcherIdsByIndex = (state: RootStateType): ImmuMap => state.graph.patcherNodeIdByIndex; +export const getPatcherNodeIdsByInstanceId = (state: RootStateType): ImmuMap => state.graph.patcherNodeIdByInstanceId; export const getNode = createSelector( [ @@ -24,31 +24,33 @@ export const getPatcherNodes = createSelector( } ); -export const getPatcherNodeByIndex = createSelector( +export const getPatcherNodeByInstanceId = createSelector( [ getNodes, - getPatcherIdsByIndex, - (state: RootStateType, index: GraphPatcherNodeRecord["index"]): GraphPatcherNodeRecord["index"] => index + getPatcherNodeIdsByInstanceId, + (state: RootStateType, instanceId: GraphPatcherNodeRecord["instanceId"]): GraphPatcherNodeRecord["instanceId"] => instanceId ], - (nodes, idsByIndex, index): GraphPatcherNodeRecord | undefined => { - const id = idsByIndex.get(index); + (nodes, idsByInstanceId, instanceId): GraphPatcherNodeRecord | undefined => { + const id = idsByInstanceId.get(instanceId); const node = id ? nodes.get(id) : undefined; return node as GraphPatcherNodeRecord | undefined; } ); -export const getFirstPatcherNodeIndex = createSelector( - [getPatcherIdsByIndex], - (idsByIndex): number | undefined => { - return idsByIndex.size === 0 ? undefined : idsByIndex.keySeq().sort().first(); +export const getFirstPatcherNodeId = createSelector( + [ + getPatcherNodeIdsByInstanceId + ], + (idsByInstanceId): string | undefined => { + return idsByInstanceId.size === 0 ? undefined : idsByInstanceId.keySeq().sort().first(); } ); -export const getPatcherNodesByIndex = (state: RootStateType): ImmuMap => { - return ImmuMap().withMutations(map => { - state.graph.patcherNodeIdByIndex.forEach((id, index) => { - const node = getNode(state, id); - if (node && node.type === NodeType.Patcher) map.set(index, node); +export const getPatcherNodesByInstanceId = (state: RootStateType): ImmuMap => { + return ImmuMap().withMutations(map => { + state.graph.patcherNodeIdByInstanceId.forEach((nodeId, instanceId) => { + const node = getNode(state, nodeId); + if (node && node.type === NodeType.Patcher) map.set(instanceId, node); }); }); }; diff --git a/src/selectors/patchers.ts b/src/selectors/patchers.ts index 798a157f..f5470e2a 100644 --- a/src/selectors/patchers.ts +++ b/src/selectors/patchers.ts @@ -2,7 +2,6 @@ import { Map as ImmuMap, Seq, OrderedSet as ImmuOrderedSet } from "immutable"; import { RootStateType } from "../lib/store"; import { PatcherInstanceRecord } from "../models/instance"; import { createSelector } from "reselect"; -import { getPatcherIdsByIndex } from "./graph"; import { ParameterRecord } from "../models/parameter"; import { MessagePortRecord } from "../models/messageport"; import { PatcherExportRecord } from "../models/patcher"; @@ -23,13 +22,13 @@ export const getPatcherExport = createSelector( } ); -const collator = new Intl.Collator("en-US"); export const getPatchersSortedByName = createSelector( [ getPatcherExports, (state: RootStateType, order: SortOrder): SortOrder => order ], (patchers, order): Seq.Indexed => { + const collator = new Intl.Collator("en-US"); return patchers.valueSeq().sort((pA, pB) => { return collator.compare(pA.name.toLowerCase(), pB.name.toLowerCase()) * (order === SortOrder.Asc ? 1 : -1); }); @@ -47,41 +46,18 @@ export const getPatcherInstance = createSelector( (instances, id): PatcherInstanceRecord | undefined => instances.get(id) ); -export const getPatcherInstanceByIndex = createSelector( - [ - getPatcherInstances, - (state: RootStateType, index: PatcherInstanceRecord["index"]): PatcherInstanceRecord["id"] | undefined => state.graph.patcherNodeIdByIndex.get(index) - ], - (instances, id): PatcherInstanceRecord | undefined => id ? instances.get(id) : undefined -); - -export const getPatcherInstancesByIndex = createSelector( - [ - getPatcherInstances, - getPatcherIdsByIndex - ], - (instances, idsByIndex): ImmuMap => { - return ImmuMap().withMutations(map => { - idsByIndex.forEach((id, index) => { - const node = instances.get(id); - if (node) map.set(index, node); - }); - }); - } -); - export const getPatcherInstanceParameters = (state: RootStateType): ImmuMap => state.patchers.instanceParameters; -export const getPatcherInstanceParamtersSortedByIndex = createSelector( +export const getPatcherInstanceParamtersSortedByInstanceIdAndIndex = createSelector( [ getPatcherInstanceParameters ], (parameters): Seq.Indexed => { + const collator = new Intl.Collator("en-US", { numeric: true }); return parameters .valueSeq() .sort((a, b) => { - if (a.instanceIndex < b.instanceIndex) return -1; - if (a.instanceIndex > b.instanceIndex) return 1; + if (a.instanceId !== b.instanceId) return collator.compare(a.instanceId, b.instanceId); if (a.index < b.index) return -1; if (a.index > b.index) return 1; return 0; @@ -100,14 +76,14 @@ export const getPatcherInstanceParametersWithMIDIMapping = createSelector( export const getPatcherInstancesAreWaitingForMIDIMappingBySetView = createSelector( [ - getPatcherInstancesByIndex, + getPatcherInstances, (state: RootStateType, setView: GraphSetViewRecord): GraphSetViewRecord => setView ], (instances, setView): boolean => { - const indices = setView.instanceIndices.toArray(); - if (!indices.length) return false; - for (const index of indices) { - const instance = instances.get(index); + const ids = setView.instanceIds.toArray(); + if (!ids.length) return false; + for (const instanceId of ids) { + const instance = instances.get(instanceId); if (!instance || !instance.waitingForMidiMapping) return false; } return true; @@ -122,8 +98,8 @@ export const getPatcherInstanceParametersBySetView = createSelector( (parameters, viewParamList): ImmuOrderedSet => { return ImmuOrderedSet().withMutations(list => { const entries = viewParamList.valueSeq().toArray(); - for (const { instanceIndex, paramIndex } of entries) { - const param = parameters.find(p => p.instanceIndex === instanceIndex && p.index === paramIndex); + for (const { instanceId, paramIndex } of entries) { + const param = parameters.find(p => p.instanceId === instanceId && p.index === paramIndex); if (param) list.add(param); } }); @@ -150,14 +126,14 @@ export const getPatcherInstanceParameterByPath = createSelector( } ); -export const getPatcherInstanceParametersByInstanceIndex = createSelector( +export const getPatcherInstanceParametersByInstanceId = createSelector( [ getPatcherInstanceParameters, - (state: RootStateType, instanceIndex: PatcherInstanceRecord["index"]): PatcherInstanceRecord["index"] => instanceIndex + (state: RootStateType, instanceId: PatcherInstanceRecord["id"]): PatcherInstanceRecord["id"] => instanceId ], - (parameters, instanceIndex): ImmuMap => { + (parameters, instanceId): ImmuMap => { return parameters.filter(p => { - return p.instanceIndex === instanceIndex; + return p.instanceId === instanceId; }); } ); @@ -173,21 +149,21 @@ export const getPatcherInstancesAndParameters = createSelector( instances.valueSeq().forEach(instance => { map.set(instance.id, { instance, - parameters: parameters.filter(p => p.instanceIndex === instance.index).valueSeq() + parameters: parameters.filter(p => p.instanceId === instance.id).valueSeq() }); }); }); } ); -export const getPatcherInstanceParametersByInstanceIndexAndName = createSelector( +export const getPatcherInstanceParametersByInstanceIdAndName = createSelector( [ getPatcherInstanceParameters, - (state: RootStateType, instanceIndex: PatcherInstanceRecord["index"]): PatcherInstanceRecord["index"] => instanceIndex, - (state: RootStateType, instanceIndex: PatcherInstanceRecord["index"], name: ParameterRecord["name"]): ParameterRecord["name"] => name + (state: RootStateType, instanceId: PatcherInstanceRecord["id"]): PatcherInstanceRecord["id"] => instanceId, + (state: RootStateType, instanceId: PatcherInstanceRecord["id"], name: ParameterRecord["name"]): ParameterRecord["name"] => name ], - (parameters, instanceIndex, name): ParameterRecord | undefined => { - return parameters.find(p => p.instanceIndex === instanceIndex && p.name === name); + (parameters, instanceId, name): ParameterRecord | undefined => { + return parameters.find(p => p.instanceId === instanceId && p.name === name); } ); @@ -213,26 +189,26 @@ export const getPatcherInstanceMessageInportByPath = createSelector( } ); -export const getPatcherInstanceMessageInportsByInstanceIndex = createSelector( +export const getPatcherInstanceMessageInportsByInstanceId = createSelector( [ getPatcherInstanceMessageInports, - (state: RootStateType, instanceIndex: PatcherInstanceRecord["index"]): PatcherInstanceRecord["index"] => instanceIndex + (state: RootStateType, instanceId: PatcherInstanceRecord["id"]): PatcherInstanceRecord["id"] => instanceId ], - (ports, instanceIndex): ImmuMap => { + (ports, instanceId): ImmuMap => { return ports.filter(p => { - return p.instanceIndex === instanceIndex; + return p.instanceId === instanceId; }); } ); -export const getPatcherInstanceMessageInportsByInstanceIndexAndTag = createSelector( +export const getPatcherInstanceMessageInportsByInstanceIdAndTag = createSelector( [ getPatcherInstanceMessageInports, - (state: RootStateType, instanceIndex: PatcherInstanceRecord["index"]): PatcherInstanceRecord["index"] => instanceIndex, - (state: RootStateType, instanceIndex: PatcherInstanceRecord["index"], tag: MessagePortRecord["tag"]): MessagePortRecord["tag"] => tag + (state: RootStateType, instanceId: PatcherInstanceRecord["id"]): PatcherInstanceRecord["id"] => instanceId, + (state: RootStateType, instanceId: PatcherInstanceRecord["id"], tag: MessagePortRecord["tag"]): MessagePortRecord["tag"] => tag ], - (ports, instanceIndex, tag): MessagePortRecord | undefined => { - return ports.find(p => p.instanceIndex === instanceIndex && p.tag === tag); + (ports, instanceId, tag): MessagePortRecord | undefined => { + return ports.find(p => p.instanceId === instanceId && p.tag === tag); } ); @@ -258,25 +234,25 @@ export const getPatcherInstanceMessageOutportByPath = createSelector( } ); -export const getPatcherInstanceMesssageOutportsByInstanceIndex = createSelector( +export const getPatcherInstanceMesssageOutportsByInstanceId = createSelector( [ getPatcherInstanceMessageOutports, - (state: RootStateType, instanceIndex: PatcherInstanceRecord["index"]): PatcherInstanceRecord["index"] => instanceIndex + (state: RootStateType, instanceId: PatcherInstanceRecord["id"]): PatcherInstanceRecord["id"] => instanceId ], - (ports, instanceIndex): ImmuMap => { + (ports, instanceId): ImmuMap => { return ports.filter(p => { - return p.instanceIndex === instanceIndex; + return p.instanceId === instanceId; }); } ); -export const getPatcherInstanceMesssageOutportsByInstanceIndexAndTag = createSelector( +export const getPatcherInstanceMesssageOutportsByInstanceIdAndTag = createSelector( [ getPatcherInstanceMessageOutports, - (state: RootStateType, instanceIndex: PatcherInstanceRecord["index"]): PatcherInstanceRecord["index"] => instanceIndex, - (state: RootStateType, instanceIndex: PatcherInstanceRecord["index"], tag: MessagePortRecord["tag"]): MessagePortRecord["tag"] => tag + (state: RootStateType, instanceId: PatcherInstanceRecord["id"]): PatcherInstanceRecord["id"] => instanceId, + (state: RootStateType, instanceId: PatcherInstanceRecord["id"], tag: MessagePortRecord["tag"]): MessagePortRecord["tag"] => tag ], - (ports, instanceIndex, tag): MessagePortRecord | undefined => { - return ports.find(p => p.instanceIndex === instanceIndex && p.tag === tag); + (ports, instanceId, tag): MessagePortRecord | undefined => { + return ports.find(p => p.instanceId === instanceId && p.tag === tag); } ); diff --git a/src/selectors/sets.ts b/src/selectors/sets.ts index 060dc7db..9ed1dc98 100644 --- a/src/selectors/sets.ts +++ b/src/selectors/sets.ts @@ -19,14 +19,13 @@ export const getGraphSet = createSelector( } ); -const collator = new Intl.Collator("en-US"); - export const getGraphSetsSortedByName = createSelector( [ getGraphSets, (state: RootStateType, order: SortOrder): SortOrder => order ], (sets, order) => { + const collator = new Intl.Collator("en-US"); return sets.valueSeq().sort((left: GraphSetRecord, right: GraphSetRecord): number => { return collator.compare(left.name, right.name) * (order === SortOrder.Asc ? 1 : -1); }); @@ -54,6 +53,7 @@ export const getGraphSetPresetsSortedByName = createSelector( (state: RootStateType, order: SortOrder): SortOrder => order ], (presets, order) => { + const collator = new Intl.Collator("en-US"); return presets.valueSeq().sort((left: PresetRecord, right: PresetRecord): number => { let result; if (left.name === right.name) { @@ -80,6 +80,7 @@ export const getGraphSetViewsBySortOrder = createSelector( getGraphSetViews ], (views): ImmuMap => { + const collator = new Intl.Collator("en-US"); return views.sort((va, vb) => { if (va.sortOrder < vb.sortOrder) return -1; if (va.sortOrder > vb.sortOrder) return 1; @@ -93,8 +94,8 @@ export const getGraphSetView = createSelector( getGraphSetViews, (state: RootStateType, id: GraphSetViewRecord["id"]): string => id ], - (views, index): GraphSetViewRecord | undefined => { - return views.get(index); + (views, id): GraphSetViewRecord | undefined => { + return views.get(id); } ); From 78661e7afb891727ea089011eaedd4309b419059 Mon Sep 17 00:00:00 2001 From: Florian Demmer Date: Tue, 31 Dec 2024 15:32:07 +0000 Subject: [PATCH 2/3] further clean up to refer to instances by id, not by index --- server.py | 4 ++-- src/actions/graph.ts | 2 +- src/actions/patchers.ts | 2 +- src/components/editor/index.tsx | 2 +- src/components/editor/patcherNode.tsx | 2 +- src/components/midi/mappedParameterItem.tsx | 2 +- src/components/nav/index.tsx | 6 +++--- src/pages/instances/{[index].tsx => [id].tsx} | 6 +++--- 8 files changed, 13 insertions(+), 13 deletions(-) rename src/pages/instances/{[index].tsx => [id].tsx} (97%) diff --git a/server.py b/server.py index fdc61461..5ce7e724 100755 --- a/server.py +++ b/server.py @@ -45,8 +45,8 @@ def do_GET(self): normPath.remove('') fpath = path.join(args.directory, '{os.sep}'.join(normPath)) - # handle /instances/12 -> /instances/[index].html mapping - ipath = path.join(normPath[0], "[index].html") + # handle /instances/12 -> /instances/[id].html mapping + ipath = path.join(normPath[0], "[id].html") if not path.isfile(fpath) and not fext and path.isfile(fpath + '.html'): self.path = self.path + '.html' diff --git a/src/actions/graph.ts b/src/actions/graph.ts index e1eaf2dd..1cc337b0 100644 --- a/src/actions/graph.ts +++ b/src/actions/graph.ts @@ -714,7 +714,7 @@ export const removePatcherNode = (instanceId: string): AppThunk => if (node?.type !== NodeType.Patcher) return; dispatch(deleteNode(node)); - const instance = getPatcherInstance(state, node.id); + const instance = getPatcherInstance(state, instanceId); if (!instance) return; dispatch(deleteInstance(instance)); diff --git a/src/actions/patchers.ts b/src/actions/patchers.ts index a7d18b91..8c3c1650 100644 --- a/src/actions/patchers.ts +++ b/src/actions/patchers.ts @@ -741,7 +741,7 @@ export const updateInstanceMessageOutportValue = (instanceId: string, tag: Messa if (!enabled) return; // Active Instance view?! - if (Router.pathname !== "/instances/[index]" || Router.query.index !== `${instanceId}`) return; + if (Router.pathname !== "/instances/[id]" || Router.query.id !== `${instanceId}`) return; const instance = getPatcherInstance(state, instanceId); if (!instance) return; diff --git a/src/components/editor/index.tsx b/src/components/editor/index.tsx index 4bcf8400..dd7888dd 100644 --- a/src/components/editor/index.tsx +++ b/src/components/editor/index.tsx @@ -85,7 +85,7 @@ const GraphEditor: FunctionComponent = memo(function WrappedFl const onNodeDoubleClick = useCallback((e: React.MouseEvent, node: Node) => { if (node.type !== NodeType.Patcher) return; - push({ pathname: "/instances/[index]", query: { ...query, index: (node.data.node as GraphPatcherNodeRecord).instanceId }}); + push({ pathname: "/instances/[id]", query: { ...query, id: (node.data.node as GraphPatcherNodeRecord).instanceId }}); }, [query, push]); const flowNodes: Node[] = nodes.valueSeq().toArray().map(node => ({ diff --git a/src/components/editor/patcherNode.tsx b/src/components/editor/patcherNode.tsx index 9b6b65e9..b41a3131 100644 --- a/src/components/editor/patcherNode.tsx +++ b/src/components/editor/patcherNode.tsx @@ -31,7 +31,7 @@ const EditorPatcherNode: FunctionComponent = memo(function Wrap diff --git a/src/components/midi/mappedParameterItem.tsx b/src/components/midi/mappedParameterItem.tsx index 720846c0..fc40ea23 100644 --- a/src/components/midi/mappedParameterItem.tsx +++ b/src/components/midi/mappedParameterItem.tsx @@ -100,7 +100,7 @@ const MIDIMappedParameter: FC = memo(function WrappedMIDIM } component={ Link } - href={{ pathname: "/instances/[index]", query: { ...restQuery, index: instance.id } }} + href={{ pathname: "/instances/[id]", query: { ...restQuery, id: instance.id } }} > Show Instance diff --git a/src/components/nav/index.tsx b/src/components/nav/index.tsx index 7d3010f4..abb8777b 100644 --- a/src/components/nav/index.tsx +++ b/src/components/nav/index.tsx @@ -26,7 +26,7 @@ const AppNav: FunctionComponent = memo(function WrappedNav() { ]); // eslint-disable-next-line @typescript-eslint/no-unused-vars - const { index, ...restQuery } = query; // slurp out potential index query element for a clean query + const { id, ...restQuery } = query; // slurp out potential id query element for a clean query return ( @@ -42,8 +42,8 @@ const AppNav: FunctionComponent = memo(function WrappedNav() { disabled={ instanceId === undefined } icon={ mdiVectorSquare } label="Patcher Instance Control" - href={{ pathname: "/instances/[index]", query: { ...restQuery, index: instanceId } }} - isActive={ pathname === "/instances/[index]" } + href={{ pathname: "/instances/[id]", query: { ...restQuery, id: instanceId } }} + isActive={ pathname === "/instances/[id]" } /> ) => { - push({ pathname, query: { ...query, index: e.currentTarget.value } }); + push({ pathname, query: { ...query, id: e.currentTarget.value } }); }, [push, pathname, query]); const onUnloadInstance = useCallback((e: MouseEvent) => { From fd1d64dc9ea1530b7fdf1729138473d300f82dd6 Mon Sep 17 00:00:00 2001 From: Florian Demmer Date: Tue, 31 Dec 2024 15:45:13 +0000 Subject: [PATCH 3/3] fixed typo --- src/models/set.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/models/set.ts b/src/models/set.ts index 21ac1ded..42bd0c35 100644 --- a/src/models/set.ts +++ b/src/models/set.ts @@ -52,7 +52,7 @@ export class GraphSetViewRecord extends ImmuRecord({ for (const p of params) { const [instanceId, pIndex] = p.split(":"); const paramIndex = parseInt(pIndex, 10); - if (!instanceId.length && !isNaN(paramIndex)) { + if (instanceId.length && !isNaN(paramIndex)) { list.push({ instanceId, paramIndex }); } }