Browse Source

Engine: simplify ordering and add debug printing

pull/410/head
vitreo12 3 years ago
parent
commit
60b4bd7db3
1 changed files with 30 additions and 65 deletions
  1. +30
    -65
      src/override/Engine.cpp

+ 30
- 65
src/override/Engine.cpp View File

@@ -278,74 +278,50 @@ static void Port_setConnected(Port* that) {
that->channels = 1;
}

template<typename T, typename Y>
using Dictionary = std::unordered_map<T, Y>;

template<typename T>
using IdentityDictionary = std::unordered_map<T, T>;

template<typename T, typename Y>
inline bool dictContains(Dictionary<T, Y> &dict, T key) {
template<typename T>
inline bool dictContains(IdentityDictionary<T> &dict, T key) {
return dict.find(key) != dict.end();
}

template<typename T, typename Y>
inline void dictAdd(Dictionary<T, Y> &dict, T key, Y entry) {
dict[key] = entry;
}

template<typename T>
inline void dictAdd(IdentityDictionary<T> &dict, T key) {
dict[key] = key;
}

static void Engine_detectFeedback(Module* targetModule, Module* currentModule, Dictionary<Module*, IdentityDictionary<Module*>> &feedbacks, IdentityDictionary<Module*> &touchedModules, IdentityDictionary<int64_t> &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<Module*> modules, Dictionary<Module*, IdentityDictionary<Module*>> &feedbacks, IdentityDictionary<int64_t> &terminalModulesIDs) {
for (Module* module : modules) {
IdentityDictionary<Module*> touchedModules;
Engine_detectFeedback(module, module, feedbacks, touchedModules, terminalModulesIDs);
}
}

static bool Engine_isFeedback(Module* sender, Module* receiver, Dictionary<Module*, IdentityDictionary<Module*>> &feedbacks) {
return dictContains(feedbacks[sender], receiver) || dictContains(feedbacks[receiver], sender);
static void Engine_storeTerminalModulesIDs(std::vector<TerminalModule*> terminalModules, IdentityDictionary<int64_t> &terminalModulesIDs) {
for (TerminalModule* terminalModule : terminalModules)
dictAdd(terminalModulesIDs, terminalModule->id);
}

static void Engine_orderModule(Module* module, IdentityDictionary<Module*> &touchedModules, std::vector<Module*> &orderedModules, Dictionary<Module*, IdentityDictionary<Module*>> &feedbacks, IdentityDictionary<int64_t> &terminalModulesIDs) {
if (!dictContains(touchedModules, module) && !dictContains(terminalModulesIDs, module->id)) {
static void Engine_orderModule(Module* module, IdentityDictionary<Module*> &touchedModules, std::vector<Module*> &orderedModules, IdentityDictionary<int64_t> &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<TerminalModule*> terminalModules, IdentityDictionary<int64_t> &terminalModulesIDs) {
for (TerminalModule* terminalModule : terminalModules)
dictAdd(terminalModulesIDs, terminalModule->id);
static void Engine_assignOrderedModules(std::vector<Module*> &modules, std::vector<Module*> &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<Module*> &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<int64_t> terminalModulesIDs;
Engine_storeTerminalModulesIDs(internal->terminalModules, terminalModulesIDs);

Dictionary<Module*, IdentityDictionary<Module*>> feedbacks;
Engine_findFeedbacks(internal->modules, feedbacks, terminalModulesIDs);

//IdentityDictionary<Module*> visitedModules; //global
IdentityDictionary<Module*> touchedModules;
//std::vector<Module*> unvisitedModules(internal->modules); //copy
std::vector<Module*> 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);
}




Loading…
Cancel
Save