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.

217 lines
4.6KB

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