Construction/destruction sequence

Looks like the construction / destruction sequence was changed, perhaps with 2.0?

How it used to be:

Construction order: module, widget, dataFromJson, onAdd

Destruction order: dataToJson, onRemove, widget, module

How it is now:

Construction order: [module, dataFromJson, onAdd], [widget]

Destruction order: [dataToJson], [widget, onRemove, module]

(Square brackets suggest grouping of calls, when you have multiple instances. Not sure how that used to be.)

That means you could rely on the fact that in onAdd/onRemove the module and the widget were constructed, had loaded params and were in the engine. Everything was in place, no dangling ends. You could do any further initialization you fancied.

Not so anymore. For instance, output port initialization based on saved states will be overwritten by the engine, if you do it in dataFromJson or onAdd. You have to call back into the module from the widget constructor to do such things. Or initializing custom widgets must now be done the other way around. In one of my modules, there’s data shared between instances, which I used to update in onAdd/onRemove. Haven’t checked yet how that behaves now.

Was there any reason for this change? Can it be reversed? What’s the intended purpose of onAdd/onRemove? They seem pretty much useless now.

You cant rely on the widget ever being created, because rack supports a headless mode. And data to/from json was originally in the widget, then was added to the module. In 2.0 it was deprecated in the widget, as was always the plan. These things are probably some of the reasons for the change

Oh right, headless mode. Thanks for the reminder. Then the initialization for custom widgets should definitely be done in the module widget ctor, which actually makes sense.

Maybe I was too quick judging onAdd, regarding the output port initialization. I’m actually not sure if cables were already connected in earlier versions, but I was under the impression. Now that’s definitely done after onAdd is called. So initalization of output port polyphony / initial voltages has to be done in the first process call.