diff --git a/include/app.hpp b/include/app.hpp index 142f36d5..52634e6e 100644 --- a/include/app.hpp +++ b/include/app.hpp @@ -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(); diff --git a/include/plugin.hpp b/include/plugin.hpp index f6b39357..9b00831e 100644 --- a/include/plugin.hpp +++ b/include/plugin.hpp @@ -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(); diff --git a/src/app.cpp b/src/app.cpp index e993539a..1b595b57 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -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; } diff --git a/src/main.cpp b/src/main.cpp index eace6645..dbfc9bf9 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -16,6 +16,7 @@ #include "system.hpp" #include +#include #include // for getopt #include // 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; diff --git a/src/plugin.cpp b/src/plugin.cpp index 1035bec8..56d92bf7 100644 --- a/src/plugin.cpp +++ b/src/plugin.cpp @@ -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