| @@ -409,9 +409,6 @@ static void Engine_stepFrame(Engine* that) { | |||||
| static void Port_setDisconnected(Port* that) { | static void Port_setDisconnected(Port* that) { | ||||
| that->channels = 0; | that->channels = 0; | ||||
| for (int c = 0; c < PORT_MAX_CHANNELS; c++) { | |||||
| that->voltages[c] = 0.f; | |||||
| } | |||||
| } | } | ||||
| @@ -422,38 +419,6 @@ static void Port_setConnected(Port* that) { | |||||
| } | } | ||||
| static void Engine_updateConnected(Engine* that) { | |||||
| // Find disconnected ports | |||||
| std::set<Port*> disconnectedPorts; | |||||
| for (Module* module : that->internal->modules) { | |||||
| for (Input& input : module->inputs) { | |||||
| disconnectedPorts.insert(&input); | |||||
| } | |||||
| for (Output& output : module->outputs) { | |||||
| disconnectedPorts.insert(&output); | |||||
| } | |||||
| } | |||||
| for (Cable* cable : that->internal->cables) { | |||||
| // Connect input | |||||
| Input& input = cable->inputModule->inputs[cable->inputId]; | |||||
| auto inputIt = disconnectedPorts.find(&input); | |||||
| if (inputIt != disconnectedPorts.end()) | |||||
| disconnectedPorts.erase(inputIt); | |||||
| Port_setConnected(&input); | |||||
| // Connect output | |||||
| Output& output = cable->outputModule->outputs[cable->outputId]; | |||||
| auto outputIt = disconnectedPorts.find(&output); | |||||
| if (outputIt != disconnectedPorts.end()) | |||||
| disconnectedPorts.erase(outputIt); | |||||
| Port_setConnected(&output); | |||||
| } | |||||
| // Disconnect ports that have no cable | |||||
| for (Port* port : disconnectedPorts) { | |||||
| Port_setDisconnected(port); | |||||
| } | |||||
| } | |||||
| static void Engine_refreshParamHandleCache(Engine* that) { | static void Engine_refreshParamHandleCache(Engine* that) { | ||||
| // Clear cache | // Clear cache | ||||
| that->internal->paramHandlesCache.clear(); | that->internal->paramHandlesCache.clear(); | ||||
| @@ -963,8 +928,7 @@ void Engine::addCable(Cable* cable) { | |||||
| assert(cable2 != cable); | assert(cable2 != cable); | ||||
| // Check that the input is not already used by another cable | // Check that the input is not already used by another cable | ||||
| assert(!(cable2->inputModule == cable->inputModule && cable2->inputId == cable->inputId)); | assert(!(cable2->inputModule == cable->inputModule && cable2->inputId == cable->inputId)); | ||||
| // Get connected status of output, to decide whether we need to call a PortChangeEvent. | |||||
| // It's best to not trust `cable->outputModule->outputs[cable->outputId]->isConnected()` | |||||
| // Check if output is already connected to a cable | |||||
| if (cable2->outputModule == cable->outputModule && cable2->outputId == cable->outputId) | if (cable2->outputModule == cable->outputModule && cable2->outputId == cable->outputId) | ||||
| outputWasConnected = true; | outputWasConnected = true; | ||||
| } | } | ||||
| @@ -976,7 +940,12 @@ void Engine::addCable(Cable* cable) { | |||||
| // Add the cable | // Add the cable | ||||
| internal->cables.push_back(cable); | internal->cables.push_back(cable); | ||||
| internal->cablesCache[cable->id] = cable; | internal->cablesCache[cable->id] = cable; | ||||
| Engine_updateConnected(this); | |||||
| // Set input as connected | |||||
| Input& input = cable->inputModule->inputs[cable->inputId]; | |||||
| Port_setConnected(&input); | |||||
| // Set output as connected, which might already be connected | |||||
| Output& output = cable->outputModule->outputs[cable->outputId]; | |||||
| Port_setConnected(&output); | |||||
| // Dispatch input port event | // Dispatch input port event | ||||
| { | { | ||||
| Module::PortChangeEvent e; | Module::PortChangeEvent e; | ||||
| @@ -1010,13 +979,21 @@ void Engine::removeCable_NoLock(Cable* cable) { | |||||
| // Remove the cable | // Remove the cable | ||||
| internal->cablesCache.erase(cable->id); | internal->cablesCache.erase(cable->id); | ||||
| internal->cables.erase(it); | internal->cables.erase(it); | ||||
| Engine_updateConnected(this); | |||||
| // Set input as disconnected | |||||
| Input& input = cable->inputModule->inputs[cable->inputId]; | |||||
| Port_setDisconnected(&input); | |||||
| // Check if output is still connected to a cable | |||||
| bool outputIsConnected = false; | bool outputIsConnected = false; | ||||
| for (Cable* cable2 : internal->cables) { | for (Cable* cable2 : internal->cables) { | ||||
| // Get connected status of output, to decide whether we need to call a PortChangeEvent. | |||||
| // It's best to not trust `cable->outputModule->outputs[cable->outputId]->isConnected()` | |||||
| if (cable2->outputModule == cable->outputModule && cable2->outputId == cable->outputId) | |||||
| if (cable2->outputModule == cable->outputModule && cable2->outputId == cable->outputId) { | |||||
| outputIsConnected = true; | outputIsConnected = true; | ||||
| break; | |||||
| } | |||||
| } | |||||
| // Set output as disconnected if disconnected from all cables | |||||
| if (!outputIsConnected) { | |||||
| Output& output = cable->outputModule->outputs[cable->outputId]; | |||||
| Port_setDisconnected(&output); | |||||
| } | } | ||||
| // Dispatch input port event | // Dispatch input port event | ||||
| { | { | ||||