Separation of user data in Module and Widget in V2

In V1 I could use fromJson() and toJson() inside the Widget to load/save user data that do not have anything to do with audio processing, e.g. a string displayed on the GUI or the color of the GUI.

Now in V2 I have to use dataFromJson() and dataToJson() inside the Module to load/save this data.

If this data is a number and/or can be packed into a numeric Param, now I add a Param to the module. As a new side effect, this kind of GUI data can now be controlled by Modules like Stoermelder Macro. Is there a way to prevent this?

If this data is a string and/or can’t be packed into a numeric Param, now I use dataFromJson() and dataToJson().

But what I’m worrying about is the lost of logical separation of Module’s data and Widget’s data, because now in my Module I have data that only makes sense for the widget.

I think this is just the way it is.

If you don’t want some of your values to act like a param, then don’t make them be params.

It is not uncommon (to me anyway) for the widget and the module to share data. Your case sounds easier than some, and the only communication needed is for some serialized values.

Still you need to be aware that the two will be running on different threads, and you many need to do something to guarantee that there are no bugs arising from that.

Don’t use Params for storing internal data for your Module or ModuleWidget. Params are for knobs, switches, buttons, and float values that users should be able to directly control. Use a Module member variable for internal data.

This is best. What if your Module is loaded headless and then re-serializes? If you persist data in ModuleWidget, then that data is lost. Module should store all data that you want to persist. If you’re familiar with the MVC pattern, Module is the model while ModuleWidget is the view/controller.

3 Likes

I still struggling with this issue, maybe I’m thinking to complicate or something…

I used the old json methods in ModuleWidget to store/reload data on creating and changing the widget, it worked without any issues. Now I try to shift this functionality to the module, but I can’t find any proper entry point in the module widget where the json is loaded and I have random crashes do it via the Module’s methods. (Maybe because of the separated threads)

So my question: What is the standard way to store and load properties for a ModuleWidget? For example I provide the option to show the module in a ‘used’ look, this could be put on via a menu entry entry and have to be saved and reloaded on creating the module.

Thanks in advance, Patrick.

Do you want to store plugin-wide settings? I’d use global variables in your plugin.hpp file, a settingsSave() function that is called after changing a setting, and settingsLoad() that is called in init().

1 Like

When Andrew originally deprecated the moduleWidget methods in v1, I made an effort to move all my widget specific settings to the module. I added member variables to the module and then the widget reads and writes those as it needs to. (Taking care to check that there really is a module).

For an example you can look at the core blanking plate in VCVRack and compare between v1 and v2. It used to save the width using ModuleWidget methods, and in v2 it uses Module methods.

For the global color scheme settings in the SubmarineFree modules; any moduleWidget which changes that setting calls a function in a function within my dll, which sets global values for setting that all the moduleWidgets can look at.

3 Likes

No, I mean a setting for a concrete instance of a module in a patch.

Thanks, I will take a look. I think I will move the config to the module, I will thing about how this can be done elegant. :slight_smile:

For module-local storage, use a member variable in your Module subclass.

Yeah, I do the same thing. But you really, really must remember that they are on different threads, so “sharing variables” isn’t trivial. If you want it to work. And you can’t use a mutex, of you will get dropouts.

1 Like

For panel color settings for example, the audio thread never needs to access them, so you don’t need to worry about synchronization.

Oh, cool. So the json deserialize in the module is run on the widget thread? Or is it already in the module at the time the widget is created?