@@ -1,6 +1,6 @@ | |||||
#pragma once | #pragma once | ||||
#include <vector> | #include <vector> | ||||
#include "util.hpp" | |||||
#include "util/util.hpp" | |||||
#include <jansson.h> | #include <jansson.h> | ||||
@@ -1,6 +1,6 @@ | |||||
#pragma once | #pragma once | ||||
#include "util.hpp" | |||||
#include "util/util.hpp" | |||||
#include <queue> | #include <queue> | ||||
#include <vector> | #include <vector> | ||||
#include <jansson.h> | #include <jansson.h> | ||||
@@ -1,7 +1,6 @@ | |||||
#pragma once | #pragma once | ||||
#include "util.hpp" | |||||
#include "util/math.hpp" | |||||
#include "util/util.hpp" | |||||
#include "asset.hpp" | #include "asset.hpp" | ||||
#include "plugin.hpp" | #include "plugin.hpp" | ||||
#include "engine.hpp" | #include "engine.hpp" | ||||
@@ -1,5 +1,4 @@ | |||||
#pragma once | #pragma once | ||||
#include <stdint.h> | #include <stdint.h> | ||||
#include <stdlib.h> | #include <stdlib.h> | ||||
#include <cmath> | #include <cmath> | ||||
@@ -1,5 +1,4 @@ | |||||
#pragma once | #pragma once | ||||
#include <string> | #include <string> | ||||
#include <jansson.h> | #include <jansson.h> | ||||
@@ -18,7 +17,10 @@ enum RequestMethod { | |||||
json_t *requestJson(RequestMethod method, std::string url, json_t *dataJ); | json_t *requestJson(RequestMethod method, std::string url, json_t *dataJ); | ||||
/** Returns the filename, blank if unsuccessful */ | /** Returns the filename, blank if unsuccessful */ | ||||
bool requestDownload(std::string url, std::string filename, float *progress); | bool requestDownload(std::string url, std::string filename, float *progress); | ||||
/** URL-encodes `s` */ | |||||
std::string requestEscape(std::string s); | std::string requestEscape(std::string s); | ||||
/** Computes the SHA256 of the file at `filename` */ | |||||
std::string requestSHA256File(std::string filename); | std::string requestSHA256File(std::string filename); | ||||
} // namespace rack | } // namespace rack |
@@ -4,12 +4,15 @@ | |||||
#include <stdlib.h> | #include <stdlib.h> | ||||
#include <stdio.h> | #include <stdio.h> | ||||
#include <stdint.h> | #include <stdint.h> | ||||
#include <string.h> | |||||
#include <assert.h> | #include <assert.h> | ||||
#include <string> | #include <string> | ||||
#include <condition_variable> | #include <condition_variable> | ||||
#include <mutex> | #include <mutex> | ||||
#include "util/math.hpp" | |||||
/** Surrounds raw text with quotes | /** Surrounds raw text with quotes | ||||
Example: | Example: | ||||
@@ -63,6 +66,55 @@ T *construct(F f, V v, Args... args) { | |||||
return o; | 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 | // 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 | } // namespace rack |
@@ -6,9 +6,7 @@ | |||||
#include "../ext/oui-blendish/blendish.h" | #include "../ext/oui-blendish/blendish.h" | ||||
#include "../ext/nanosvg/src/nanosvg.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" | #include "events.hpp" | ||||
@@ -1,5 +1,5 @@ | |||||
#include "asset.hpp" | #include "asset.hpp" | ||||
#include "util.hpp" | |||||
#include "util/util.hpp" | |||||
#include <assert.h> | #include <assert.h> | ||||
#include <sys/stat.h> // for mkdir | #include <sys/stat.h> // for mkdir | ||||
#include "../ext/osdialog/osdialog.h" | #include "../ext/osdialog/osdialog.h" | ||||
@@ -1,4 +1,4 @@ | |||||
#include "util.hpp" | |||||
#include "util/util.hpp" | |||||
#include "util/math.hpp" | #include "util/math.hpp" | ||||
#include "audio.hpp" | #include "audio.hpp" | ||||
@@ -10,7 +10,6 @@ | |||||
#include <pmmintrin.h> | #include <pmmintrin.h> | ||||
#include "engine.hpp" | #include "engine.hpp" | ||||
#include "util.hpp" | |||||
namespace rack { | namespace rack { | ||||
@@ -1,3 +1,4 @@ | |||||
#include "util/util.hpp" | |||||
#include "engine.hpp" | #include "engine.hpp" | ||||
#include "gui.hpp" | #include "gui.hpp" | ||||
#include "app.hpp" | #include "app.hpp" | ||||
@@ -1,4 +1,3 @@ | |||||
#include "util.hpp" | |||||
#include <stdarg.h> | #include <stdarg.h> | ||||
#include <string.h> | #include <string.h> | ||||
#include <random> | #include <random> | ||||
@@ -10,202 +9,3 @@ | |||||
#include <windows.h> | #include <windows.h> | ||||
#include <shellapi.h> | #include <shellapi.h> | ||||
#endif | #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/request.hpp" | ||||
#include "util.hpp" | |||||
#include <assert.h> | |||||
#include <stdio.h> | |||||
#include <string.h> | |||||
#include <curl/curl.h> | #include <curl/curl.h> | ||||
#include <openssl/sha.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 |