Significantly large amount of CustomValueVariable makes Cubase interface lagging

I’m trying to trigger Key Commands via this code

// ----------------------------------------------------------------------------
// SURFACE
// ----------------------------------------------------------------------------
var surface = deviceDriver.mSurface
var slotSelectButtons = []
var keyCommandsObj = []

for (var s = 0; s < 16; s++) {
    var btnSlot = surface.makeButton(s, 0, 1, 1)
    btnSlot.mSurfaceValue.mMidiBinding.setInputPort(midiInput).bindToNote(1, s)
    slotSelectButtons.push(btnSlot)
}

var dummyFader = surface.makeFader(0, 0, 0, 0)
dummyFader.mSurfaceValue.mMidiBinding.setInputPort(midiInput).bindToPitchBend(12)
dummyFader.mSurfaceValue.mOnProcessValueChange = function (activeDevice, value, diff) {
    var kcIndex = Math.round(value * 16383)-8192
    console.log("[Assistant] Command: " + keyCommands[kcIndex].category + " - " + keyCommands[kcIndex].command)
    keyCommandsObj[kcIndex].setProcessValue(activeDevice, 1)
}

// ----------------------------------------------------------------------------
// MAPPING
// ----------------------------------------------------------------------------
function makePageWithDefaults(name) {
    var page = deviceDriver.mMapping.makePage(name)
    var kcInit = false

    if (!kcInit) {
        for (var i = 0; i < keyCommands.length; i++) {
            var kc = keyCommands[i]; // { index, category, command }
            var obj = surface.makeCustomValueVariable('kcObj' + kc.index);
            page.makeCommandBinding(obj, kc.category, kc.command)
            keyCommandsObj.push(obj);
        }
        kcInit = true
    }

    return page
}

Key Commands.xml parsed into JS object (var keyCommands = require(‘./keyCommands’))

module.exports = [
  { index: 0, category: "Preferences", command: "Controls - Value Box/Time Control Mode" },
  { index: 1, category: "Preferences", command: "MediaBay - Scan Folders only when MediaBay is open" },
  { index: 2, category: "Preferences", command: "MediaBay - Scan unknown File Types" },
………
  { index: 3228, category: "Process Plug-in", command: "132A82E52E2548ED8D1384E92C1C8B0E" }
];

So, it’s kinda big object, but everythyng works fine, exept one thing - Cubase interface starts lagging when track selection chenges. It didn’t happen without makeCommandBinding, but, oc, not working then

Hi, I didn’t experience lagging, but I didn’t use a control for inputting the index, in this prototype A Key Commander for Cubase (Jump Bar?) . Instead I used sysex messages. Not sure if this can make a difference at your side.

Here’s the script I used:

var commandsFile=require('./Commands')
var mapOfCommands=commandsFile.mapOfCommands
var sysexHeader=[240,0,32,41,2,10,1]

var midiremote_api = require('midiremote_api_v1')
var deviceDriver = midiremote_api.makeDeviceDriver("Test","Commander","m.c")

var midiInput = deviceDriver.mPorts.makeMidiInput("anInput")

var detectionUnit=deviceDriver.makeDetectionUnit()
detectionUnit.detectSingleInput(midiInput)
    .expectInputNameEquals("loopMIDI Port")

var surface=deviceDriver.mSurface
var mapping=deviceDriver.mMapping

var customVars={}

var page=mapping.makePage("Commander")

Object.keys(mapOfCommands).forEach(function(commandIndex){
    
    var commandArray=mapOfCommands[commandIndex]
    var commandCategory=commandArray[0]
    var commandName=commandArray[1]
    
    customVars[commandIndex]=surface.makeCustomValueVariable("customVar"+commandIndex)
    
    page.makeCommandBinding(customVars[commandIndex],commandCategory,commandName).mOnValueChange=function(activeDevice,activeMapping,value,diff){
    
        if(value==1){
    
            customVars[this.commandIndex].setProcessValue(activeDevice,0)

        }
    
    }.bind({commandIndex})

})

midiInput.mOnSysex=function(activeDevice,midiMessage){
  
    for(var i=0;i<sysexHeader.length;i++) {
    
        if(midiMessage[i]!==sysexHeader[i]) return
  
    }

    var body=midiMessage.slice(sysexHeader.length,midiMessage.length-1)
    
    var commandIndex=String.fromCharCode.apply(null,body)

    if(customVars && Object.prototype.hasOwnProperty.call(customVars, commandIndex)){

        customVars[commandIndex].setProcessValue(activeDevice,1)
  
    }

}

And part of my Commands.js (mine has around 2000 elements):

var mapOfCommands={
0:["ADM Editor","ADM Editor..."],
1:["ADM Editor","Add Bed"],
2:["ADM Editor","Add Object"],
3:["ADM Editor","Apply Source Track Name"],
4:["ADM Editor","Create objects from selected tracks"],
5:["ADM Editor","Open Group Editor"],
6:["ADM Editor","Open Trim and Downmix Editor"],
7:["ADM Editor","Remove Selected Audio Object"],
...
}

Maybe you could try the sysex approach and see if this helps. I currently have no access to my music PC so can’t really test your code for lagging.

By the way, why do you need the dynamic selection of a command? If you have a template that you want to add commands later on, you can always do that and call the “Scripting Tools: Reload Scripts” command. This way you can minimize the overhead. The dynamic approach makes sense in apps like mine, where we really need the ability to search over all the available commands.

Cuz it’s works through my custom midware, wich recieves OSC messages, interpretates them and sends MIDI messages to virtual port. The point is that I can create any button for any command at any time without reloading MR

But this approach causing lags. For eg when scrolling tracks via arrow keys I can clearly see that track selection changes with some latency (about 200-300ms)

Just tried triggering with SysEx instead of pitchbend - still lagging