| @@ -1,6 +1,6 @@ | |||
| #pragma once | |||
| #include <vector> | |||
| #include "util.hpp" | |||
| #include "util/util.hpp" | |||
| #include <jansson.h> | |||
| @@ -1,6 +1,6 @@ | |||
| #pragma once | |||
| #include "util.hpp" | |||
| #include "util/util.hpp" | |||
| #include <queue> | |||
| #include <vector> | |||
| #include <jansson.h> | |||
| @@ -1,7 +1,6 @@ | |||
| #pragma once | |||
| #include "util.hpp" | |||
| #include "util/math.hpp" | |||
| #include "util/util.hpp" | |||
| #include "asset.hpp" | |||
| #include "plugin.hpp" | |||
| #include "engine.hpp" | |||
| @@ -1,5 +1,4 @@ | |||
| #pragma once | |||
| #include <stdint.h> | |||
| #include <stdlib.h> | |||
| #include <cmath> | |||
| @@ -1,5 +1,4 @@ | |||
| #pragma once | |||
| #include <string> | |||
| #include <jansson.h> | |||
| @@ -18,7 +17,10 @@ enum RequestMethod { | |||
| json_t *requestJson(RequestMethod method, std::string url, json_t *dataJ); | |||
| /** Returns the filename, blank if unsuccessful */ | |||
| bool requestDownload(std::string url, std::string filename, float *progress); | |||
| /** URL-encodes `s` */ | |||
| std::string requestEscape(std::string s); | |||
| /** Computes the SHA256 of the file at `filename` */ | |||
| std::string requestSHA256File(std::string filename); | |||
| } // namespace rack | |||
| @@ -4,12 +4,15 @@ | |||
| #include <stdlib.h> | |||
| #include <stdio.h> | |||
| #include <stdint.h> | |||
| #include <string.h> | |||
| #include <assert.h> | |||
| #include <string> | |||
| #include <condition_variable> | |||
| #include <mutex> | |||
| #include "util/math.hpp" | |||
| /** Surrounds raw text with quotes | |||
| Example: | |||
| @@ -63,6 +66,55 @@ T *construct(F f, V v, Args... args) { | |||
| return o; | |||
| } | |||
| //////////////////// | |||
| // random.cpp | |||
| //////////////////// | |||
| /** Seeds the RNG with the current time */ | |||
| void randomInit(); | |||
| uint32_t randomu32(); | |||
| uint64_t randomu64(); | |||
| /** Returns a uniform random float in the interval [0.0, 1.0) */ | |||
| float randomf(); | |||
| /** Returns a normal random number with mean 0 and std dev 1 */ | |||
| float randomNormal(); | |||
| //////////////////// | |||
| // string.cpp | |||
| //////////////////// | |||
| /** Converts a printf format string and optional arguments into a std::string */ | |||
| std::string stringf(const char *format, ...); | |||
| std::string lowercase(std::string s); | |||
| std::string uppercase(std::string s); | |||
| /** Truncates and adds "..." to a string, not exceeding `len` characters */ | |||
| std::string ellipsize(std::string s, size_t len); | |||
| bool startsWith(std::string str, std::string prefix); | |||
| std::string extractDirectory(std::string path); | |||
| std::string extractFilename(std::string path); | |||
| std::string extractExtension(std::string path); | |||
| //////////////////// | |||
| // system.cpp | |||
| //////////////////// | |||
| /** Opens a URL, also happens to work with PDFs and folders. | |||
| Shell injection is possible, so make sure the URL is trusted or hard coded. | |||
| May block, so open in a new thread. | |||
| */ | |||
| void openBrowser(std::string url); | |||
| //////////////////// | |||
| // logger.cpp | |||
| //////////////////// | |||
| extern FILE *gLogFile; | |||
| void debug(const char *format, ...); | |||
| void info(const char *format, ...); | |||
| void warn(const char *format, ...); | |||
| void fatal(const char *format, ...); | |||
| //////////////////// | |||
| // Thread functions | |||
| @@ -98,15 +150,5 @@ struct VIPLock { | |||
| } | |||
| }; | |||
| //////////////////// | |||
| // logger | |||
| //////////////////// | |||
| extern FILE *gLogFile; | |||
| void debug(const char *format, ...); | |||
| void info(const char *format, ...); | |||
| void warn(const char *format, ...); | |||
| void fatal(const char *format, ...); | |||
| } // namespace rack | |||
| @@ -6,9 +6,7 @@ | |||
| #include "../ext/oui-blendish/blendish.h" | |||
| #include "../ext/nanosvg/src/nanosvg.h" | |||
| #include "util/math.hpp" | |||
| #include "util/vec.hpp" | |||
| #include "util.hpp" | |||
| #include "util/util.hpp" | |||
| #include "events.hpp" | |||
| @@ -1,5 +1,5 @@ | |||
| #include "asset.hpp" | |||
| #include "util.hpp" | |||
| #include "util/util.hpp" | |||
| #include <assert.h> | |||
| #include <sys/stat.h> // for mkdir | |||
| #include "../ext/osdialog/osdialog.h" | |||
| @@ -1,4 +1,4 @@ | |||
| #include "util.hpp" | |||
| #include "util/util.hpp" | |||
| #include "util/math.hpp" | |||
| #include "audio.hpp" | |||
| @@ -10,7 +10,6 @@ | |||
| #include <pmmintrin.h> | |||
| #include "engine.hpp" | |||
| #include "util.hpp" | |||
| namespace rack { | |||
| @@ -1,3 +1,4 @@ | |||
| #include "util/util.hpp" | |||
| #include "engine.hpp" | |||
| #include "gui.hpp" | |||
| #include "app.hpp" | |||
| @@ -1,4 +1,3 @@ | |||
| #include "util.hpp" | |||
| #include <stdarg.h> | |||
| #include <string.h> | |||
| #include <random> | |||
| @@ -10,202 +9,3 @@ | |||
| #include <windows.h> | |||
| #include <shellapi.h> | |||
| #endif | |||
| namespace rack { | |||
| //////////////////// | |||
| // RNG | |||
| //////////////////// | |||
| // xoroshiro128+ | |||
| // from http://xoroshiro.di.unimi.it/xoroshiro128plus.c | |||
| static uint64_t xoroshiro128plus_state[2] = {}; | |||
| static uint64_t rotl(const uint64_t x, int k) { | |||
| return (x << k) | (x >> (64 - k)); | |||
| } | |||
| static uint64_t xoroshiro128plus_next(void) { | |||
| const uint64_t s0 = xoroshiro128plus_state[0]; | |||
| uint64_t s1 = xoroshiro128plus_state[1]; | |||
| const uint64_t result = s0 + s1; | |||
| s1 ^= s0; | |||
| xoroshiro128plus_state[0] = rotl(s0, 55) ^ s1 ^ (s1 << 14); // a, b | |||
| xoroshiro128plus_state[1] = rotl(s1, 36); // c | |||
| return result; | |||
| } | |||
| void randomInit() { | |||
| // Only allow the seed to be initialized once during the lifetime of the program. | |||
| assert(xoroshiro128plus_state[0] == 0 && xoroshiro128plus_state[1] == 0); | |||
| struct timeval tv; | |||
| gettimeofday(&tv, NULL); | |||
| xoroshiro128plus_state[0] = tv.tv_sec; | |||
| xoroshiro128plus_state[1] = tv.tv_usec; | |||
| // Generate a few times to fix the fact that the time is not a uniform u64 | |||
| for (int i = 0; i < 10; i++) { | |||
| xoroshiro128plus_next(); | |||
| } | |||
| } | |||
| uint32_t randomu32() { | |||
| return xoroshiro128plus_next() >> 32; | |||
| } | |||
| uint64_t randomu64() { | |||
| return xoroshiro128plus_next(); | |||
| } | |||
| float randomf() { | |||
| // 24 bits of granularity is the best that can be done with floats while ensuring that the return value lies in [0.0, 1.0). | |||
| return (xoroshiro128plus_next() >> (64 - 24)) / powf(2, 24); | |||
| } | |||
| float randomNormal() { | |||
| // Box-Muller transform | |||
| float radius = sqrtf(-2.f * logf(1.f - randomf())); | |||
| float theta = 2.f * M_PI * randomf(); | |||
| return radius * sinf(theta); | |||
| // // Central Limit Theorem | |||
| // const int n = 8; | |||
| // float sum = 0.0; | |||
| // for (int i = 0; i < n; i++) { | |||
| // sum += randomf(); | |||
| // } | |||
| // return (sum - n / 2.f) / sqrtf(n / 12.f); | |||
| } | |||
| //////////////////// | |||
| // String functions | |||
| //////////////////// | |||
| std::string stringf(const char *format, ...) { | |||
| va_list args; | |||
| va_start(args, format); | |||
| // Compute size of required buffer | |||
| int size = vsnprintf(NULL, 0, format, args); | |||
| va_end(args); | |||
| if (size < 0) | |||
| return ""; | |||
| // Create buffer | |||
| std::string s; | |||
| s.resize(size); | |||
| va_start(args, format); | |||
| vsnprintf(&s[0], size + 1, format, args); | |||
| va_end(args); | |||
| return s; | |||
| } | |||
| std::string lowercase(std::string s) { | |||
| std::transform(s.begin(), s.end(), s.begin(), ::tolower); | |||
| return s; | |||
| } | |||
| std::string uppercase(std::string s) { | |||
| std::transform(s.begin(), s.end(), s.begin(), ::toupper); | |||
| return s; | |||
| } | |||
| std::string ellipsize(std::string s, size_t len) { | |||
| if (s.size() <= len) | |||
| return s; | |||
| else | |||
| return s.substr(0, len - 3) + "..."; | |||
| } | |||
| bool startsWith(std::string str, std::string prefix) { | |||
| return str.substr(0, prefix.size()) == prefix; | |||
| } | |||
| std::string extractDirectory(std::string path) { | |||
| char *pathDup = strdup(path.c_str()); | |||
| std::string directory = dirname(pathDup); | |||
| free(pathDup); | |||
| return directory; | |||
| } | |||
| std::string extractFilename(std::string path) { | |||
| char *pathDup = strdup(path.c_str()); | |||
| std::string filename = basename(pathDup); | |||
| free(pathDup); | |||
| return filename; | |||
| } | |||
| std::string extractExtension(std::string path) { | |||
| const char *ext = strrchr(path.c_str(), '.'); | |||
| if (!ext) | |||
| return ""; | |||
| return ext + 1; | |||
| } | |||
| //////////////////// | |||
| // Operating system functions | |||
| //////////////////// | |||
| void openBrowser(std::string url) { | |||
| #if ARCH_LIN | |||
| std::string command = "xdg-open " + url; | |||
| (void)system(command.c_str()); | |||
| #endif | |||
| #if ARCH_MAC | |||
| std::string command = "open " + url; | |||
| system(command.c_str()); | |||
| #endif | |||
| #if ARCH_WIN | |||
| ShellExecute(NULL, "open", url.c_str(), NULL, NULL, SW_SHOWNORMAL); | |||
| #endif | |||
| } | |||
| //////////////////// | |||
| // logger | |||
| //////////////////// | |||
| FILE *gLogFile = stderr; | |||
| void debug(const char *format, ...) { | |||
| va_list args; | |||
| va_start(args, format); | |||
| fprintf(gLogFile, "[debug] "); | |||
| vfprintf(gLogFile, format, args); | |||
| fprintf(gLogFile, "\n"); | |||
| fflush(gLogFile); | |||
| va_end(args); | |||
| } | |||
| void info(const char *format, ...) { | |||
| va_list args; | |||
| va_start(args, format); | |||
| fprintf(gLogFile, "[info] "); | |||
| vfprintf(gLogFile, format, args); | |||
| fprintf(gLogFile, "\n"); | |||
| fflush(gLogFile); | |||
| va_end(args); | |||
| } | |||
| void warn(const char *format, ...) { | |||
| va_list args; | |||
| va_start(args, format); | |||
| fprintf(gLogFile, "[warning] "); | |||
| vfprintf(gLogFile, format, args); | |||
| fprintf(gLogFile, "\n"); | |||
| fflush(gLogFile); | |||
| va_end(args); | |||
| } | |||
| void fatal(const char *format, ...) { | |||
| va_list args; | |||
| va_start(args, format); | |||
| fprintf(gLogFile, "[fatal] "); | |||
| vfprintf(gLogFile, format, args); | |||
| fprintf(gLogFile, "\n"); | |||
| fflush(gLogFile); | |||
| va_end(args); | |||
| } | |||
| } // namespace rack | |||
| @@ -0,0 +1,51 @@ | |||
| #include "util/util.hpp" | |||
| #include <stdarg.h> | |||
| namespace rack { | |||
| FILE *gLogFile = stderr; | |||
| void debug(const char *format, ...) { | |||
| va_list args; | |||
| va_start(args, format); | |||
| fprintf(gLogFile, "[debug] "); | |||
| vfprintf(gLogFile, format, args); | |||
| fprintf(gLogFile, "\n"); | |||
| fflush(gLogFile); | |||
| va_end(args); | |||
| } | |||
| void info(const char *format, ...) { | |||
| va_list args; | |||
| va_start(args, format); | |||
| fprintf(gLogFile, "[info] "); | |||
| vfprintf(gLogFile, format, args); | |||
| fprintf(gLogFile, "\n"); | |||
| fflush(gLogFile); | |||
| va_end(args); | |||
| } | |||
| void warn(const char *format, ...) { | |||
| va_list args; | |||
| va_start(args, format); | |||
| fprintf(gLogFile, "[warning] "); | |||
| vfprintf(gLogFile, format, args); | |||
| fprintf(gLogFile, "\n"); | |||
| fflush(gLogFile); | |||
| va_end(args); | |||
| } | |||
| void fatal(const char *format, ...) { | |||
| va_list args; | |||
| va_start(args, format); | |||
| fprintf(gLogFile, "[fatal] "); | |||
| vfprintf(gLogFile, format, args); | |||
| fprintf(gLogFile, "\n"); | |||
| fflush(gLogFile); | |||
| va_end(args); | |||
| } | |||
| } // namespace rack | |||
| @@ -0,0 +1,72 @@ | |||
| #include "util/util.hpp" | |||
| #include <time.h> | |||
| #include <sys/time.h> | |||
| namespace rack { | |||
| // xoroshiro128+ | |||
| // from http://xoroshiro.di.unimi.it/xoroshiro128plus.c | |||
| static uint64_t xoroshiro128plus_state[2] = {}; | |||
| static uint64_t rotl(const uint64_t x, int k) { | |||
| return (x << k) | (x >> (64 - k)); | |||
| } | |||
| static uint64_t xoroshiro128plus_next(void) { | |||
| const uint64_t s0 = xoroshiro128plus_state[0]; | |||
| uint64_t s1 = xoroshiro128plus_state[1]; | |||
| const uint64_t result = s0 + s1; | |||
| s1 ^= s0; | |||
| xoroshiro128plus_state[0] = rotl(s0, 55) ^ s1 ^ (s1 << 14); // a, b | |||
| xoroshiro128plus_state[1] = rotl(s1, 36); // c | |||
| return result; | |||
| } | |||
| void randomInit() { | |||
| // Only allow the seed to be initialized once during the lifetime of the program. | |||
| assert(xoroshiro128plus_state[0] == 0 && xoroshiro128plus_state[1] == 0); | |||
| struct timeval tv; | |||
| gettimeofday(&tv, NULL); | |||
| xoroshiro128plus_state[0] = tv.tv_sec; | |||
| xoroshiro128plus_state[1] = tv.tv_usec; | |||
| // Generate a few times to fix the fact that the time is not a uniform u64 | |||
| for (int i = 0; i < 10; i++) { | |||
| xoroshiro128plus_next(); | |||
| } | |||
| } | |||
| uint32_t randomu32() { | |||
| return xoroshiro128plus_next() >> 32; | |||
| } | |||
| uint64_t randomu64() { | |||
| return xoroshiro128plus_next(); | |||
| } | |||
| float randomf() { | |||
| // 24 bits of granularity is the best that can be done with floats while ensuring that the return value lies in [0.0, 1.0). | |||
| return (xoroshiro128plus_next() >> (64 - 24)) / powf(2, 24); | |||
| } | |||
| float randomNormal() { | |||
| // Box-Muller transform | |||
| float radius = sqrtf(-2.f * logf(1.f - randomf())); | |||
| float theta = 2.f * M_PI * randomf(); | |||
| return radius * sinf(theta); | |||
| // // Central Limit Theorem | |||
| // const int n = 8; | |||
| // float sum = 0.0; | |||
| // for (int i = 0; i < n; i++) { | |||
| // sum += randomf(); | |||
| // } | |||
| // return (sum - n / 2.f) / sqrtf(n / 12.f); | |||
| } | |||
| } // namespace rack | |||
| @@ -1,8 +1,5 @@ | |||
| #include "util/util.hpp" | |||
| #include "util/request.hpp" | |||
| #include "util.hpp" | |||
| #include <assert.h> | |||
| #include <stdio.h> | |||
| #include <string.h> | |||
| #include <curl/curl.h> | |||
| #include <openssl/sha.h> | |||
| @@ -0,0 +1,70 @@ | |||
| #include "util/util.hpp" | |||
| #include <stdarg.h> | |||
| #include <algorithm> | |||
| #include <libgen.h> // for dirname and basename | |||
| namespace rack { | |||
| std::string stringf(const char *format, ...) { | |||
| va_list args; | |||
| va_start(args, format); | |||
| // Compute size of required buffer | |||
| int size = vsnprintf(NULL, 0, format, args); | |||
| va_end(args); | |||
| if (size < 0) | |||
| return ""; | |||
| // Create buffer | |||
| std::string s; | |||
| s.resize(size); | |||
| va_start(args, format); | |||
| vsnprintf(&s[0], size + 1, format, args); | |||
| va_end(args); | |||
| return s; | |||
| } | |||
| std::string lowercase(std::string s) { | |||
| std::transform(s.begin(), s.end(), s.begin(), ::tolower); | |||
| return s; | |||
| } | |||
| std::string uppercase(std::string s) { | |||
| std::transform(s.begin(), s.end(), s.begin(), ::toupper); | |||
| return s; | |||
| } | |||
| std::string ellipsize(std::string s, size_t len) { | |||
| if (s.size() <= len) | |||
| return s; | |||
| else | |||
| return s.substr(0, len - 3) + "..."; | |||
| } | |||
| bool startsWith(std::string str, std::string prefix) { | |||
| return str.substr(0, prefix.size()) == prefix; | |||
| } | |||
| std::string extractDirectory(std::string path) { | |||
| char *pathDup = strdup(path.c_str()); | |||
| std::string directory = dirname(pathDup); | |||
| free(pathDup); | |||
| return directory; | |||
| } | |||
| std::string extractFilename(std::string path) { | |||
| char *pathDup = strdup(path.c_str()); | |||
| std::string filename = basename(pathDup); | |||
| free(pathDup); | |||
| return filename; | |||
| } | |||
| std::string extractExtension(std::string path) { | |||
| const char *ext = strrchr(path.c_str(), '.'); | |||
| if (!ext) | |||
| return ""; | |||
| return ext + 1; | |||
| } | |||
| } // namespace rack | |||
| @@ -0,0 +1,27 @@ | |||
| #include "util/util.hpp" | |||
| #if ARCH_WIN | |||
| #include <windows.h> | |||
| #include <shellapi.h> | |||
| #endif | |||
| namespace rack { | |||
| void openBrowser(std::string url) { | |||
| #if ARCH_LIN | |||
| std::string command = "xdg-open " + url; | |||
| (void)system(command.c_str()); | |||
| #endif | |||
| #if ARCH_MAC | |||
| std::string command = "open " + url; | |||
| system(command.c_str()); | |||
| #endif | |||
| #if ARCH_WIN | |||
| ShellExecute(NULL, "open", url.c_str(), NULL, NULL, SW_SHOWNORMAL); | |||
| #endif | |||
| } | |||
| } // namespace rack | |||