From 60b4bd7db3f407bf1aff8c85045482fec6c498e1 Mon Sep 17 00:00:00 2001 From: vitreo12 Date: Sat, 29 Oct 2022 14:21:59 +0200 Subject: [PATCH] Engine: simplify ordering and add debug printing --- src/override/Engine.cpp | 95 +++++++++++++---------------------------- 1 file changed, 30 insertions(+), 65 deletions(-) diff --git a/src/override/Engine.cpp b/src/override/Engine.cpp index 2ee59ea..2ce8b82 100644 --- a/src/override/Engine.cpp +++ b/src/override/Engine.cpp @@ -278,74 +278,50 @@ static void Port_setConnected(Port* that) { that->channels = 1; } -template -using Dictionary = std::unordered_map; template using IdentityDictionary = std::unordered_map; -template -inline bool dictContains(Dictionary &dict, T key) { +template +inline bool dictContains(IdentityDictionary &dict, T key) { return dict.find(key) != dict.end(); } -template -inline void dictAdd(Dictionary &dict, T key, Y entry) { - dict[key] = entry; -} - template inline void dictAdd(IdentityDictionary &dict, T key) { dict[key] = key; } -static void Engine_detectFeedback(Module* targetModule, Module* currentModule, Dictionary> &feedbacks, IdentityDictionary &touchedModules, IdentityDictionary &terminalModulesIDs) { - if (!dictContains(touchedModules, currentModule) && !dictContains(terminalModulesIDs, currentModule->id)) { - dictAdd(touchedModules, currentModule); - for (Output& currentOutput : currentModule->outputs) { - for (Cable* currentOutCable : currentOutput.cables) { - Module* outModule = currentOutCable->inputModule; //The input to the cable is the receiving module - if ((outModule == targetModule) && !((dictContains(feedbacks[targetModule], outModule) || dictContains(feedbacks[outModule], targetModule)))) { - // is this correct? which modules should be added? the starting ones? - dictAdd(feedbacks[targetModule], outModule); - dictAdd(feedbacks[outModule], targetModule); - printf("\nFB: %ld -> %ld\n", currentModule->id, targetModule->id); - } - else - Engine_detectFeedback(targetModule, outModule, feedbacks, touchedModules, terminalModulesIDs); - } - } - } -} - -static void Engine_findFeedbacks(std::vector modules, Dictionary> &feedbacks, IdentityDictionary &terminalModulesIDs) { - for (Module* module : modules) { - IdentityDictionary touchedModules; - Engine_detectFeedback(module, module, feedbacks, touchedModules, terminalModulesIDs); - } -} - -static bool Engine_isFeedback(Module* sender, Module* receiver, Dictionary> &feedbacks) { - return dictContains(feedbacks[sender], receiver) || dictContains(feedbacks[receiver], sender); +static void Engine_storeTerminalModulesIDs(std::vector terminalModules, IdentityDictionary &terminalModulesIDs) { + for (TerminalModule* terminalModule : terminalModules) + dictAdd(terminalModulesIDs, terminalModule->id); } -static void Engine_orderModule(Module* module, IdentityDictionary &touchedModules, std::vector &orderedModules, Dictionary> &feedbacks, IdentityDictionary &terminalModulesIDs) { - if (!dictContains(touchedModules, module) && !dictContains(terminalModulesIDs, module->id)) { +static void Engine_orderModule(Module* module, IdentityDictionary &touchedModules, std::vector &orderedModules, IdentityDictionary &terminalModulesIDs) { + if (!dictContains(touchedModules, module) && !dictContains(terminalModulesIDs, module->id)) { // Ignore feedback loops and terminal modules dictAdd(touchedModules, module); for (Output& output : module->outputs) { for (Cable* cable : output.cables) { - Module* receiver = cable->inputModule; - if (!Engine_isFeedback(module, receiver, feedbacks)) - Engine_orderModule(receiver, touchedModules, orderedModules, feedbacks, terminalModulesIDs); + Module* receiver = cable->inputModule; // The input to the cable is the receiving module + Engine_orderModule(receiver, touchedModules, orderedModules, terminalModulesIDs); } } orderedModules.push_back(module); } } -void Engine_storeTerminalModulesIDs(std::vector terminalModules, IdentityDictionary &terminalModulesIDs) { - for (TerminalModule* terminalModule : terminalModules) - dictAdd(terminalModulesIDs, terminalModule->id); +static void Engine_assignOrderedModules(std::vector &modules, std::vector &orderedModules) { + std::reverse(orderedModules.begin(), orderedModules.end()); // These are stored bottom up + if (orderedModules.size() == modules.size()) { + for (unsigned int i = 0; i < orderedModules.size(); i++) + modules[i] = orderedModules[i]; + } +} + +static void Engine_debugOrderedModules(std::vector &modules) { + printf("\n--- Ordered modules ---\n"); + for (unsigned int i = 0; i < modules.size(); i++) + printf("%d) %s - %ld\n", i, modules[i]->model->getFullName().c_str(), modules[i]->id); } /** Order the modules so that they always read the most recent sample from their inputs @@ -356,27 +332,15 @@ static void Engine_orderModules(Engine* that) { IdentityDictionary terminalModulesIDs; Engine_storeTerminalModulesIDs(internal->terminalModules, terminalModulesIDs); - Dictionary> feedbacks; - Engine_findFeedbacks(internal->modules, feedbacks, terminalModulesIDs); - - //IdentityDictionary visitedModules; //global IdentityDictionary touchedModules; - //std::vector unvisitedModules(internal->modules); //copy std::vector orderedModules; - orderedModules.reserve(internal->modules.size()); //return - for (Module* module : internal->modules) { - //Module* module = unvisitedModules[unvisitedModules.size() - 1]; //get last one - Engine_orderModule(module, touchedModules, orderedModules, feedbacks, terminalModulesIDs); - //unvisitedModules.pop_back(); //pop last one - } - std::reverse(orderedModules.begin(), orderedModules.end()); - printf("\n\nORDERED MODULES %ld:\n", orderedModules.size()); - if (orderedModules.size() == internal->modules.size()) { - for (unsigned int i = 0; i < orderedModules.size(); i++) { - printf("%d) %ld \n", i, orderedModules[i]->id); - internal->modules[i] = orderedModules[i]; - } - } + orderedModules.reserve(internal->modules.size()); + for (Module* module : internal->modules) + Engine_orderModule(module, touchedModules, orderedModules, terminalModulesIDs); + + Engine_assignOrderedModules(internal->modules, orderedModules); + + Engine_debugOrderedModules(internal->modules); } @@ -422,6 +386,7 @@ static void Engine_updateConnected(Engine* that) { Port_setDisconnected(output); DISTRHO_SAFE_ASSERT(output->cables.empty()); } + // Order the modules according to their connections Engine_orderModules(that); } @@ -722,7 +687,7 @@ void Engine::addModule(Module* module) { if (paramHandle->moduleId == module->id) paramHandle->module = module; } - printf("NEW MODULE: %ld\n", module->id); + printf("New module: %s - %ld\n", module->model->getFullName().c_str(), module->id); }