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.

201 lines
4.4KB

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