@@ -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 |