Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Writing a VCV Rack module which uses Grids #155

Open
docb opened this issue Apr 20, 2023 · 4 comments
Open

Feature: Writing a VCV Rack module which uses Grids #155

docb opened this issue Apr 20, 2023 · 4 comments

Comments

@docb
Copy link

docb commented Apr 20, 2023

Use Case: I want to develop a VCV Rack module which can interact with Virtual or Hardware Grids.

I would think that there could be a "lib" which includes the sources in common and lib but without the Firmware stuff, but this is easy to clean up.

The main problem is: The Connection Manager seems to be only visible per plugin. So it would have to be investigated how the Instance of the Connection Manger could be made "global" (see e.g. here).

Or may be using other mechanisms via the Rack API (expander or module API).

Or any other hints to solve?
Thanks.

@Dewb
Copy link
Owner

Dewb commented Apr 20, 2023

Hi! Yes, enabling other package authors to leverage hardware and software grids is definitely a long-term goal and we've had some discussions about it. You have correctly identified the issue with the current state of the grid connection code, I'm afraid.

The answer is probably going to be having the virtual grids register themselves with serialosc through zeroconf. Then we can distribute a serialosc library for other Rack packages to use, which will communicate with hardware and software grids over network ports, avoiding any in-process memory access issues across plugins.

The hope is to tackle that work later this year after the initial package scope is finished and launched in the VCV Library.

@docb
Copy link
Author

docb commented Apr 22, 2023

ok, i have tried something may be hacky which seem to work, however not tested and thought through in detail:

monomegrid

the only way i found to get the GridConnectionManager of the monome plugin is by using an instance pointer which is exported as not mangled symbol.
so in monome:

GridConnectionManager *gridInstance=nullptr;
GridConnectionManager *Instance() {
  if(!gridInstance) gridInstance=new GridConnectionManager();
  return gridInstance;
}

GridConnectionManager& GridConnectionManager::get()
{
    return *Instance();
}

and in my plugin i fetch the symbol of this instance pointer from the plugin->handle of the dynamic lib
(Rack does the same to call the init function of the plugin):

GridConnectionManager& GridConnectionManager::get()
{
  rack::plugin::Plugin *p=rack::plugin::getPlugin("monome");
  void *symbol=(void*)getSymbol(p->handle,"gridInstance");
  void *grid=*(void**)symbol;
  return *(static_cast<GridConnectionManager*>(grid));
}

but this only works if a monome module is loaded first, so some extra mechanisms have to be developed.

@docb
Copy link
Author

docb commented Apr 22, 2023

but this only works if a monome module is loaded first, so some extra mechanisms have to be developed.

when calling GridConnectionManager::get() in the init code of the monome plugin the problem is solved.

@docb
Copy link
Author

docb commented Apr 22, 2023

i forgot to some function, the code of the plugin looks like this:

static inline void* getSymbol(void* handle, const char* name) {
  if (!handle)
    return NULL;

#if defined ARCH_WIN
  return (void*) GetProcAddress((HMODULE) handle, name);
#else
  return dlsym(handle, name);
#endif
}

GridConnectionManager& GridConnectionManager::get()
{
  rack::plugin::Plugin *p=rack::plugin::getPlugin("monome");
  void **symbol=(void**)getSymbol(p->handle,"gridInstance");
  return *(static_cast<GridConnectionManager*>(*symbol));
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants