From f887faea7965a3bbb0a5b89820471744284cd522 Mon Sep 17 00:00:00 2001 From: Andrew Belt Date: Thu, 10 Sep 2020 23:30:51 -0400 Subject: [PATCH] Fix module and cable ID variables that were `int` instead of `int64_t`. Add `Engine::getNumCables()` and `Engine::getCableIds()`. --- CHANGELOG.md | 1 + include/app/RackWidget.hpp | 4 +-- include/engine/Engine.hpp | 22 ++++++++------ include/engine/Module.hpp | 2 +- include/engine/ParamHandle.hpp | 2 +- include/history.hpp | 8 +++--- src/app/RackWidget.cpp | 28 +++++++++++------- src/core/MIDI_Map.cpp | 4 +-- src/engine/Cable.cpp | 4 +-- src/engine/Engine.cpp | 52 +++++++++++++++++++++++++++------- 10 files changed, 86 insertions(+), 41 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index be322b69..fa428099 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -62,6 +62,7 @@ In this document, Mod is Ctrl on Windows/Linux and Cmd on Mac. - Improve thread safety of `dsp::RingBuffer`. - Add several convenient filesystem routines to `system::`. - Move all `string::` functions dealing with filesystem paths to `system::`. + - Change type of `Module::id` and `Cable::id` from `int` to `int64_t`. ### 1.1.6 (2019-11-04) - Add ability for plugins to use LuaJIT on Mac. diff --git a/include/app/RackWidget.hpp b/include/app/RackWidget.hpp index 25c9a59c..93b6cef3 100644 --- a/include/app/RackWidget.hpp +++ b/include/app/RackWidget.hpp @@ -57,7 +57,7 @@ struct RackWidget : widget::OpaqueWidget { /** Moves a module to the closest non-colliding position */ void setModulePosNearest(ModuleWidget* mw, math::Vec pos); void setModulePosForce(ModuleWidget* mw, math::Vec pos); - ModuleWidget* getModule(int moduleId); + ModuleWidget* getModule(int64_t moduleId); bool isEmpty(); void updateModuleOldPositions(); history::ComplexAction* getModuleDragAction(); @@ -78,7 +78,7 @@ struct RackWidget : widget::OpaqueWidget { CableWidget* releaseIncompleteCable(); /** Returns the most recently added complete cable connected to the given Port, i.e. the top of the stack. */ CableWidget* getTopCable(PortWidget* port); - CableWidget* getCable(int cableId); + CableWidget* getCable(int64_t cableId); /** Returns all cables attached to port, complete or not. */ std::list getCablesOnPort(PortWidget* port); }; diff --git a/include/engine/Engine.hpp b/include/engine/Engine.hpp index f07762a0..9fe601f6 100644 --- a/include/engine/Engine.hpp +++ b/include/engine/Engine.hpp @@ -67,8 +67,12 @@ struct Engine { // Modules size_t getNumModules(); - void getModuleIds(int* moduleIds, int len); - std::vector getModuleIds(); + /** Fills `moduleIds` with up to `len` module IDs in the rack. + Returns the number of IDs written. + This C-like method does no allocations. The vector C++ version below does. + */ + size_t getModuleIds(int64_t* moduleIds, size_t len); + std::vector getModuleIds(); /** Adds a module to the rack engine. The module ID must not be taken by another module. If the module ID is -1, an ID is automatically assigned. @@ -76,7 +80,7 @@ struct Engine { */ void addModule(Module* module); void removeModule(Module* module); - Module* getModule(int moduleId); + Module* getModule(int64_t moduleId); void resetModule(Module* module); void randomizeModule(Module* module); void bypassModule(Module* module, bool bypassed); @@ -86,6 +90,9 @@ struct Engine { void moduleFromJson(Module* module, json_t* rootJ); // Cables + size_t getNumCables(); + size_t getCableIds(int64_t* cableIds, size_t len); + std::vector getCableIds(); /** Adds a cable to the rack engine. The cable ID must not be taken by another cable. If the cable ID is -1, an ID is automatically assigned. @@ -93,7 +100,7 @@ struct Engine { */ void addCable(Cable* cable); void removeCable(Cable* cable); - Cable* getCable(int cableId); + Cable* getCable(int64_t cableId); // Params void setParam(Module* module, int paramId, float value); @@ -110,14 +117,13 @@ struct Engine { void removeParamHandle(ParamHandle* paramHandle); /** Returns the unique ParamHandle for the given paramId */ - ParamHandle* getParamHandle(int moduleId, int paramId); - /** Use getParamHandle(int, int) instead. - */ + ParamHandle* getParamHandle(int64_t moduleId, int paramId); + /** Use getParamHandle(moduleId, paramId) instead. */ DEPRECATED ParamHandle* getParamHandle(Module* module, int paramId); /** Sets the ParamHandle IDs and module pointer. If `overwrite` is true and another ParamHandle points to the same param, unsets that one and replaces it with the given handle. */ - void updateParamHandle(ParamHandle* paramHandle, int moduleId, int paramId, bool overwrite = true); + void updateParamHandle(ParamHandle* paramHandle, int64_t moduleId, int paramId, bool overwrite = true); json_t* toJson(); void fromJson(json_t* rootJ); diff --git a/include/engine/Module.hpp b/include/engine/Module.hpp index 26952c8a..e63c9a5e 100644 --- a/include/engine/Module.hpp +++ b/include/engine/Module.hpp @@ -50,7 +50,7 @@ struct Module { /** Represents a message-passing channel for an adjacent module. */ struct Expander { /** ID of the expander module, or -1 if nonexistent. */ - int moduleId = -1; + int64_t moduleId = -1; /** Pointer to the expander Module, or NULL if nonexistent. */ Module* module = NULL; /** Double buffer for receiving messages from the expander module. diff --git a/include/engine/ParamHandle.hpp b/include/engine/ParamHandle.hpp index cae77e18..ac037309 100644 --- a/include/engine/ParamHandle.hpp +++ b/include/engine/ParamHandle.hpp @@ -14,7 +14,7 @@ struct ParamHandle { /** Do not set these directly. Use Engine ParamHandle methods. */ - int moduleId = -1; + int64_t moduleId = -1; int paramId = 0; Module* module = NULL; diff --git a/include/history.hpp b/include/history.hpp index 30832795..33b64368 100644 --- a/include/history.hpp +++ b/include/history.hpp @@ -64,7 +64,7 @@ struct ComplexAction : Action { Subclass this to create your own custom actions for your module. */ struct ModuleAction : Action { - int moduleId; + int64_t moduleId; }; @@ -135,10 +135,10 @@ struct ParamChange : ModuleAction { struct CableAdd : Action { - int cableId; - int inputModuleId; + int64_t cableId; + int64_t inputModuleId; int inputId; - int outputModuleId; + int64_t outputModuleId; int outputId; NVGcolor color; void setCable(app::CableWidget* cw); diff --git a/src/app/RackWidget.cpp b/src/app/RackWidget.cpp index aa6b886e..e9850eb6 100644 --- a/src/app/RackWidget.cpp +++ b/src/app/RackWidget.cpp @@ -182,11 +182,13 @@ void RackWidget::mergeJson(json_t* rootJ) { json_t* idJ = json_object_get(moduleJ, "id"); if (!idJ) continue; - int id = json_integer_value(idJ); + int64_t id = json_integer_value(idJ); // TODO Legacy v0.6? ModuleWidget* moduleWidget = getModule(id); - if (!moduleWidget) + if (!moduleWidget) { + WARN("Cannot find ModuleWidget with ID %ld", id); continue; + } // pos math::Vec pos = moduleWidget->box.pos.minus(moduleOffset); @@ -206,10 +208,12 @@ void RackWidget::mergeJson(json_t* rootJ) { json_t* idJ = json_object_get(cableJ, "id"); if (!idJ) continue; - int id = json_integer_value(idJ); + int64_t id = json_integer_value(idJ); CableWidget* cw = getCable(id); - if (!cw) + if (!cw) { + WARN("Cannot find CableWidget with ID %ld", id); continue; + } json_t* cwJ = cw->toJson(); // Merge cable JSON object @@ -230,10 +234,12 @@ void RackWidget::fromJson(json_t* rootJ) { json_t* idJ = json_object_get(moduleJ, "id"); if (!idJ) continue; - int id = json_integer_value(idJ); + int64_t id = json_integer_value(idJ); engine::Module* module = APP->engine->getModule(id); - if (!module) + if (!module) { + WARN("Cannot find module with ID %ld", id); continue; + } ModuleWidget* moduleWidget = module->model->createModuleWidget(module); @@ -273,10 +279,12 @@ void RackWidget::fromJson(json_t* rootJ) { json_t* idJ = json_object_get(cableJ, "id"); if (!idJ) continue; - int id = json_integer_value(idJ); + int64_t id = json_integer_value(idJ); engine::Cable* cable = APP->engine->getCable(id); - if (!cable) + if (!cable) { + WARN("Cannot find cable with ID %ld", id); continue; + } CableWidget* cw = new CableWidget; // Legacy: Before v1, cable colors were not serialized. So we need to initialize the color here. @@ -515,7 +523,7 @@ void RackWidget::setModulePosForce(ModuleWidget* mw, math::Vec pos) { RackWidget_updateAdjacent(this); } -ModuleWidget* RackWidget::getModule(int moduleId) { +ModuleWidget* RackWidget::getModule(int64_t moduleId) { for (widget::Widget* w : moduleContainer->children) { ModuleWidget* mw = dynamic_cast(w); assert(mw); @@ -648,7 +656,7 @@ CableWidget* RackWidget::getTopCable(PortWidget* port) { return NULL; } -CableWidget* RackWidget::getCable(int cableId) { +CableWidget* RackWidget::getCable(int64_t cableId) { for (widget::Widget* w : cableContainer->children) { CableWidget* cw = dynamic_cast(w); assert(cw); diff --git a/src/core/MIDI_Map.cpp b/src/core/MIDI_Map.cpp index 17ec545e..366c82bd 100644 --- a/src/core/MIDI_Map.cpp +++ b/src/core/MIDI_Map.cpp @@ -225,7 +225,7 @@ struct MIDI_Map : Module { } } - void learnParam(int id, int moduleId, int paramId) { + void learnParam(int id, int64_t moduleId, int paramId) { APP->engine->updateParamHandle(¶mHandles[id], moduleId, paramId, true); learnedParam = true; commitLearn(); @@ -335,7 +335,7 @@ struct MIDI_MapChoice : LedDisplayChoice { ParamWidget* touchedParam = APP->scene->rack->touchedParam; if (touchedParam) { APP->scene->rack->touchedParam = NULL; - int moduleId = touchedParam->module->id; + int64_t moduleId = touchedParam->module->id; int paramId = touchedParam->paramId; module->learnParam(id, moduleId, paramId); } diff --git a/src/engine/Cable.cpp b/src/engine/Cable.cpp index 4f8b4f46..6dca57d2 100644 --- a/src/engine/Cable.cpp +++ b/src/engine/Cable.cpp @@ -23,7 +23,7 @@ void Cable::fromJson(json_t* rootJ) { json_t* inputModuleIdJ = json_object_get(rootJ, "inputModuleId"); if (!inputModuleIdJ) throw Exception("inputModuleId not found for cable"); - int inputModuleId = json_integer_value(inputModuleIdJ); + int64_t inputModuleId = json_integer_value(inputModuleIdJ); inputModule = APP->engine->getModule(inputModuleId); if (!inputModule) throw Exception("inputModule not found for cable"); @@ -38,7 +38,7 @@ void Cable::fromJson(json_t* rootJ) { json_t* outputModuleIdJ = json_object_get(rootJ, "outputModuleId"); if (!outputModuleIdJ) throw Exception("outputModuleId not found for cable"); - int outputModuleId = json_integer_value(outputModuleIdJ); + int64_t outputModuleId = json_integer_value(outputModuleIdJ); outputModule = APP->engine->getModule(outputModuleId); if (!outputModule) throw Exception("outputModule not found for cable"); diff --git a/src/engine/Engine.cpp b/src/engine/Engine.cpp index 6d368448..12bb1fdc 100644 --- a/src/engine/Engine.cpp +++ b/src/engine/Engine.cpp @@ -188,11 +188,11 @@ struct Engine::Internal { std::set paramHandles; // moduleId - std::map modulesCache; + std::map modulesCache; // cableId - std::map cablesCache; + std::map cablesCache; // (moduleId, paramId) - std::map, ParamHandle*> paramHandlesCache; + std::map, ParamHandle*> paramHandlesCache; float sampleRate = 0.f; float sampleTime = 0.f; @@ -657,21 +657,22 @@ size_t Engine::getNumModules() { } -void Engine::getModuleIds(int* moduleIds, int len) { +size_t Engine::getModuleIds(int64_t* moduleIds, size_t len) { SharedLock lock(internal->mutex); - int i = 0; + size_t i = 0; for (Module* m : internal->modules) { if (i >= len) break; moduleIds[i] = m->id; i++; } + return i; } -std::vector Engine::getModuleIds() { +std::vector Engine::getModuleIds() { SharedLock lock(internal->mutex); - std::vector moduleIds; + std::vector moduleIds; moduleIds.reserve(internal->modules.size()); for (Module* m : internal->modules) { moduleIds.push_back(m->id); @@ -748,7 +749,7 @@ void Engine::removeModule(Module* module) { } -Module* Engine::getModule(int moduleId) { +Module* Engine::getModule(int64_t moduleId) { SharedLock lock(internal->mutex); auto it = internal->modulesCache.find(moduleId); if (it == internal->modulesCache.end()) @@ -812,6 +813,35 @@ void Engine::moduleFromJson(Module* module, json_t* rootJ) { } +size_t Engine::getNumCables() { + return internal->cables.size(); +} + + +size_t Engine::getCableIds(int64_t* cableIds, size_t len) { + SharedLock lock(internal->mutex); + size_t i = 0; + for (Cable* c : internal->cables) { + if (i >= len) + break; + cableIds[i] = c->id; + i++; + } + return i; +} + + +std::vector Engine::getCableIds() { + SharedLock lock(internal->mutex); + std::vector cableIds; + cableIds.reserve(internal->cables.size()); + for (Cable* c : internal->cables) { + cableIds.push_back(c->id); + } + return cableIds; +} + + void Engine::addCable(Cable* cable) { ExclusiveSharedLock lock(internal->mutex); assert(cable); @@ -893,7 +923,7 @@ void Engine::removeCable(Cable* cable) { } -Cable* Engine::getCable(int cableId) { +Cable* Engine::getCable(int64_t cableId) { SharedLock lock(internal->mutex); auto it = internal->cablesCache.find(cableId); if (it == internal->cablesCache.end()) @@ -965,7 +995,7 @@ void Engine::removeParamHandle(ParamHandle* paramHandle) { } -ParamHandle* Engine::getParamHandle(int moduleId, int paramId) { +ParamHandle* Engine::getParamHandle(int64_t moduleId, int paramId) { SharedLock lock(internal->mutex); auto it = internal->paramHandlesCache.find(std::make_tuple(moduleId, paramId)); if (it == internal->paramHandlesCache.end()) @@ -979,7 +1009,7 @@ ParamHandle* Engine::getParamHandle(Module* module, int paramId) { } -void Engine::updateParamHandle(ParamHandle* paramHandle, int moduleId, int paramId, bool overwrite) { +void Engine::updateParamHandle(ParamHandle* paramHandle, int64_t moduleId, int paramId, bool overwrite) { SharedLock lock(internal->mutex); // Check that it exists auto it = internal->paramHandles.find(paramHandle);