VCV Rack has crashed on module browser

In MeanderWidget() constructor, I moved all object creation inside of an “if (module) {}” bracketing and my step() function no longer crashes on module browse.

I see what you mean. In the past the browser thumbnail had a valid fully rendered image of the module and I always wondered how it did that. So now that the module checks are in place, obviously the proceedurally generated or modified panel content is not available without a module.

I will look at caching some of this for use when there is no module. Actually, I think I already have it cached.

Ok, like I said earlier, one of the widget or component you are creating in the constructor is probably interfering with module at some point and causing the crash :wink:

Exactly. It will no more:)

I hope this will be my last question on this topic, but I think it is important. In Meander, I am creating params inside of the MeanderWidget() constructor using CreateParam(). CreateParam() requires a module argument, so when the browser instantiated a widget without a module, things were getting messed up.

I think this goes back to our discussion in the past couple of weeks about widgets needing to be completely “stateless”, so that in v2 a headless (widgetless) module can instantiate. Does this mean that I should move all CreateParam() calls to the module constructor rather than being in the widget constructor? Likewise, do I need to move use of these params from the Widget::step() to the module step (or process)?

Thanks for your patience with me.

CreateParam() should go in the ModuleWidget constructor, and yes it requires a module argument, but it’s only use to “link” the parameter to your module, and as it is designed it shouldn’t cause any crash.

Can you explain in detail what you are doing there ?

I think the name createParam is a bit misleading: the parameters are defined with the ParamIds enum in Module. createParam creates a ParamWidget for an existing parameter in the module, so: no, don’t move these calls to the module constructor.

Can you explain in detail what you are doing there ?

What I am doing is probably not the best way of doing things, but since my existing Meander for Windows code was so complex, it was difficult to just drop it into the right places in the Rack module. I tried looking at others’ source code to determine best practices, but, I surely did not get everything done in the best way possible, even if it worked, until it didn’t.

Basically I have been using MeanderWidget::step() to procedurally rearrange controls that were created in the MeanderWidget() constructor to align better on the panel than what was in the SVG file, particularly since I am not doing all of my panel design in Inkscape any longer, but doing it procedurally. I had the code in step() executing each time step() was called, which was unnecessary. Now I just do it once at startup if the module is not null. I remember putting this procedural code in step() because I was having trouble putting it somewhere in the MeanderWidget() constructor. I think I was thinking that this positional data was going to change during execution so needed to be updated per frame. But, I ended up putting such dynamic updates in draw() functions within a TransparentWidget panel drawing widget.

MeanderWidget is the ModuleWidget, so sounds like it is okay for CreateParam() calls in the Meanderwidget() constructor. Right now I am only doing the CreatParam() if the module is non-null and that seems to have eliminated the crashes.

I moved the control param realignment code from step() back to MeanderWidget() constructor and that is working fine.

That works better because the module browser thumbnail has my procedural panel updates showing.

As I better understand the plugin architecture better now than when I started developing Meander a couple of months ago, and better than yesterday, I did a major reorganization of the Meander module towards two ends:

  • All computational code is done within the Module, in the process() function with a dsp::ClockDivider set to a 512 division factor, so I do not try to use draw() or step() for frame rate updates. No GUI is done from the Module.
  • All GUI is done by the ModuleWidget and no computational work is done by the Widget, except perhaps control repositioning in step(). In particular, no computation is occurring in draw(), other than GUI computations.

Hopefully my module will be better behaved as a result of this, as well as be ready for v2 headless execution.

Thanks to several of you for helping me understand the architecture and best practices better. If I am still on the wrong path, please tell me so:wink:

2 Likes

Looks good to me!