amazing! I’ll defo check that out, thanks for the response.
It’s been a while since I debugged on a Mac. I thought they had some fake gdb to translate. But if you have to use lldb it’s ok. I always build my rack and then do plugins there, and running rack under a debugger is just make debug.
Also, that json stuff is weird. I think json-t is a ref counted pointer.
I notice that most people are storing strings to JSON direct from their Module struct, I couldn’t find an example of how to do it from a widget. Yeah, been looking on the github comments for the GDB patch for OSX 10.14 and loads of people are having issues, so that might take a while to sort.
It’s not recommended to do it from the widget. It used to be done like that, but as the api has changed, it’s now recommended to do it all from the module.
Thanks David. Ok I see, I assumed that was the case and that’s what I’ve been attempting to do. So I’ve been trying to shared between the (drag and drop) TransparentWidget the (Display SVG image) SvgWidget and the actual Module using pointers and that’s where I’ve gotten messed up. I can share the path between the widgets and that part works, it’s just getting the same location saved to JSON that’s confusing me
Put one pointer in the module. Then either widget can update it, and the module can save it.
Don’t try to do anything with it if the module isn’t there, but you won’t be dragging and dropping to the version in the browser, so that shouldn’t be a problem.
You won’t need to access that pointer from the module’s process method, so there shouldn’t be any threading issues.
Ok, having a bit more luck. This is how I have the pointers setup now…
// make NEWPATH, svgPath and jsonSavePath point to the same memory location
CP->NEWPATH = &DND->svgPath;
if (module)
{
module->jsonSavePath = *CP->NEWPATH;
std::cout << module->jsonSavePath << "\n";
}
the drag and drop works and there’s no longer a seg fault, however the jsonSavePath is not updating to the new NEWPATH. The console.log just shows the initial NEWPATH and not the current one set after dragging and dropping, so i have no persistence. I feel like i’m missing a trick here? There’s got to be an easier way of doing this
I’m not really clear what you are trying to do. But why is NEWPATH a pointer to a std::string rather than a std::string?
#include "plugin.hpp"
#include <iostream>
struct _4hp : Module
{
enum ParamId
{
PARAMS_LEN
};
enum InputId
{
INPUTS_LEN
};
enum OutputId
{
OUTPUTS_LEN
};
enum LightId
{
LIGHTS_LEN
};
_4hp()
{
config(PARAMS_LEN, INPUTS_LEN, OUTPUTS_LEN, LIGHTS_LEN);
}
std::string jsonSavePath; // storage for SVG image file path
// save and load filepath to JSON file
json_t *dataToJson() override
{
json_t *rootJ = json_object();
json_object_set_new(rootJ, "sPATH", json_string(jsonSavePath.c_str()));
return rootJ;
}
void dataFromJson(json_t *rootJ) override
{
json_t *savedPATHJ = json_object_get(rootJ, "sPATH");
jsonSavePath = json_string_value(savedPATHJ);
}
};
struct customPanel : SvgWidget
{
std::string *NEWPATH; // incoming SVG file path
std::string PATH; // current SVG file path
customPanel()
{
setSvg(Svg::load(asset::plugin(pluginInstance, PATH))); // set SVG file on creation of customPanel
}
void draw(const DrawArgs& args) override
{
if(*NEWPATH != PATH) // check if SVG file path has changed
{
setSvg(Svg::load(asset::plugin(pluginInstance, *NEWPATH))); // set new file path
PATH = *NEWPATH; // asign new path to current path variable
}
SvgWidget::draw(args); // continue to run the rest of the default draw function
}
};
struct dnd : TransparentWidget
{
std::string filePath; // path of dropped file
std::string svgPath = asset::plugin(pluginInstance, "res/test.svg"); // path with SVG extension
void onPathDrop(const PathDropEvent &e) override
{
filePath = e.paths.front(); // get first path in array, all other paths are ignored
if(filePath.substr(filePath.find_last_of(".") + 1) == "svg") // check for SVG extension
{
svgPath = filePath; // store path
}
else
{
std::cout << "Invalid file extension: try *.svg" << "\n";
}
}
};
struct _4hpWidget : ModuleWidget
{
_4hpWidget(_4hp *module)
{
setModule(module);
setPanel(createPanel(asset::plugin(pluginInstance, "res/4hp.svg")));
// maunally add widgets to allow for pointer references
dnd *DND = new dnd();
DND->box.pos = Vec(0, 0);
DND->box.size = Vec(RACK_GRID_WIDTH * 4, RACK_GRID_HEIGHT);
addChild(DND);
customPanel *CP = new customPanel();
CP->box.pos = Vec(0, 0);
CP->box.size = Vec(RACK_GRID_WIDTH * 4, RACK_GRID_HEIGHT);
addChild(CP);
// make NEWPATH, svgPath and jsonSavePath point to the same memory location
CP->NEWPATH = &DND->svgPath;
if (module)
{
module->jsonSavePath = *CP->NEWPATH;
std::cout << module->jsonSavePath << "\n";
}
}
};
Model* model_4hp = createModel<_4hp, _4hpWidget>("4hp");
NEWPATH is not in the Module it’s in the SvgWidget, JsonSavePath is in the main Module
But why is newpath defined as a pointer?
Good question! I’m not sure, will change it and see if that works…
I’m not sure why you need it at all. Is there more code that you have not posted?
No that’s everything, it should be short and sweet…drag and drop SVG file onto TransparentWidget, check it’s an SVG, then pass path to SvgWidget and draw image, then pass the currently displayed image path to the Module so it can save and load it from JSON
As far as i can see, you are only updating the svgSavePath once, and that is when your module is created. You aren’t updating it after the drop event
Yeah, that’s why I was using pointers, so it should all point to the same memloc, so dragging and dropping should trigger everything when it updates the SvgPath
Ok. I think the problem then, is that your module->jsonSavePath is NOT a pointer, so you are not getting them all to point to the same memloc. When you assign to the jsonSavePath in your constructor, you are just assigning the string value at the time.
Lol, changed jsonSavePath back to a pointer and now the seg fault is back…oh my days, I’ve made a right pigs ear of this!
Are you definitely guarding all the places where widgets might try to access that pointer when there no module?
I think so…but then I’m new to all this so I’ve probably missed something obvious…
#include "plugin.hpp"
#include <iostream>
struct _4hp : Module
{
enum ParamId
{
PARAMS_LEN
};
enum InputId
{
INPUTS_LEN
};
enum OutputId
{
OUTPUTS_LEN
};
enum LightId
{
LIGHTS_LEN
};
_4hp()
{
config(PARAMS_LEN, INPUTS_LEN, OUTPUTS_LEN, LIGHTS_LEN);
}
std::string jsonSavePath; // storage for SVG image file path
// save and load filepath to JSON file
json_t *dataToJson() override
{
json_t *rootJ = json_object();
json_object_set_new(rootJ, "sPATH", json_string(jsonSavePath.c_str()));
return rootJ;
}
void dataFromJson(json_t *rootJ) override
{
json_t *savedPATHJ = json_object_get(rootJ, "sPATH");
jsonSavePath = json_string_value(savedPATHJ);
}
};
struct customPanel : SvgWidget
{
std::string *NEWPATH; // incoming SVG file path
std::string PATH; // current SVG file path
customPanel()
{
setSvg(Svg::load(asset::plugin(pluginInstance, PATH))); // set SVG file on creation of customPanel
}
void draw(const DrawArgs& args) override
{
if(*NEWPATH != PATH) // check if SVG file path has changed
{
setSvg(Svg::load(asset::plugin(pluginInstance, *NEWPATH))); // set new file path
PATH = *NEWPATH; // asign new path to current path variable
}
SvgWidget::draw(args); // continue to run the rest of the default draw function
}
};
struct dnd : TransparentWidget
{
std::string filePath; // path of dropped file
std::string svgPath = asset::plugin(pluginInstance, "res/test.svg"); // path with SVG extension
void onPathDrop(const PathDropEvent &e) override
{
filePath = e.paths.front(); // get first path in array, all other paths are ignored
if(filePath.substr(filePath.find_last_of(".") + 1) == "svg") // check for SVG extension
{
svgPath = filePath; // store path
}
else
{
std::cout << "Invalid file extension: try *.svg" << "\n";
}
}
};
struct _4hpWidget : ModuleWidget
{
_4hpWidget(_4hp *module)
{
setModule(module);
setPanel(createPanel(asset::plugin(pluginInstance, "res/4hp.svg")));
// maunally add widgets to allow for pointer references
dnd *DND = new dnd();
DND->box.pos = Vec(0, 0);
DND->box.size = Vec(RACK_GRID_WIDTH * 4, RACK_GRID_HEIGHT);
addChild(DND);
customPanel *CP = new customPanel();
CP->box.pos = Vec(0, 0);
CP->box.size = Vec(RACK_GRID_WIDTH * 4, RACK_GRID_HEIGHT);
addChild(CP);
// make NEWPATH, svgPath and jsonSavePath point to the same memory location
CP->NEWPATH = &DND->svgPath;
if (module)
{
module->jsonSavePath = *CP->NEWPATH;
}
}
};
Model* model_4hp = createModel<_4hp, _4hpWidget>("4hp");