@@ -45,12 +45,12 @@ struct App { | |||
history::State *history = NULL; | |||
PatchManager *patch = NULL; | |||
App(); | |||
void init(bool headless); | |||
~App(); | |||
}; | |||
void init(); | |||
void init(bool headless); | |||
void destroy(); | |||
/** Returns the global App pointer */ | |||
App *get(); | |||
@@ -14,7 +14,7 @@ namespace rack { | |||
namespace plugin { | |||
void init(bool devMode); | |||
void init(); | |||
void destroy(); | |||
void logIn(const std::string &email, const std::string &password); | |||
void logOut(); | |||
@@ -11,42 +11,51 @@ namespace rack { | |||
namespace app { | |||
App::App() { | |||
event = new event::State; | |||
history = new history::State; | |||
window = new Window; | |||
void App::init(bool headless) { | |||
engine = new engine::Engine; | |||
patch = new PatchManager; | |||
scene = new Scene; | |||
event->rootWidget = scene; | |||
if (!headless) { | |||
event = new event::State; | |||
history = new history::State; | |||
window = new Window; | |||
patch = new PatchManager; | |||
scene = new Scene; | |||
event->rootWidget = scene; | |||
} | |||
} | |||
App::~App() { | |||
// Set pointers to NULL so other objects will segfault when attempting to access them | |||
delete scene; scene = NULL; | |||
delete patch; patch = NULL; | |||
delete event; event = NULL; | |||
delete history; history = NULL; | |||
delete engine; engine = NULL; | |||
delete window; window = NULL; | |||
if (scene) delete scene; | |||
scene = NULL; | |||
if (patch) delete patch; | |||
patch = NULL; | |||
if (event) delete event; | |||
event = NULL; | |||
if (history) delete history; | |||
history = NULL; | |||
if (window) delete window; | |||
window = NULL; | |||
if (engine) delete engine; | |||
engine = NULL; | |||
} | |||
static App *c = NULL; | |||
static App *app = NULL; | |||
void init() { | |||
assert(!c); | |||
c = new App; | |||
void init(bool headless) { | |||
assert(!app); | |||
app = new App; | |||
app->init(headless); | |||
} | |||
void destroy() { | |||
assert(c); | |||
delete c; | |||
c = NULL; | |||
assert(app); | |||
delete app; | |||
app = NULL; | |||
} | |||
App *get() { | |||
return c; | |||
return app; | |||
} | |||
@@ -16,6 +16,7 @@ | |||
#include "system.hpp" | |||
#include <osdialog.h> | |||
#include <thread> | |||
#include <unistd.h> // for getopt | |||
#include <signal.h> // for signal | |||
@@ -55,6 +56,7 @@ int main(int argc, char *argv[]) { | |||
#endif | |||
bool devMode = false; | |||
bool headless = false; | |||
std::string patchPath; | |||
// Parse command line arguments | |||
@@ -65,6 +67,9 @@ int main(int argc, char *argv[]) { | |||
case 'd': { | |||
devMode = true; | |||
} break; | |||
case 'h': { | |||
headless = true; | |||
} break; | |||
case 's': { | |||
asset::systemDir = optarg; | |||
} break; | |||
@@ -101,43 +106,59 @@ int main(int argc, char *argv[]) { | |||
INFO("System directory: %s", asset::systemDir.c_str()); | |||
INFO("User directory: %s", asset::userDir.c_str()); | |||
INFO("Initializing environment"); | |||
random::init(); | |||
midi::init(); | |||
rtmidiInit(); | |||
bridgeInit(); | |||
keyboard::init(); | |||
gamepad::init(); | |||
ui::init(); | |||
plugin::init(devMode); | |||
windowInit(); | |||
INFO("Initialized environment"); | |||
plugin::init(); | |||
if (!headless) { | |||
ui::init(); | |||
windowInit(); | |||
} | |||
// Initialize app | |||
INFO("Initializing app"); | |||
settings.load(asset::user("settings.json")); | |||
app::init(); | |||
APP->scene->devMode = devMode; | |||
APP->patch->init(patchPath); | |||
INFO("Initialized app"); | |||
app::init(headless); | |||
if (!headless) { | |||
APP->scene->devMode = devMode; | |||
APP->patch->init(patchPath); | |||
} | |||
INFO("Starting engine"); | |||
APP->engine->start(); | |||
APP->window->run(); | |||
INFO("Window closed"); | |||
if (!headless) { | |||
INFO("Running window"); | |||
APP->window->run(); | |||
INFO("Stopped window"); | |||
} | |||
else { | |||
// TEMP Prove that the app doesn't crash | |||
std::this_thread::sleep_for(std::chrono::seconds(2)); | |||
} | |||
INFO("Stopping engine"); | |||
APP->engine->stop(); | |||
// Destroy app | |||
APP->patch->save(asset::user("autosave.vcv")); | |||
// APP->patch->save(asset::user("autosave.vcv")); | |||
INFO("Destroying app"); | |||
app::destroy(); | |||
settings.save(asset::user("settings.json")); | |||
INFO("Cleaned up app"); | |||
// Destroy environment | |||
windowDestroy(); | |||
INFO("Destroying environment"); | |||
if (!headless) { | |||
windowDestroy(); | |||
ui::destroy(); | |||
} | |||
plugin::destroy(); | |||
ui::destroy(); | |||
bridgeDestroy(); | |||
midi::destroy(); | |||
INFO("Cleaned up environment"); | |||
INFO("Destroying logger"); | |||
logger::destroy(); | |||
return 0; | |||
@@ -352,7 +352,7 @@ static void extractPackages(const std::string &path) { | |||
// public API | |||
//////////////////// | |||
void init(bool devMode) { | |||
void init() { | |||
// Load Core | |||
Plugin *corePlugin = new Plugin; | |||
// This function is defined in Core/plugin.cpp | |||