modetags/v0.6.1
| @@ -5,10 +5,6 @@ FLAGS += \ | |||
| -Iinclude \ | |||
| -Idep/include -Idep/lib/libzip/include | |||
| ifdef RELEASE | |||
| FLAGS += -DRELEASE | |||
| endif | |||
| include arch.mk | |||
| STRIP ?= strip | |||
| @@ -58,22 +54,25 @@ dep: | |||
| $(MAKE) -C dep | |||
| run: $(TARGET) | |||
| ./$< -d | |||
| runr: $(TARGET) | |||
| ./$< | |||
| debug: $(TARGET) | |||
| ifdef ARCH_MAC | |||
| lldb -ex run ./$< | |||
| lldb -ex run ./$< -d | |||
| endif | |||
| ifdef ARCH_WIN | |||
| gdb -ex run ./$< | |||
| gdb -ex run ./$< -d | |||
| endif | |||
| ifdef ARCH_LIN | |||
| gdb -ex run ./$< | |||
| gdb -ex run ./$< -d | |||
| endif | |||
| perf: $(TARGET) | |||
| ifdef ARCH_LIN | |||
| perf record --call-graph dwarf ./$< | |||
| perf record --call-graph dwarf ./$< -d | |||
| endif | |||
| clean: | |||
| @@ -88,9 +87,6 @@ endif | |||
| # This target is not intended for public use | |||
| dist: all | |||
| ifndef RELEASE | |||
| exit 1 # Must enable RELEASE for dist target | |||
| endif | |||
| rm -rf dist | |||
| # Rack distribution | |||
| $(MAKE) -C plugins/Fundamental dist | |||
| @@ -7,6 +7,7 @@ | |||
| namespace rack { | |||
| void assetInit(bool devMode); | |||
| /** Returns the path of a global resource. Should only read files from this location. */ | |||
| std::string assetGlobal(std::string filename); | |||
| /** Returns the path of a local resource. Can read and write files to this location. */ | |||
| @@ -95,7 +95,7 @@ struct Model { | |||
| }; | |||
| void pluginInit(); | |||
| void pluginInit(bool devMode); | |||
| void pluginDestroy(); | |||
| void pluginLogIn(std::string email, std::string password); | |||
| void pluginLogOut(); | |||
| @@ -175,7 +175,7 @@ enum LoggerLevel { | |||
| FATAL_LEVEL | |||
| }; | |||
| void loggerInit(); | |||
| void loggerInit(bool devMode); | |||
| void loggerDestroy(); | |||
| /** Do not use this function directly. Use the macros below. */ | |||
| void loggerLog(LoggerLevel level, const char *file, int line, const char *format, ...); | |||
| @@ -209,10 +209,11 @@ Toolbar::Toolbar() { | |||
| layout->addChild(cpuUsageButton); | |||
| */ | |||
| #if defined(RELEASE) | |||
| Widget *pluginManager = new PluginManagerWidget(); | |||
| layout->addChild(pluginManager); | |||
| #endif | |||
| // Kind of hacky, but display the PluginManagerWidget only if the local directory is not the development directory | |||
| if (assetLocal("") != "./") { | |||
| Widget *pluginManager = new PluginManagerWidget(); | |||
| layout->addChild(pluginManager); | |||
| } | |||
| } | |||
| void Toolbar::draw(NVGcontext *vg) { | |||
| @@ -3,6 +3,8 @@ | |||
| namespace rack { | |||
| bool gDev = false; | |||
| std::string gApplicationName = "VCV Rack"; | |||
| std::string gApplicationVersion = TOSTRING(VERSION); | |||
| std::string gApiHost = "https://api.vcvrack.com"; | |||
| @@ -1,93 +1,94 @@ | |||
| #include "asset.hpp" | |||
| #include "util/common.hpp" | |||
| #include <sys/stat.h> // for mkdir | |||
| #include "osdialog.h" | |||
| #if ARCH_MAC | |||
| #include <CoreFoundation/CoreFoundation.h> | |||
| #include <pwd.h> | |||
| #include <CoreFoundation/CoreFoundation.h> | |||
| #include <pwd.h> | |||
| #endif | |||
| #if ARCH_WIN | |||
| #include <Windows.h> | |||
| #include <Shlobj.h> | |||
| #include <Shlwapi.h> | |||
| #include <Windows.h> | |||
| #include <Shlobj.h> | |||
| #include <Shlwapi.h> | |||
| #endif | |||
| #if ARCH_LIN | |||
| #include <unistd.h> | |||
| #include <sys/types.h> | |||
| #include <pwd.h> | |||
| #include <unistd.h> | |||
| #include <sys/types.h> | |||
| #include <pwd.h> | |||
| #endif | |||
| namespace rack { | |||
| std::string assetGlobal(std::string filename) { | |||
| std::string dir; | |||
| #if RELEASE | |||
| static std::string globalDir; | |||
| static std::string localDir; | |||
| void assetInit(bool devMode) { | |||
| if (devMode) { | |||
| // Use current working directory if running in development mode | |||
| globalDir = "."; | |||
| localDir = "."; | |||
| return; | |||
| } | |||
| #if ARCH_MAC | |||
| CFBundleRef bundle = CFBundleGetMainBundle(); | |||
| assert(bundle); | |||
| CFURLRef resourcesUrl = CFBundleCopyResourcesDirectoryURL(bundle); | |||
| char buf[PATH_MAX]; | |||
| Boolean success = CFURLGetFileSystemRepresentation(resourcesUrl, TRUE, (UInt8 *)buf, sizeof(buf)); | |||
| Boolean success = CFURLGetFileSystemRepresentation(resourcesUrl, TRUE, (UInt8*) buf, sizeof(buf)); | |||
| assert(success); | |||
| CFRelease(resourcesUrl); | |||
| dir = buf; | |||
| globalDir = buf; | |||
| // Get home directory | |||
| struct passwd *pw = getpwuid(getuid()); | |||
| assert(pw); | |||
| localDir = pw->pw_dir; | |||
| localDir += "/Documents/Rack"; | |||
| #endif | |||
| #if ARCH_WIN | |||
| char buf[MAX_PATH]; | |||
| DWORD length = GetModuleFileName(NULL, buf, sizeof(buf)); | |||
| assert(length > 0); | |||
| PathRemoveFileSpec(buf); | |||
| dir = buf; | |||
| #endif | |||
| #if ARCH_LIN | |||
| // TODO For now, users should launch Rack from their terminal in the global directory | |||
| dir = "."; | |||
| #endif | |||
| #else // RELEASE | |||
| dir = "."; | |||
| #endif // RELEASE | |||
| return dir + "/" + filename; | |||
| } | |||
| globalDir = buf; | |||
| std::string assetLocal(std::string filename) { | |||
| std::string dir; | |||
| #if RELEASE | |||
| #if ARCH_MAC | |||
| // Get home directory | |||
| struct passwd *pw = getpwuid(getuid()); | |||
| assert(pw); | |||
| dir = pw->pw_dir; | |||
| dir += "/Documents/Rack"; | |||
| #endif | |||
| #if ARCH_WIN | |||
| // Get "My Documents" folder | |||
| char buf[MAX_PATH]; | |||
| HRESULT result = SHGetFolderPath(NULL, CSIDL_MYDOCUMENTS, NULL, SHGFP_TYPE_CURRENT, buf); | |||
| assert(result == S_OK); | |||
| dir = buf; | |||
| dir += "/Rack"; | |||
| localDir = buf; | |||
| localDir += "/Rack"; | |||
| #endif | |||
| #if ARCH_LIN | |||
| // TODO For now, users should launch Rack from their terminal in the global directory | |||
| globalDir = "."; | |||
| // Get home directory | |||
| const char *home = getenv("HOME"); | |||
| if (!home) { | |||
| struct passwd *pw = getpwuid(getuid()); | |||
| assert(pw); | |||
| home = pw->pw_dir; | |||
| } | |||
| dir = home; | |||
| dir += "/.Rack"; | |||
| localDir = home; | |||
| localDir += "/.Rack"; | |||
| #endif | |||
| systemCreateDirectory(dir); | |||
| #else // RELEASE | |||
| dir = "."; | |||
| #endif // RELEASE | |||
| return dir + "/" + filename; | |||
| } | |||
| std::string assetGlobal(std::string filename) { | |||
| return globalDir + "/" + filename; | |||
| } | |||
| std::string assetLocal(std::string filename) { | |||
| return localDir + "/" + filename; | |||
| } | |||
| @@ -20,23 +20,38 @@ using namespace rack; | |||
| int main(int argc, char* argv[]) { | |||
| randomInit(); | |||
| loggerInit(); | |||
| bool devMode = false; | |||
| std::string patchFile; | |||
| // Parse command line arguments | |||
| std::string patchFile; | |||
| if (argc >= 2) { | |||
| patchFile = argv[1]; | |||
| int c; | |||
| opterr = 0; | |||
| while ((c = getopt(argc, argv, "d")) != -1) { | |||
| switch (c) { | |||
| case 'd': { | |||
| devMode = true; | |||
| } break; | |||
| default: break; | |||
| } | |||
| } | |||
| if (optind < argc) { | |||
| patchFile = argv[optind]; | |||
| } | |||
| info("Rack %s", gApplicationVersion.c_str()); | |||
| // Initialize environment | |||
| randomInit(); | |||
| assetInit(devMode); | |||
| loggerInit(devMode); | |||
| // Log directories | |||
| // Log environment | |||
| info("Rack %s", gApplicationVersion.c_str()); | |||
| if (devMode) | |||
| info("Development mode"); | |||
| info("Global directory: %s", assetGlobal("").c_str()); | |||
| info("Local directory: %s", assetLocal("").c_str()); | |||
| // Initialize namespaces | |||
| pluginInit(); | |||
| // Initialize app | |||
| pluginInit(devMode); | |||
| engineInit(); | |||
| rtmidiInit(); | |||
| bridgeInit(); | |||
| @@ -321,7 +321,7 @@ static void extractPackages(std::string path) { | |||
| // public API | |||
| //////////////////// | |||
| void pluginInit() { | |||
| void pluginInit(bool devMode) { | |||
| tagsInit(); | |||
| // Load core | |||
| @@ -334,15 +334,15 @@ void pluginInit() { | |||
| std::string localPlugins = assetLocal("plugins"); | |||
| mkdir(localPlugins.c_str(), 0755); | |||
| #if RELEASE | |||
| // Copy Fundamental package to plugins directory if folder does not exist | |||
| std::string fundamentalSrc = assetGlobal("Fundamental.zip"); | |||
| std::string fundamentalDest = assetLocal("plugins/Fundamental.zip"); | |||
| std::string fundamentalDir = assetLocal("plugins/Fundamental"); | |||
| if (!systemIsDirectory(fundamentalDir) && !systemIsFile(fundamentalDest)) { | |||
| systemCopy(fundamentalSrc, fundamentalDest); | |||
| if (!devMode) { | |||
| // Copy Fundamental package to plugins directory if folder does not exist | |||
| std::string fundamentalSrc = assetGlobal("Fundamental.zip"); | |||
| std::string fundamentalDest = assetLocal("plugins/Fundamental.zip"); | |||
| std::string fundamentalDir = assetLocal("plugins/Fundamental"); | |||
| if (systemIsFile(fundamentalSrc) && !systemIsFile(fundamentalDest) && !systemIsDirectory(fundamentalDir)) { | |||
| systemCopy(fundamentalSrc, fundamentalDest); | |||
| } | |||
| } | |||
| #endif | |||
| // Extract packages and load plugins | |||
| extractPackages(localPlugins); | |||
| @@ -6,22 +6,25 @@ | |||
| namespace rack { | |||
| static FILE *logFile = stderr; | |||
| static FILE *logFile = NULL; | |||
| static std::chrono::high_resolution_clock::time_point startTime; | |||
| void loggerInit() { | |||
| void loggerInit(bool devMode) { | |||
| startTime = std::chrono::high_resolution_clock::now(); | |||
| #ifdef RELEASE | |||
| std::string logFilename = assetLocal("log.txt"); | |||
| logFile = fopen(logFilename.c_str(), "w"); | |||
| #endif | |||
| if (devMode) { | |||
| logFile = stderr; | |||
| } | |||
| else { | |||
| std::string logFilename = assetLocal("log.txt"); | |||
| logFile = fopen(logFilename.c_str(), "w"); | |||
| } | |||
| } | |||
| void loggerDestroy() { | |||
| #ifdef RELEASE | |||
| fclose(logFile); | |||
| #endif | |||
| if (logFile != stderr) { | |||
| fclose(logFile); | |||
| } | |||
| } | |||
| static const char* const loggerText[] = { | |||