@@ -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. | |||
@@ -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<CableWidget*> getCablesOnPort(PortWidget* port); | |||
}; | |||
@@ -67,8 +67,12 @@ struct Engine { | |||
// Modules | |||
size_t getNumModules(); | |||
void getModuleIds(int* moduleIds, int len); | |||
std::vector<int> 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<int64_t> 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<int64_t> 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); | |||
@@ -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. | |||
@@ -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; | |||
@@ -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); | |||
@@ -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<ModuleWidget*>(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<CableWidget*>(w); | |||
assert(cw); | |||
@@ -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); | |||
} | |||
@@ -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"); | |||
@@ -188,11 +188,11 @@ struct Engine::Internal { | |||
std::set<ParamHandle*> paramHandles; | |||
// moduleId | |||
std::map<int, Module*> modulesCache; | |||
std::map<int64_t, Module*> modulesCache; | |||
// cableId | |||
std::map<int, Cable*> cablesCache; | |||
std::map<int64_t, Cable*> cablesCache; | |||
// (moduleId, paramId) | |||
std::map<std::tuple<int, int>, ParamHandle*> paramHandlesCache; | |||
std::map<std::tuple<int64_t, int>, 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<int> Engine::getModuleIds() { | |||
std::vector<int64_t> Engine::getModuleIds() { | |||
SharedLock lock(internal->mutex); | |||
std::vector<int> moduleIds; | |||
std::vector<int64_t> 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<int64_t> Engine::getCableIds() { | |||
SharedLock lock(internal->mutex); | |||
std::vector<int64_t> 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); | |||