You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

191 lines
4.0KB

  1. #pragma once
  2. #include <string>
  3. #include <list>
  4. #include <vector>
  5. #include <memory>
  6. #include "widgets.hpp"
  7. namespace rack {
  8. extern Scene *gScene;
  9. extern RackWidget *gRackWidget;
  10. ////////////////////
  11. // Plugin manager
  12. ////////////////////
  13. struct Model;
  14. // Subclass this and return a pointer to a new one when init() is called
  15. struct Plugin {
  16. virtual ~Plugin();
  17. // A unique identifier for your plugin, e.g. "foo"
  18. std::string slug;
  19. // Human readable name for your plugin, e.g. "Foo Modular"
  20. std::string name;
  21. // A list of the models made available by this plugin
  22. std::list<Model*> models;
  23. };
  24. struct Model {
  25. virtual ~Model() {}
  26. Plugin *plugin;
  27. // A unique identifier for the model in this plugin, e.g. "vco"
  28. std::string slug;
  29. // Human readable name for your model, e.g. "VCO"
  30. std::string name;
  31. virtual ModuleWidget *createModuleWidget() { return NULL; }
  32. };
  33. extern std::list<Plugin*> gPlugins;
  34. void pluginInit();
  35. void pluginDestroy();
  36. ////////////////////
  37. // gui.cpp
  38. ////////////////////
  39. extern Vec gMousePos;
  40. extern Widget *gHoveredWidget;
  41. extern Widget *gDraggedWidget;
  42. void guiInit();
  43. void guiDestroy();
  44. void guiRun();
  45. void guiCursorLock();
  46. void guiCursorUnlock();
  47. int loadFont(std::string filename);
  48. int loadImage(std::string filename);
  49. void drawImage(NVGcontext *vg, Vec pos, int imageId);
  50. ////////////////////
  51. // rack.cpp
  52. ////////////////////
  53. // TODO Find a clean way to make this a variable
  54. #define SAMPLE_RATE 44100
  55. struct Wire;
  56. struct Module {
  57. std::vector<float> params;
  58. // Pointers to voltage values at each port
  59. // If value is NULL, the input/output is disconnected
  60. std::vector<float*> inputs;
  61. std::vector<float*> outputs;
  62. virtual ~Module() {}
  63. // Always called on each sample frame before calling getOutput()
  64. virtual void step() {}
  65. };
  66. struct Wire {
  67. Module *outputModule = NULL;
  68. int outputId;
  69. Module *inputModule = NULL;
  70. int inputId;
  71. // The voltage which is pointed to by module inputs/outputs
  72. float value = 0.0;
  73. };
  74. void rackInit();
  75. void rackDestroy();
  76. void rackStart();
  77. void rackStop();
  78. // Does not transfer ownership
  79. void rackAddModule(Module *module);
  80. void rackRemoveModule(Module *module);
  81. // Does not transfer ownership
  82. void rackConnectWire(Wire *wire);
  83. void rackDisconnectWire(Wire *wire);
  84. void rackSetParamSmooth(Module *module, int paramId, float value);
  85. ////////////////////
  86. // Optional helpers for plugins
  87. ////////////////////
  88. inline
  89. Plugin *createPlugin(std::string slug, std::string name) {
  90. Plugin *plugin = new Plugin();
  91. plugin->slug = slug;
  92. plugin->name = name;
  93. return plugin;
  94. }
  95. template <class TModuleWidget>
  96. Model *createModel(Plugin *plugin, std::string slug, std::string name) {
  97. struct TModel : Model {
  98. ModuleWidget *createModuleWidget() {
  99. ModuleWidget *moduleWidget = new TModuleWidget();
  100. moduleWidget->model = this;
  101. return moduleWidget;
  102. }
  103. };
  104. Model *model = new TModel();
  105. model->plugin = plugin;
  106. model->slug = slug;
  107. model->name = name;
  108. // Create bi-directional association between the Plugin and Model
  109. if (plugin) {
  110. plugin->models.push_back(model);
  111. }
  112. return model;
  113. }
  114. template <class TParam>
  115. ParamWidget *createParam(Vec pos, Module *module, int paramId, float minValue, float maxValue, float defaultValue) {
  116. ParamWidget *param = new TParam();
  117. param->box.pos = pos;
  118. param->module = module;
  119. param->paramId = paramId;
  120. param->setLimits(minValue, maxValue);
  121. param->setDefaultValue(defaultValue);
  122. return param;
  123. }
  124. inline
  125. InputPort *createInput(Vec pos, Module *module, int inputId) {
  126. InputPort *port = new InputPort();
  127. port->box.pos = pos;
  128. port->module = module;
  129. port->inputId = inputId;
  130. return port;
  131. }
  132. inline
  133. OutputPort *createOutput(Vec pos, Module *module, int outputId) {
  134. OutputPort *port = new OutputPort();
  135. port->box.pos = pos;
  136. port->module = module;
  137. port->outputId = outputId;
  138. return port;
  139. }
  140. inline
  141. Screw *createScrew(Vec pos) {
  142. Screw *screw = new Screw();
  143. screw->box.pos = pos;
  144. return screw;
  145. }
  146. } // namespace rack
  147. ////////////////////
  148. // Implemented by plugin
  149. ////////////////////
  150. // Called once to initialize and return Plugin.
  151. // Plugin is destructed when Rack closes
  152. extern "C"
  153. rack::Plugin *init();