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.

197 lines
4.3KB

  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. 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. // TODO Find a clean way to make this a variable
  59. #define SAMPLE_RATE 44100
  60. struct Wire;
  61. struct Module {
  62. std::vector<float> params;
  63. // Pointers to voltage values at each port
  64. // If value is NULL, the input/output is disconnected
  65. std::vector<float*> inputs;
  66. std::vector<float*> outputs;
  67. virtual ~Module() {}
  68. // Always called on each sample frame before calling getOutput()
  69. virtual void step() {}
  70. };
  71. struct Wire {
  72. Module *outputModule = NULL;
  73. int outputId;
  74. Module *inputModule = NULL;
  75. int inputId;
  76. // The voltage which is pointed to by module inputs/outputs
  77. float value = 0.0;
  78. };
  79. void rackInit();
  80. void rackDestroy();
  81. void rackStart();
  82. void rackStop();
  83. // Does not transfer ownership
  84. void rackAddModule(Module *module);
  85. void rackRemoveModule(Module *module);
  86. // Does not transfer ownership
  87. void rackConnectWire(Wire *wire);
  88. void rackDisconnectWire(Wire *wire);
  89. void rackSetParamSmooth(Module *module, int paramId, float value);
  90. ////////////////////
  91. // Optional helpers for plugins
  92. ////////////////////
  93. inline
  94. Plugin *createPlugin(std::string slug, std::string name) {
  95. Plugin *plugin = new Plugin();
  96. plugin->slug = slug;
  97. plugin->name = name;
  98. return plugin;
  99. }
  100. template <class TModuleWidget>
  101. Model *createModel(Plugin *plugin, std::string slug, std::string name) {
  102. struct TModel : Model {
  103. ModuleWidget *createModuleWidget() {
  104. ModuleWidget *moduleWidget = new TModuleWidget();
  105. moduleWidget->model = this;
  106. return moduleWidget;
  107. }
  108. };
  109. Model *model = new TModel();
  110. model->plugin = plugin;
  111. model->slug = slug;
  112. model->name = name;
  113. // Create bi-directional association between the Plugin and Model
  114. if (plugin) {
  115. plugin->models.push_back(model);
  116. }
  117. return model;
  118. }
  119. template <class TParam>
  120. ParamWidget *createParam(Vec pos, Module *module, int paramId, float minValue, float maxValue, float defaultValue) {
  121. ParamWidget *param = new TParam();
  122. param->box.pos = pos;
  123. param->module = module;
  124. param->paramId = paramId;
  125. param->setLimits(minValue, maxValue);
  126. param->setDefaultValue(defaultValue);
  127. return param;
  128. }
  129. inline
  130. InputPort *createInput(Vec pos, Module *module, int inputId) {
  131. InputPort *port = new InputPort();
  132. port->box.pos = pos;
  133. port->module = module;
  134. port->inputId = inputId;
  135. return port;
  136. }
  137. inline
  138. OutputPort *createOutput(Vec pos, Module *module, int outputId) {
  139. OutputPort *port = new OutputPort();
  140. port->box.pos = pos;
  141. port->module = module;
  142. port->outputId = outputId;
  143. return port;
  144. }
  145. inline
  146. Screw *createScrew(Vec pos) {
  147. Screw *screw = new Screw();
  148. screw->box.pos = pos;
  149. return screw;
  150. }
  151. } // namespace rack
  152. ////////////////////
  153. // Implemented by plugin
  154. ////////////////////
  155. // Called once to initialize and return Plugin.
  156. // Plugin is destructed when Rack closes
  157. extern "C"
  158. rack::Plugin *init();