Browse Source

Add Context class for storing global state

tags/v1.0.0
Andrew Belt 5 years ago
parent
commit
402f42a354
36 changed files with 213 additions and 163 deletions
  1. +0
    -4
      include/app/Scene.hpp
  2. +1
    -1
      include/asset.hpp
  3. +28
    -0
      include/context.hpp
  4. +0
    -4
      include/engine/Engine.hpp
  5. +0
    -4
      include/event.hpp
  6. +2
    -1
      include/helpers.hpp
  7. +1
    -1
      include/logger.hpp
  8. +1
    -1
      include/plugin/PluginManager.hpp
  9. +1
    -0
      include/rack.hpp
  10. +2
    -1
      include/ui/MenuItem.hpp
  11. +2
    -1
      include/ui/ScrollWidget.hpp
  12. +4
    -3
      include/ui/TextField.hpp
  13. +2
    -1
      src/Core/AudioInterface.cpp
  14. +4
    -3
      src/Core/Blank.cpp
  15. +5
    -5
      src/Core/MIDICCToCVInterface.cpp
  16. +1
    -1
      src/Core/MIDIToCVInterface.cpp
  17. +3
    -3
      src/Core/MIDITriggerToCVInterface.cpp
  18. +2
    -1
      src/app/LedDisplay.cpp
  19. +6
    -5
      src/app/ModuleBrowser.cpp
  20. +17
    -15
      src/app/ModuleWidget.cpp
  21. +10
    -9
      src/app/Port.cpp
  22. +2
    -1
      src/app/RackScrollWidget.cpp
  23. +2
    -1
      src/app/RackWidget.cpp
  24. +2
    -4
      src/app/Scene.cpp
  25. +18
    -17
      src/app/Toolbar.cpp
  26. +11
    -10
      src/app/WireWidget.cpp
  27. +6
    -3
      src/asset.cpp
  28. +15
    -0
      src/context.cpp
  29. +0
    -3
      src/engine/Engine.cpp
  30. +2
    -1
      src/engine/Light.cpp
  31. +3
    -2
      src/logger.cpp
  32. +26
    -27
      src/main.cpp
  33. +3
    -2
      src/plugin/PluginManager.cpp
  34. +15
    -14
      src/settings.cpp
  35. +2
    -1
      src/widgets/Widget.cpp
  36. +14
    -13
      src/window.cpp

+ 0
- 4
include/app/Scene.hpp View File

@@ -18,7 +18,6 @@ struct Scene : OpaqueWidget {
RackWidget *rackWidget;
Toolbar *toolbar;

bool devMode = false;
// Version checking
bool checkVersion = true;
bool checkedVersion = false;
@@ -34,7 +33,4 @@ struct Scene : OpaqueWidget {
};


extern Scene *gScene;


} // namespace rack

+ 1
- 1
include/asset.hpp View File

@@ -7,7 +7,7 @@ namespace rack {
namespace asset {


void init(bool devMode);
void init();
/** Returns the path of a system resource. Should only read files from this location. */
std::string system(std::string filename);
/** Returns the path of a user resource. Can read and write files to this location. */


+ 28
- 0
include/context.hpp View File

@@ -0,0 +1,28 @@
#pragma once
#include "common.hpp"


namespace rack {


struct Scene;
struct Engine;

namespace event {
struct Context;
}


struct Context {
bool devMode = false;

event::Context *event = NULL;
Scene *scene = NULL;
Engine *engine = NULL;
};


Context *context();


} // namespace rack

+ 0
- 4
include/engine/Engine.hpp View File

@@ -44,8 +44,4 @@ struct Engine {
};


// TODO Move to global state header
extern Engine *gEngine;


} // namespace rack

+ 0
- 4
include/event.hpp View File

@@ -230,9 +230,5 @@ struct Context {
};


// TODO Move this into a global context class
extern Context *gContext;


} // namespace event
} // namespace rack

+ 2
- 1
include/helpers.hpp View File

@@ -5,6 +5,7 @@
#include "ui/Menu.hpp"
#include "app/Port.hpp"
#include "engine/Module.hpp"
#include "context.hpp"


namespace rack {
@@ -148,7 +149,7 @@ inline Menu *createMenu() {
MenuOverlay *menuOverlay = new MenuOverlay;
menuOverlay->addChild(o);

event::gContext->rootWidget->addChild(menuOverlay);
context()->event->rootWidget->addChild(menuOverlay);
return o;
}



+ 1
- 1
include/logger.hpp View File

@@ -24,7 +24,7 @@ enum Level {
FATAL_LEVEL
};

void init(bool devMode);
void init();
void destroy();
/** Do not use this function directly. Use the macros below. */
void log(Level level, const char *filename, int line, const char *format, ...);


+ 1
- 1
include/plugin/PluginManager.hpp View File

@@ -17,7 +17,7 @@ struct PluginManager {
std::string downloadName;
std::string loginStatus;

PluginManager(bool devMode);
PluginManager();
~PluginManager();
void logIn(std::string email, std::string password);
void logOut();


+ 1
- 0
include/rack.hpp View File

@@ -9,6 +9,7 @@
#include "network.hpp"
#include "asset.hpp"
#include "window.hpp"
#include "context.hpp"
#include "helpers.hpp"

#include "widgets/Widget.hpp"


+ 2
- 1
include/ui/MenuItem.hpp View File

@@ -3,6 +3,7 @@
#include "ui/Menu.hpp"
#include "ui/MenuEntry.hpp"
#include "ui/MenuOverlay.hpp"
#include "context.hpp"


namespace rack {
@@ -17,7 +18,7 @@ struct MenuItem : MenuEntry {

void draw(NVGcontext *vg) override {
// Get state
BNDwidgetState state = (event::gContext->hoveredWidget == this) ? BND_HOVER : BND_DEFAULT;
BNDwidgetState state = (context()->event->hoveredWidget == this) ? BND_HOVER : BND_DEFAULT;
Menu *parentMenu = dynamic_cast<Menu*>(parent);
if (parentMenu && parentMenu->activeEntry == this) {
state = BND_ACTIVE;


+ 2
- 1
include/ui/ScrollWidget.hpp View File

@@ -2,6 +2,7 @@
#include "widgets/OpaqueWidget.hpp"
#include "ui/common.hpp"
#include "event.hpp"
#include "context.hpp"


namespace rack {
@@ -111,7 +112,7 @@ struct ScrollWidget : OpaqueWidget {

void onHover(event::Hover &e) override {
// Scroll with arrow keys
if (!event::gContext->selectedWidget) {
if (!context()->event->selectedWidget) {
float arrowSpeed = 30.0;
if (windowIsShiftPressed() && windowIsModPressed())
arrowSpeed /= 16.0;


+ 4
- 3
include/ui/TextField.hpp View File

@@ -2,6 +2,7 @@
#include "widgets/OpaqueWidget.hpp"
#include "ui/common.hpp"
#include "event.hpp"
#include "context.hpp"


namespace rack {
@@ -26,9 +27,9 @@ struct TextField : OpaqueWidget {
nvgScissor(vg, 0, 0, box.size.x, box.size.y);

BNDwidgetState state;
if (this == event::gContext->selectedWidget)
if (this == context()->event->selectedWidget)
state = BND_ACTIVE;
else if (this == event::gContext->hoveredWidget)
else if (this == context()->event->hoveredWidget)
state = BND_HOVER;
else
state = BND_DEFAULT;
@@ -52,7 +53,7 @@ struct TextField : OpaqueWidget {
}

void onHover(event::Hover &e) override {
if (this == event::gContext->draggedWidget) {
if (this == context()->event->draggedWidget) {
int pos = getTextPosition(e.pos);
if (pos != selection) {
cursor = pos;


+ 2
- 1
src/Core/AudioInterface.cpp View File

@@ -7,6 +7,7 @@
#include <thread>
#include <mutex>
#include <condition_variable>
#include "context.hpp"


#define AUDIO_OUTPUTS 8
@@ -144,7 +145,7 @@ struct AudioInterface : Module {

void AudioInterface::step() {
// Update SRC states
int sampleRate = (int) gEngine->getSampleRate();
int sampleRate = (int) context()->engine->getSampleRate();
inputSrc.setRates(audioIO.sampleRate, sampleRate);
outputSrc.setRates(sampleRate, audioIO.sampleRate);



+ 4
- 3
src/Core/Blank.cpp View File

@@ -1,4 +1,5 @@
#include "Core.hpp"
#include "context.hpp"

using namespace rack;

@@ -17,14 +18,14 @@ struct ModuleResizeHandle : virtual Widget {
// }
}
void onDragStart(event::DragStart &e) override {
dragX = gScene->rackWidget->lastMousePos.x;
dragX = context()->scene->rackWidget->lastMousePos.x;
ModuleWidget *m = getAncestorOfType<ModuleWidget>();
originalBox = m->box;
}
void onDragMove(event::DragMove &e) override {
ModuleWidget *m = getAncestorOfType<ModuleWidget>();

float newDragX = gScene->rackWidget->lastMousePos.x;
float newDragX = context()->scene->rackWidget->lastMousePos.x;
float deltaX = newDragX - dragX;

Rect newBox = originalBox;
@@ -40,7 +41,7 @@ struct ModuleResizeHandle : virtual Widget {
newBox.size.x = roundf(newBox.size.x / RACK_GRID_WIDTH) * RACK_GRID_WIDTH;
newBox.pos.x = originalBox.pos.x + originalBox.size.x - newBox.size.x;
}
gScene->rackWidget->requestModuleBox(m, newBox);
context()->scene->rackWidget->requestModuleBox(m, newBox);
}
void draw(NVGcontext *vg) override {
for (float x = 5.0; x <= 10.0; x += 5.0) {


+ 5
- 5
src/Core/MIDICCToCVInterface.cpp View File

@@ -46,7 +46,7 @@ struct MIDICCToCVInterface : Module {
processMessage(msg);
}

float lambda = 100.f * gEngine->getSampleTime();
float lambda = 100.f * context()->engine->getSampleTime();
for (int i = 0; i < 16; i++) {
int learnedCc = learnedCcs[i];
float value = rescale(clamp(ccs[learnedCc], -127, 127), 0, 127, 0.f, 10.f);
@@ -129,8 +129,8 @@ struct MidiCcChoice : GridChoice {
else {
text = string::f("%d", module->learnedCcs[id]);
color.a = 1.0;
if (event::gContext->selectedWidget == this)
event::gContext->selectedWidget = NULL;
if (context()->event->selectedWidget == this)
context()->event->selectedWidget = NULL;
}
}

@@ -158,11 +158,11 @@ struct MidiCcChoice : GridChoice {
}

void onSelectKey(event::SelectKey &e) override {
if (event::gContext->selectedWidget == this) {
if (context()->event->selectedWidget == this) {
if (e.key == GLFW_KEY_ENTER || e.key == GLFW_KEY_KP_ENTER) {
event::Deselect eDeselect;
onDeselect(eDeselect);
event::gContext->selectedWidget = NULL;
context()->event->selectedWidget = NULL;
e.target = this;
}
}


+ 1
- 1
src/Core/MIDIToCVInterface.cpp View File

@@ -146,7 +146,7 @@ struct MIDIToCVInterface : Module {
while (midiInput.shift(&msg)) {
processMessage(msg);
}
float deltaTime = gEngine->getSampleTime();
float deltaTime = context()->engine->getSampleTime();

outputs[CV_OUTPUT].value = (lastNote - 60) / 12.f;
outputs[GATE_OUTPUT].value = gate ? 10.f : 0.f;


+ 3
- 3
src/Core/MIDITriggerToCVInterface.cpp View File

@@ -71,7 +71,7 @@ struct MIDITriggerToCVInterface : Module {
while (midiInput.shift(&msg)) {
processMessage(msg);
}
float deltaTime = gEngine->getSampleTime();
float deltaTime = context()->engine->getSampleTime();

for (int i = 0; i < 16; i++) {
if (gateTimes[i] > 0.f) {
@@ -173,8 +173,8 @@ struct MidiTrigChoice : GridChoice {
text = string::f("%s%d", noteNames[semi], oct);
color.a = 1.0;

if (event::gContext->selectedWidget == this)
event::gContext->selectedWidget = NULL;
if (context()->event->selectedWidget == this)
context()->event->selectedWidget = NULL;
}
}



+ 2
- 1
src/app/LedDisplay.cpp View File

@@ -2,6 +2,7 @@
#include "asset.hpp"
#include "window.hpp"
#include "event.hpp"
#include "context.hpp"


namespace rack {
@@ -85,7 +86,7 @@ void LedDisplayTextField::draw(NVGcontext *vg) {
NVGcolor highlightColor = color;
highlightColor.a = 0.5;
int begin = std::min(cursor, selection);
int end = (this == event::gContext->selectedWidget) ? std::max(cursor, selection) : -1;
int end = (this == context()->event->selectedWidget) ? std::max(cursor, selection) : -1;
bndIconLabelCaret(vg, textOffset.x, textOffset.y,
box.size.x - 2*textOffset.x, box.size.y - 2*textOffset.y,
-1, color, 12, text.c_str(), highlightColor, begin, end);


+ 6
- 5
src/app/ModuleBrowser.cpp View File

@@ -11,6 +11,7 @@
#include "ui/List.hpp"
#include "ui/TextField.hpp"
#include "plugin/PluginManager.hpp"
#include "context.hpp"


static const float itemMargin = 2.0;
@@ -157,10 +158,10 @@ struct ModelItem : BrowserListItem {
ModuleWidget *moduleWidget = model->createModuleWidget();
if (!moduleWidget)
return;
gScene->rackWidget->addModule(moduleWidget);
context()->scene->rackWidget->addModule(moduleWidget);
// Move module nearest to the mouse position
moduleWidget->box.pos = gScene->rackWidget->lastMousePos.minus(moduleWidget->box.size.div(2));
gScene->rackWidget->requestModuleBoxNearest(moduleWidget, moduleWidget->box);
moduleWidget->box.pos = context()->scene->rackWidget->lastMousePos.minus(moduleWidget->box.size.div(2));
context()->scene->rackWidget->requestModuleBoxNearest(moduleWidget, moduleWidget->box);
}
};

@@ -446,7 +447,7 @@ struct ModuleBrowser : OpaqueWidget {
moduleScroll->box.size.y = std::min(box.size.y - moduleScroll->box.pos.y, moduleList->box.size.y);
box.size.y = std::min(box.size.y, moduleScroll->box.getBottomRight().y);

event::gContext->selectedWidget = searchField;
context()->event->selectedWidget = searchField;
Widget::step();
}
};
@@ -557,7 +558,7 @@ void moduleBrowserCreate() {
ModuleBrowser *moduleBrowser = new ModuleBrowser;
overlay->addChild(moduleBrowser);

gScene->addChild(overlay);
context()->scene->addChild(overlay);
}

json_t *moduleBrowserToJson() {


+ 17
- 15
src/app/ModuleWidget.cpp View File

@@ -5,6 +5,8 @@
#include "asset.hpp"
#include "app/Scene.hpp"
#include "helpers.hpp"
#include "context.hpp"

#include "osdialog.h"


@@ -13,7 +15,7 @@ namespace rack {

ModuleWidget::ModuleWidget(Module *module) {
if (module) {
gEngine->addModule(module);
context()->engine->addModule(module);
}
this->module = module;
}
@@ -23,7 +25,7 @@ ModuleWidget::~ModuleWidget() {
disconnect();
// Remove and delete the Module instance
if (module) {
gEngine->removeModule(module);
context()->engine->removeModule(module);
delete module;
module = NULL;
}
@@ -217,10 +219,10 @@ void ModuleWidget::saveDialog() {

void ModuleWidget::disconnect() {
for (Port *input : inputs) {
gScene->rackWidget->wireContainer->removeAllWires(input);
context()->scene->rackWidget->wireContainer->removeAllWires(input);
}
for (Port *output : outputs) {
gScene->rackWidget->wireContainer->removeAllWires(output);
context()->scene->rackWidget->wireContainer->removeAllWires(output);
}
}

@@ -235,7 +237,7 @@ void ModuleWidget::reset() {
param->reset();
}
if (module) {
gEngine->resetModule(module);
context()->engine->resetModule(module);
}
}

@@ -244,7 +246,7 @@ void ModuleWidget::randomize() {
param->randomize();
}
if (module) {
gEngine->randomizeModule(module);
context()->engine->randomizeModule(module);
}
}

@@ -253,7 +255,7 @@ void ModuleWidget::draw(NVGcontext *vg) {
Widget::draw(vg);

// Power meter
if (module && gEngine->powerMeter) {
if (module && context()->engine->powerMeter) {
nvgBeginPath(vg);
nvgRect(vg,
0, box.size.y - 20,
@@ -297,7 +299,7 @@ void ModuleWidget::onHover(event::Hover &e) {
// Instead of checking key-down events, delete the module even if key-repeat hasn't fired yet and the cursor is hovering over the widget.
if (glfwGetKey(gWindow, GLFW_KEY_DELETE) == GLFW_PRESS || glfwGetKey(gWindow, GLFW_KEY_BACKSPACE) == GLFW_PRESS) {
if (!windowIsModPressed() && !windowIsShiftPressed()) {
gScene->rackWidget->deleteModule(this);
context()->scene->rackWidget->deleteModule(this);
delete this;
// e.target = this;
return;
@@ -346,7 +348,7 @@ void ModuleWidget::onHoverKey(event::HoverKey &e) {
} break;
case GLFW_KEY_D: {
if (windowIsModPressed() && !windowIsShiftPressed()) {
gScene->rackWidget->cloneModule(this);
context()->scene->rackWidget->cloneModule(this);
e.target = this;
return;
}
@@ -364,17 +366,17 @@ void ModuleWidget::onHoverKey(event::HoverKey &e) {
}

void ModuleWidget::onDragStart(event::DragStart &e) {
dragPos = gScene->rackWidget->lastMousePos.minus(box.pos);
dragPos = context()->scene->rackWidget->lastMousePos.minus(box.pos);
}

void ModuleWidget::onDragEnd(event::DragEnd &e) {
}

void ModuleWidget::onDragMove(event::DragMove &e) {
if (!gScene->rackWidget->lockModules) {
if (!context()->scene->rackWidget->lockModules) {
Rect newBox = box;
newBox.pos = gScene->rackWidget->lastMousePos.minus(dragPos);
gScene->rackWidget->requestModuleBoxNearest(this, newBox);
newBox.pos = context()->scene->rackWidget->lastMousePos.minus(dragPos);
context()->scene->rackWidget->requestModuleBoxNearest(this, newBox);
}
}

@@ -431,14 +433,14 @@ struct ModuleLoadItem : MenuItem {
struct ModuleCloneItem : MenuItem {
ModuleWidget *moduleWidget;
void onAction(event::Action &e) override {
gScene->rackWidget->cloneModule(moduleWidget);
context()->scene->rackWidget->cloneModule(moduleWidget);
}
};

struct ModuleDeleteItem : MenuItem {
ModuleWidget *moduleWidget;
void onAction(event::Action &e) override {
gScene->rackWidget->deleteModule(moduleWidget);
context()->scene->rackWidget->deleteModule(moduleWidget);
delete moduleWidget;
}
};


+ 10
- 9
src/app/Port.cpp View File

@@ -1,6 +1,7 @@
#include "app/Port.hpp"
#include "app/Scene.hpp"
#include "window.hpp"
#include "context.hpp"
#include "componentlibrary.hpp"


@@ -24,7 +25,7 @@ Port::Port() {
Port::~Port() {
// plugLight is not a child and is thus owned by the Port, so we need to delete it here
delete plugLight;
gScene->rackWidget->wireContainer->removeAllWires(this);
context()->scene->rackWidget->wireContainer->removeAllWires(this);
}

void Port::step() {
@@ -41,7 +42,7 @@ void Port::step() {
}

void Port::draw(NVGcontext *vg) {
WireWidget *activeWire = gScene->rackWidget->wireContainer->activeWire;
WireWidget *activeWire = context()->scene->rackWidget->wireContainer->activeWire;
if (activeWire) {
// Dim the Port if the active wire cannot plug into this Port
if (type == INPUT ? activeWire->inputPort : activeWire->outputPort)
@@ -51,7 +52,7 @@ void Port::draw(NVGcontext *vg) {

void Port::onButton(event::Button &e) {
if (e.action == GLFW_PRESS && e.button == GLFW_MOUSE_BUTTON_LEFT) {
gScene->rackWidget->wireContainer->removeTopWire(this);
context()->scene->rackWidget->wireContainer->removeTopWire(this);

// HACK
// Update hovered*Port of active wire if applicable
@@ -63,7 +64,7 @@ void Port::onButton(event::Button &e) {

void Port::onDragStart(event::DragStart &e) {
// Try to grab wire on top of stack
WireWidget *wire = gScene->rackWidget->wireContainer->getTopWire(this);
WireWidget *wire = context()->scene->rackWidget->wireContainer->getTopWire(this);
if (type == OUTPUT && windowIsModPressed()) {
wire = NULL;
}
@@ -84,13 +85,13 @@ void Port::onDragStart(event::DragStart &e) {
else
wire->outputPort = this;
}
gScene->rackWidget->wireContainer->setActiveWire(wire);
context()->scene->rackWidget->wireContainer->setActiveWire(wire);
}

void Port::onDragEnd(event::DragEnd &e) {
// FIXME
// If the source Port is deleted, this will be called, removing the cable
gScene->rackWidget->wireContainer->commitActiveWire();
context()->scene->rackWidget->wireContainer->commitActiveWire();
}

void Port::onDragDrop(event::DragDrop &e) {
@@ -99,12 +100,12 @@ void Port::onDragDrop(event::DragDrop &e) {
void Port::onDragEnter(event::DragEnter &e) {
// Reject ports if this is an input port and something is already plugged into it
if (type == INPUT) {
WireWidget *topWire = gScene->rackWidget->wireContainer->getTopWire(this);
WireWidget *topWire = context()->scene->rackWidget->wireContainer->getTopWire(this);
if (topWire)
return;
}

WireWidget *activeWire = gScene->rackWidget->wireContainer->activeWire;
WireWidget *activeWire = context()->scene->rackWidget->wireContainer->activeWire;
if (activeWire) {
if (type == INPUT)
activeWire->hoveredInputPort = this;
@@ -114,7 +115,7 @@ void Port::onDragEnter(event::DragEnter &e) {
}

void Port::onDragLeave(event::DragLeave &e) {
WireWidget *activeWire = gScene->rackWidget->wireContainer->activeWire;
WireWidget *activeWire = context()->scene->rackWidget->wireContainer->activeWire;
if (activeWire) {
if (type == INPUT)
activeWire->hoveredInputPort = NULL;


+ 2
- 1
src/app/RackScrollWidget.cpp View File

@@ -1,6 +1,7 @@
#include "app/RackScrollWidget.hpp"
#include "app/Scene.hpp"
#include "window.hpp"
#include "context.hpp"


namespace rack {
@@ -10,7 +11,7 @@ void RackScrollWidget::step() {
Vec pos = gMousePos;
Rect viewport = getViewport(box.zeroPos());
// Scroll rack if dragging cable near the edge of the screen
if (gScene->rackWidget->wireContainer->activeWire) {
if (context()->scene->rackWidget->wireContainer->activeWire) {
float margin = 20.0;
float speed = 15.0;
if (pos.x <= viewport.pos.x + margin)


+ 2
- 1
src/app/RackWidget.cpp View File

@@ -10,6 +10,7 @@
#include "system.hpp"
#include "logger.hpp"
#include "plugin/PluginManager.hpp"
#include "context.hpp"


namespace rack {
@@ -59,7 +60,7 @@ void RackWidget::clear() {
wireContainer->clearChildren();
moduleContainer->clearChildren();

gScene->scrollWidget->offset = Vec(0, 0);
context()->scene->scrollWidget->offset = Vec(0, 0);
}

void RackWidget::reset() {


+ 2
- 4
src/app/Scene.cpp View File

@@ -4,6 +4,7 @@
#include "app/Scene.hpp"
#include "app/ModuleBrowser.hpp"
#include "app/RackScrollWidget.hpp"
#include "context.hpp"
#include <thread>


@@ -43,7 +44,7 @@ void Scene::step() {
zoomWidget->box.size = rackWidget->box.size.mult(zoomWidget->zoom);

// Request latest version from server
if (!devMode && checkVersion && !checkedVersion) {
if (!context()->devMode && checkVersion && !checkedVersion) {
std::thread t(&Scene::runCheckVersion, this);
t.detach();
checkedVersion = true;
@@ -149,7 +150,4 @@ void Scene::runCheckVersion() {
}


Scene *gScene = NULL;


} // namespace rack

+ 18
- 17
src/app/Toolbar.cpp View File

@@ -8,6 +8,7 @@
#include "ui/Slider.hpp"
#include "app/PluginManagerWidget.hpp"
#include "app/Scene.hpp"
#include "context.hpp"
#include "helpers.hpp"


@@ -21,13 +22,13 @@ struct TooltipIconButton : IconButton {
tooltip = new Tooltip;
tooltip->box.pos = getAbsoluteOffset(Vec(0, BND_WIDGET_HEIGHT));
tooltip->text = getTooltipText();
gScene->addChild(tooltip);
context()->scene->addChild(tooltip);
}
IconButton::onEnter(e);
}
void onLeave(event::Leave &e) override {
if (tooltip) {
gScene->removeChild(tooltip);
context()->scene->removeChild(tooltip);
delete tooltip;
tooltip = NULL;
}
@@ -42,7 +43,7 @@ struct NewButton : TooltipIconButton {
}
std::string getTooltipText() override {return "New patch (" WINDOW_MOD_KEY_NAME "+N)";}
void onAction(event::Action &e) override {
gScene->rackWidget->reset();
context()->scene->rackWidget->reset();
}
};

@@ -52,7 +53,7 @@ struct OpenButton : TooltipIconButton {
}
std::string getTooltipText() override {return "Open patch (" WINDOW_MOD_KEY_NAME "+O)";}
void onAction(event::Action &e) override {
gScene->rackWidget->loadDialog();
context()->scene->rackWidget->loadDialog();
}
};

@@ -62,7 +63,7 @@ struct SaveButton : TooltipIconButton {
}
std::string getTooltipText() override {return "Save patch (" WINDOW_MOD_KEY_NAME "+S)";}
void onAction(event::Action &e) override {
gScene->rackWidget->saveDialog();
context()->scene->rackWidget->saveDialog();
}
};

@@ -72,7 +73,7 @@ struct SaveAsButton : TooltipIconButton {
}
std::string getTooltipText() override {return "Save patch as (" WINDOW_MOD_KEY_NAME "+Shift+S)";}
void onAction(event::Action &e) override {
gScene->rackWidget->saveAsDialog();
context()->scene->rackWidget->saveAsDialog();
}
};

@@ -82,7 +83,7 @@ struct RevertButton : TooltipIconButton {
}
std::string getTooltipText() override {return "Revert patch";}
void onAction(event::Action &e) override {
gScene->rackWidget->revert();
context()->scene->rackWidget->revert();
}
};

@@ -92,7 +93,7 @@ struct DisconnectCablesButton : TooltipIconButton {
}
std::string getTooltipText() override {return "Disconnect cables";}
void onAction(event::Action &e) override {
gScene->rackWidget->disconnect();
context()->scene->rackWidget->disconnect();
}
};

@@ -102,21 +103,21 @@ struct PowerMeterButton : TooltipIconButton {
}
std::string getTooltipText() override {return "Toggle power meter (see manual for explanation)";}
void onAction(event::Action &e) override {
gEngine->powerMeter ^= true;
context()->engine->powerMeter ^= true;
}
};

struct EnginePauseItem : MenuItem {
void onAction(event::Action &e) override {
gEngine->paused ^= true;
context()->engine->paused ^= true;
}
};

struct SampleRateItem : MenuItem {
float sampleRate;
void onAction(event::Action &e) override {
gEngine->setSampleRate(sampleRate);
gEngine->paused = false;
context()->engine->setSampleRate(sampleRate);
context()->engine->paused = false;
}
};

@@ -133,14 +134,14 @@ struct SampleRateButton : TooltipIconButton {
menu->addChild(createMenuLabel("Engine sample rate"));

EnginePauseItem *pauseItem = new EnginePauseItem;
pauseItem->text = gEngine->paused ? "Resume engine" : "Pause engine";
pauseItem->text = context()->engine->paused ? "Resume engine" : "Pause engine";
menu->addChild(pauseItem);

std::vector<float> sampleRates = {44100, 48000, 88200, 96000, 176400, 192000};
for (float sampleRate : sampleRates) {
SampleRateItem *item = new SampleRateItem;
item->text = string::f("%.0f Hz", sampleRate);
item->rightText = CHECKMARK(gEngine->getSampleRate() == sampleRate);
item->rightText = CHECKMARK(context()->engine->getSampleRate() == sampleRate);
item->sampleRate = sampleRate;
menu->addChild(item);
}
@@ -153,7 +154,7 @@ struct RackLockButton : TooltipIconButton {
}
std::string getTooltipText() override {return "Lock modules";}
void onAction(event::Action &e) override {
gScene->rackWidget->lockModules ^= true;
context()->scene->rackWidget->lockModules ^= true;
}
};

@@ -185,10 +186,10 @@ struct WireTensionQuantity : Quantity {

struct ZoomQuantity : Quantity {
void setValue(float value) override {
gScene->zoomWidget->setZoom(std::round(value) / 100);
context()->scene->zoomWidget->setZoom(std::round(value) / 100);
}
float getValue() override {
return gScene->zoomWidget->zoom * 100;
return context()->scene->zoomWidget->zoom * 100;
}
float getMinValue() override {return 25;}
float getMaxValue() override {return 200;}


+ 11
- 10
src/app/WireWidget.cpp View File

@@ -4,6 +4,7 @@
#include "componentlibrary.hpp"
#include "window.hpp"
#include "event.hpp"
#include "context.hpp"


namespace rack {
@@ -108,12 +109,12 @@ void WireWidget::updateWire() {
wire->outputId = outputPort->portId;
wire->inputModule = inputPort->module;
wire->inputId = inputPort->portId;
gEngine->addWire(wire);
context()->engine->addWire(wire);
}
}
else {
if (wire) {
gEngine->removeWire(wire);
context()->engine->removeWire(wire);
delete wire;
wire = NULL;
}
@@ -122,25 +123,25 @@ void WireWidget::updateWire() {

Vec WireWidget::getOutputPos() {
if (outputPort) {
return outputPort->getRelativeOffset(outputPort->box.zeroPos().getCenter(), gScene->rackWidget);
return outputPort->getRelativeOffset(outputPort->box.zeroPos().getCenter(), context()->scene->rackWidget);
}
else if (hoveredOutputPort) {
return hoveredOutputPort->getRelativeOffset(hoveredOutputPort->box.zeroPos().getCenter(), gScene->rackWidget);
return hoveredOutputPort->getRelativeOffset(hoveredOutputPort->box.zeroPos().getCenter(), context()->scene->rackWidget);
}
else {
return gScene->rackWidget->lastMousePos;
return context()->scene->rackWidget->lastMousePos;
}
}

Vec WireWidget::getInputPos() {
if (inputPort) {
return inputPort->getRelativeOffset(inputPort->box.zeroPos().getCenter(), gScene->rackWidget);
return inputPort->getRelativeOffset(inputPort->box.zeroPos().getCenter(), context()->scene->rackWidget);
}
else if (hoveredInputPort) {
return hoveredInputPort->getRelativeOffset(hoveredInputPort->box.zeroPos().getCenter(), gScene->rackWidget);
return hoveredInputPort->getRelativeOffset(hoveredInputPort->box.zeroPos().getCenter(), context()->scene->rackWidget);
}
else {
return gScene->rackWidget->lastMousePos;
return context()->scene->rackWidget->lastMousePos;
}
}

@@ -166,14 +167,14 @@ void WireWidget::draw(NVGcontext *vg) {
float opacity = 0.5;
float tension = 0.5;

WireWidget *activeWire = gScene->rackWidget->wireContainer->activeWire;
WireWidget *activeWire = context()->scene->rackWidget->wireContainer->activeWire;
if (activeWire) {
// Draw as opaque if the wire is active
if (activeWire == this)
opacity = 1.0;
}
else {
Port *hoveredPort = dynamic_cast<Port*>(event::gContext->hoveredWidget);
Port *hoveredPort = dynamic_cast<Port*>(context()->event->hoveredWidget);
if (hoveredPort && (hoveredPort == outputPort || hoveredPort == inputPort))
opacity = 1.0;
}


+ 6
- 3
src/asset.cpp View File

@@ -1,5 +1,6 @@
#include "asset.hpp"
#include "system.hpp"
#include "context.hpp"

#if ARCH_MAC
#include <CoreFoundation/CoreFoundation.h>
@@ -27,9 +28,10 @@ std::string systemDir;
std::string userDir;


void init(bool devMode) {
void init() {
// Get system dir
if (systemDir.empty()) {
if (devMode) {
if (context()->devMode) {
systemDir = ".";
}
else {
@@ -57,8 +59,9 @@ void init(bool devMode) {
}
}

// Get user dir
if (userDir.empty()) {
if (devMode) {
if (context()->devMode) {
userDir = ".";
}
else {


+ 15
- 0
src/context.cpp View File

@@ -0,0 +1,15 @@
#include "context.hpp"


namespace rack {


static Context c;


Context *context() {
return &c;
}


} // namespace rack

+ 0
- 3
src/engine/Engine.cpp View File

@@ -325,7 +325,4 @@ float Engine::getSampleTime() {
}


Engine *gEngine = NULL;


} // namespace rack

+ 2
- 1
src/engine/Light.cpp View File

@@ -1,5 +1,6 @@
#include "engine/Light.hpp"
#include "engine/Engine.hpp"
#include "context.hpp"


namespace rack {
@@ -15,7 +16,7 @@ void Light::setBrightnessSmooth(float brightness, float frames) {
float v = (brightness > 0.f) ? std::pow(brightness, 2) : 0.f;
if (v < value) {
// Fade out light with lambda = framerate
value += (v - value) * gEngine->getSampleTime() * frames * 60.f;
value += (v - value) * context()->engine->getSampleTime() * frames * 60.f;
}
else {
// Immediately illuminate light


+ 3
- 2
src/logger.cpp View File

@@ -1,5 +1,6 @@
#include "logger.hpp"
#include "asset.hpp"
#include "context.hpp"
#include <chrono>


@@ -11,9 +12,9 @@ static FILE *outputFile = NULL;
static std::chrono::high_resolution_clock::time_point startTime;


void init(bool devMode) {
void init() {
startTime = std::chrono::high_resolution_clock::now();
if (devMode) {
if (context()->devMode) {
outputFile = stderr;
}
else {


+ 26
- 27
src/main.cpp View File

@@ -11,6 +11,7 @@
#include "app/Scene.hpp"
#include "tags.hpp"
#include "plugin/PluginManager.hpp"
#include "context.hpp"

#include <unistd.h>
#include <osdialog.h>
@@ -26,7 +27,7 @@ int main(int argc, char *argv[]) {
#ifdef ARCH_WIN
// Windows global mutex to prevent multiple instances
// Handle will be closed by Windows when the process ends
HANDLE instanceMutex = CreateMutex(NULL, true, gApplicationName.c_str());
HANDLE instanceMutex = CreateMutex(NULL, true, APP_NAME.c_str());
if (GetLastError() == ERROR_ALREADY_EXISTS) {
osdialog_message(OSDIALOG_ERROR, OSDIALOG_OK, "Rack is already running. Multiple Rack instances are not supported.");
exit(1);
@@ -34,7 +35,6 @@ int main(int argc, char *argv[]) {
(void) instanceMutex;
#endif

bool devMode = false;
std::string patchFile;

// Parse command line arguments
@@ -43,7 +43,7 @@ int main(int argc, char *argv[]) {
while ((c = getopt(argc, argv, "ds:u:")) != -1) {
switch (c) {
case 'd': {
devMode = true;
context()->devMode = true;
} break;
case 's': {
asset::systemDir = optarg;
@@ -60,28 +60,27 @@ int main(int argc, char *argv[]) {

// Initialize environment
random::init();
asset::init(devMode);
logger::init(devMode);
asset::init();
logger::init();

// Log environment
INFO("%s %s", APP_NAME.c_str(), APP_VERSION.c_str());
if (devMode)
if (context()->devMode)
INFO("Development mode");
INFO("System directory: %s", asset::system("").c_str());
INFO("User directory: %s", asset::user("").c_str());

// Initialize app
tagsInit();
gPluginManager = new PluginManager(devMode);
gEngine = new Engine;
gPluginManager = new PluginManager;
context()->engine = new Engine;
rtmidiInit();
bridgeInit();
keyboard::init();
gamepad::init();
event::gContext = new event::Context;
gScene = new Scene;
gScene->devMode = devMode;
event::gContext->rootWidget = gScene;
context()->event = new event::Context;
context()->scene = new Scene;
context()->event->rootWidget = context()->scene;
windowInit();
settings::load(asset::user("settings.json"));

@@ -92,36 +91,36 @@ int main(int argc, char *argv[]) {
settings::save(asset::user("settings.json"));
settings::gSkipAutosaveOnLaunch = false;
if (oldSkipAutosaveOnLaunch && osdialog_message(OSDIALOG_INFO, OSDIALOG_YES_NO, "Rack has recovered from a crash, possibly caused by a faulty module in your patch. Clear your patch and start over?")) {
gScene->rackWidget->lastPath = "";
context()->scene->rackWidget->lastPath = "";
}
else {
// Load autosave
std::string oldLastPath = gScene->rackWidget->lastPath;
gScene->rackWidget->load(asset::user("autosave.vcv"));
gScene->rackWidget->lastPath = oldLastPath;
std::string oldLastPath = context()->scene->rackWidget->lastPath;
context()->scene->rackWidget->load(asset::user("autosave.vcv"));
context()->scene->rackWidget->lastPath = oldLastPath;
}
}
else {
// Load patch
gScene->rackWidget->load(patchFile);
gScene->rackWidget->lastPath = patchFile;
context()->scene->rackWidget->load(patchFile);
context()->scene->rackWidget->lastPath = patchFile;
}

gEngine->start();
context()->engine->start();
windowRun();
gEngine->stop();
context()->engine->stop();

// Destroy namespaces
gScene->rackWidget->save(asset::user("autosave.vcv"));
context()->scene->rackWidget->save(asset::user("autosave.vcv"));
settings::save(asset::user("settings.json"));
delete gScene;
gScene = NULL;
delete event::gContext;
event::gContext = NULL;
delete context()->scene;
context()->scene = NULL;
delete context()->event;
context()->event = NULL;
windowDestroy();
bridgeDestroy();
delete gEngine;
gEngine = NULL;
delete context()->engine;
context()->engine = NULL;
midiDestroy();
delete gPluginManager;
gPluginManager = NULL;


+ 3
- 2
src/plugin/PluginManager.cpp View File

@@ -4,6 +4,7 @@
#include "network.hpp"
#include "asset.hpp"
#include "string.hpp"
#include "context.hpp"
#include "app/common.hpp"

#include <unistd.h>
@@ -299,7 +300,7 @@ static void extractPackages(std::string path) {
// public API
////////////////////

PluginManager::PluginManager(bool devMode) {
PluginManager::PluginManager() {
// Load core
// This function is defined in core.cpp
Plugin *corePlugin = new Plugin;
@@ -310,7 +311,7 @@ PluginManager::PluginManager(bool devMode) {
std::string userPlugins = asset::user("plugins");
mkdir(userPlugins.c_str(), 0755);

if (!devMode) {
if (!context()->devMode) {
// Copy Fundamental package to plugins directory if folder does not exist
std::string fundamentalSrc = asset::system("Fundamental.zip");
std::string fundamentalDest = asset::user("plugins/Fundamental.zip");


+ 15
- 14
src/settings.cpp View File

@@ -5,6 +5,7 @@
#include "app/Scene.hpp"
#include "app/ModuleBrowser.hpp"
#include "engine/Engine.hpp"
#include "context.hpp"
#include <jansson.h>


@@ -36,17 +37,17 @@ static json_t *settingsToJson() {
}

// opacity
float opacity = gScene->toolbar->wireOpacity;
float opacity = context()->scene->toolbar->wireOpacity;
json_t *opacityJ = json_real(opacity);
json_object_set_new(rootJ, "wireOpacity", opacityJ);

// tension
float tension = gScene->toolbar->wireTension;
float tension = context()->scene->toolbar->wireTension;
json_t *tensionJ = json_real(tension);
json_object_set_new(rootJ, "wireTension", tensionJ);

// zoom
float zoom = gScene->zoomWidget->zoom;
float zoom = context()->scene->zoomWidget->zoom;
json_t *zoomJ = json_real(zoom);
json_object_set_new(rootJ, "zoom", zoomJ);

@@ -55,11 +56,11 @@ static json_t *settingsToJson() {
json_object_set_new(rootJ, "allowCursorLock", allowCursorLockJ);

// sampleRate
json_t *sampleRateJ = json_real(gEngine->getSampleRate());
json_t *sampleRateJ = json_real(context()->engine->getSampleRate());
json_object_set_new(rootJ, "sampleRate", sampleRateJ);

// lastPath
json_t *lastPathJ = json_string(gScene->rackWidget->lastPath.c_str());
json_t *lastPathJ = json_string(context()->scene->rackWidget->lastPath.c_str());
json_object_set_new(rootJ, "lastPath", lastPathJ);

// skipAutosaveOnLaunch
@@ -71,10 +72,10 @@ static json_t *settingsToJson() {
json_object_set_new(rootJ, "moduleBrowser", moduleBrowserToJson());

// powerMeter
json_object_set_new(rootJ, "powerMeter", json_boolean(gEngine->powerMeter));
json_object_set_new(rootJ, "powerMeter", json_boolean(context()->engine->powerMeter));

// checkVersion
json_object_set_new(rootJ, "checkVersion", json_boolean(gScene->checkVersion));
json_object_set_new(rootJ, "checkVersion", json_boolean(context()->scene->checkVersion));

return rootJ;
}
@@ -104,17 +105,17 @@ static void settingsFromJson(json_t *rootJ) {
// opacity
json_t *opacityJ = json_object_get(rootJ, "wireOpacity");
if (opacityJ)
gScene->toolbar->wireOpacity = json_number_value(opacityJ);
context()->scene->toolbar->wireOpacity = json_number_value(opacityJ);

// tension
json_t *tensionJ = json_object_get(rootJ, "wireTension");
if (tensionJ)
gScene->toolbar->wireTension = json_number_value(tensionJ);
context()->scene->toolbar->wireTension = json_number_value(tensionJ);

// zoom
json_t *zoomJ = json_object_get(rootJ, "zoom");
if (zoomJ) {
gScene->zoomWidget->setZoom(clamp((float) json_number_value(zoomJ), 0.25f, 4.0f));
context()->scene->zoomWidget->setZoom(clamp((float) json_number_value(zoomJ), 0.25f, 4.0f));
}

// allowCursorLock
@@ -126,13 +127,13 @@ static void settingsFromJson(json_t *rootJ) {
json_t *sampleRateJ = json_object_get(rootJ, "sampleRate");
if (sampleRateJ) {
float sampleRate = json_number_value(sampleRateJ);
gEngine->setSampleRate(sampleRate);
context()->engine->setSampleRate(sampleRate);
}

// lastPath
json_t *lastPathJ = json_object_get(rootJ, "lastPath");
if (lastPathJ)
gScene->rackWidget->lastPath = json_string_value(lastPathJ);
context()->scene->rackWidget->lastPath = json_string_value(lastPathJ);

// skipAutosaveOnLaunch
json_t *skipAutosaveOnLaunchJ = json_object_get(rootJ, "skipAutosaveOnLaunch");
@@ -147,12 +148,12 @@ static void settingsFromJson(json_t *rootJ) {
// powerMeter
json_t *powerMeterJ = json_object_get(rootJ, "powerMeter");
if (powerMeterJ)
gEngine->powerMeter = json_boolean_value(powerMeterJ);
context()->engine->powerMeter = json_boolean_value(powerMeterJ);

// checkVersion
json_t *checkVersionJ = json_object_get(rootJ, "checkVersion");
if (checkVersionJ)
gScene->checkVersion = json_boolean_value(checkVersionJ);
context()->scene->checkVersion = json_boolean_value(checkVersionJ);
}




+ 2
- 1
src/widgets/Widget.cpp View File

@@ -1,5 +1,6 @@
#include "widgets/Widget.hpp"
#include "event.hpp"
#include "context.hpp"
#include <algorithm>


@@ -8,7 +9,7 @@ namespace rack {
Widget::~Widget() {
// You should only delete orphaned widgets
assert(!parent);
event::gContext->finalizeWidget(this);
context()->event->finalizeWidget(this);
clearChildren();
}



+ 14
- 13
src/window.cpp View File

@@ -5,6 +5,7 @@
#include "keyboard.hpp"
#include "gamepad.hpp"
#include "event.hpp"
#include "context.hpp"

#include <map>
#include <queue>
@@ -62,7 +63,7 @@ static void mouseButtonCallback(GLFWwindow *window, int button, int action, int
}
#endif

event::gContext->handleButton(gMousePos, button, action, mods);
context()->event->handleButton(gMousePos, button, action, mods);
}

struct MouseButtonArguments {
@@ -109,12 +110,12 @@ void cursorPosCallback(GLFWwindow* window, double xpos, double ypos) {

gMousePos = mousePos;

event::gContext->handleHover(mousePos, mouseDelta);
context()->event->handleHover(mousePos, mouseDelta);
}

void cursorEnterCallback(GLFWwindow* window, int entered) {
if (!entered) {
event::gContext->handleLeave();
context()->event->handleLeave();
}
}

@@ -126,15 +127,15 @@ void scrollCallback(GLFWwindow *window, double x, double y) {
#endif
scrollDelta = scrollDelta.mult(50.0);

event::gContext->handleScroll(gMousePos, scrollDelta);
context()->event->handleScroll(gMousePos, scrollDelta);
}

void charCallback(GLFWwindow *window, unsigned int codepoint) {
event::gContext->handleText(gMousePos, codepoint);
context()->event->handleText(gMousePos, codepoint);
}

void keyCallback(GLFWwindow *window, int key, int scancode, int action, int mods) {
event::gContext->handleKey(gMousePos, key, scancode, action, mods);
context()->event->handleKey(gMousePos, key, scancode, action, mods);

// Keyboard MIDI driver
if (!(mods & (GLFW_MOD_SHIFT | GLFW_MOD_CONTROL | GLFW_MOD_ALT | GLFW_MOD_SUPER))) {
@@ -152,7 +153,7 @@ void dropCallback(GLFWwindow *window, int count, const char **paths) {
for (int i = 0; i < count; i++) {
pathsVec.push_back(paths[i]);
}
event::gContext->handleDrop(gMousePos, pathsVec);
context()->event->handleDrop(gMousePos, pathsVec);
}

void errorCallback(int error, const char *description) {
@@ -168,7 +169,7 @@ void renderGui() {

nvgReset(gVg);
nvgScale(gVg, gPixelRatio, gPixelRatio);
event::gContext->rootWidget->draw(gVg);
context()->event->rootWidget->draw(gVg);

glViewport(0, 0, width, height);
glClearColor(0.0, 0.0, 0.0, 1.0);
@@ -307,9 +308,9 @@ void windowRun() {
windowTitle = APP_NAME;
windowTitle += " ";
windowTitle += APP_VERSION;
if (!gScene->rackWidget->lastPath.empty()) {
if (!context()->scene->rackWidget->lastPath.empty()) {
windowTitle += " - ";
windowTitle += string::filename(gScene->rackWidget->lastPath);
windowTitle += string::filename(context()->scene->rackWidget->lastPath);
}
if (windowTitle != lastWindowTitle) {
glfwSetWindowTitle(gWindow, windowTitle.c_str());
@@ -321,7 +322,7 @@ void windowRun() {
glfwGetWindowContentScale(gWindow, &pixelRatio, NULL);
pixelRatio = roundf(pixelRatio);
if (pixelRatio != gPixelRatio) {
event::gContext->handleZoom();
context()->event->handleZoom();
gPixelRatio = pixelRatio;
}

@@ -332,10 +333,10 @@ void windowRun() {
glfwGetWindowSize(gWindow, &windowWidth, &windowHeight);
gWindowRatio = (float)width / windowWidth;

event::gContext->rootWidget->box.size = Vec(width, height).div(gPixelRatio);
context()->event->rootWidget->box.size = Vec(width, height).div(gPixelRatio);

// Step scene
event::gContext->rootWidget->step();
context()->event->rootWidget->step();

// Render
bool visible = glfwGetWindowAttrib(gWindow, GLFW_VISIBLE) && !glfwGetWindowAttrib(gWindow, GLFW_ICONIFIED);


Loading…
Cancel
Save