Any VCV native event emitter?

I’d like to make some kind of communications between some widgets (i.e. if 1 button got a specific FLAG, do some GUI stuff on some other knobs).

Since I don’t see any kind of communication between widgets, do VCV develop is own event-emitter-style mechanism?

I usually use this on VSTs, which works pretty well. But if there are already somethings I can use in VCV, would be nice to know :slight_smile:

Thanks

For all the plugins I’ve written and read, the module is the common space between widgets. So if you want widget a to change widget b you modify the param bound to b in response to the param change on a in your module ::process

If you want ui to ui changes it’s not hard - you can subclass widgets easily and get the events - but most folks have not done that afaics and I have not had to in my code.

Hope that helps!

That’s exactly what I’d like to avoid, but thanks. I’m looking for a simple propagation-flow pattern.

Not sure what you mean with “subclass and get events”.

Let say I have my CustomButton: once I click on it (i.e. onMouseDown) I set a flag “clicked” on true, and from that time every CustomKnobs need to draw some stuff, until I re click on it (re setting the flag on false).

I don’t want to create an array and get the pointers of each knobs, iterating it later every time I mouse down. Event Emitter is useful for these purposes, but I still need that object on Module class; otherwise, every time I create a Knob/Button, I should pass the EventEmitter reference to it… :frowning:

You don’t have to do that, the app thread does it for you on every frame. Just set the flag in CustomButton and check in step of CustomKnobs if the flag is set. Usually flag is a field of Module.

Don’t follow you! How can I access the CustomKnobs instance without Place It on Array? Or how do I check “flag” from CustomKnob if its part of my own Module? (And not the vcv super class)?

I’m confused: can you show to me a smart example?

The thread that renders your widget of the module traverses all “elements”. The widgets don’t need to know each other, they just need to know their module.

struct MyModule : Module {
  enum ParamIds {
    MY_PARAM,
    NUM_PARAMS
  }

  bool flag
}

struct CustomButton : SvgButton {
  MyModule *module
  
  void onButton(const event::Button &e) override {
    if (e.action == GLFW_PRESS && e.button == GLFW_MOUSE_BUTTON_LEFT) {
      module->flag = true
    }
    SvgButton::onButton(e);
  }
}

struct CustomKnob : SvgKnob {
  MyModule *module

  void step() override {
    if (module->flag) { 
      /* do Something */
    }
    SygKnob::step();
  }
} 

struct MyModuleWidget : ModuleWidget {
  MyModuleWidget(MyModule *module) {
    setModule(module);
    addParam(createParam<CustomKnob>(Vec(0, 0), module, MyModule::MY_PARAM));
  }
}
1 Like

Remember to always call the superclass’s method when overriding methods.

Thanks! I always forget that… edited the example.

Of course… but I need to pass “MyModule” instance on every widget. So every time I addParam, I need to get the instance of the widget being created and pass to it the module pointer. Thats the “Array” part.

Or there is another way which I don’t know?

Yes, there is (added MY_PARAM above):

struct MyModuleWidget : ModuleWidget {
  MyModuleWidget(MyModule *module) {
    setModule(module);
    addParam(createParam<CustomKnob>(Vec(0, 0), module, MyModule::MY_PARAM));
  }
}

I meant exactly the code @stoermelder posted!

Remember module can be null and will be in preview too!

1 Like

Yes! That was not supposed to be working code, just a sketch to give @Nowhk the idea :wink:

1 Like

Uhm? Thats an engine::Module class, not MyModule class :open_mouth: It will be sliced out… won’t access module->flag later (it won’t know about it) :open_mouth:

I edited my post, it wasn’t very clear:

struct MyModuleWidget : ModuleWidget {
  MyModuleWidget(MyModule *module) {
    setModule(module);
    addParam(createParam<CustomKnob>(Vec(0, 0), module, MyModule::MY_PARAM));
  }
}

Dynamic_cast if you want - you will get your class
Make an alternate constructor for your widget which is bound to your class if you prefer and use that instead of createParam
Or inject your own base classes into the hierarchy. So make a ‘MyModuleBase : engine::Module` and then have all your modules inherit that etc… and then static cast safely to that base (with null checks)
Or make a constructor which takes a lambda and bind to the module at construction time

All options which would work. AddParam just takes a ParamWidget* (addChild takes a Widget* if you don’t need param); the createParam constructor is a convenience but you can read the code and use other creation paths if you want.

1 Like

You can also make a common widget base class if you want in your project (which may be what you want I think). So make a ‘MyModuleWidget : ModuleWidget’ and have it have a method like ‘Bus *getBus()’ where ‘Bus *’ is an instance of the communication bus thing you sketched out.

Then for each of your widgets have them implement something like ‘Busable’ interface. So you then write

Struct myWidget : app::WhateverWidget, Busable

Then in your module code you can do

   Auto wid = createParam<MyWidget>(...)
   Wid->addBus(this->getBus())
   AddParam(wid);

You get the idea (sorry for the bad autocorrect - I’m on an ipad). Then you are entirely in widget space, you don’t have to reference module, and you use the parent ModuleWidget as the holder for your inter communication bus. I think that’s the pattern you are looking for.

Like I said, I haven’t seen someone need or use that pattern exactly like that. Most things seem module intermediated. But if you want non-module-intermediated widget converasation I think you will end up with a solution like that (just not in gross pseudocode)

2 Likes

I think it’s convenient to use your module as “bus”, because you want to serialize your fields to json sooner or later.

I agree! Original Poster seems to not want to do that though.

@Nowhk curious why you don’t want to use the module as a communications bus?

Let examine one case as time :slight_smile:

I think you meant static_cast? Since I’ll know the target Module, I can really do this at compile time. But once I created the object, where would you place the cast?

myPlug = static_cast<MyPlug*>(module);

On step()?

Once I call create<>(), it automatically call the CTOR before bind the *module pointer.

It seems I need to do that for every Widget I’d create. But again: every time I create a param, I need to store the reference and than do whatever I want (which is what I’d like to prevent).

i.e. avoid this:

auto wid = createParam<MyWidget>(...)
wid->myPlug = static_cast<MyPlug*>(module);
AddParam(wid);

I’d like to “have it in one line” without create pointer for each param and such :slight_smile:

Once single code in one location: if I have 30 params, it will grown with 30 static cast :pleading_face: