/*
TessesFramework a library to make C++ easier for me, used in CrossLang:
https://git.tesses.org/tesses50/crosslang Copyright (C) 2026 Mike Nolan
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
#include "TessesFramework/Common.hpp"
#include "TessesFramework/Filesystem/FSHelpers.hpp"
#include "TessesFramework/Filesystem/LocalFS.hpp"
#include "TessesFramework/Lazy.hpp"
#include "TessesFramework/Platform/Environment.hpp"
#include "TessesFramework/Serialization/Json.hpp"
#include "TessesFramework/Streams/NetworkStream.hpp"
#include "TessesFramework/Text/StringConverter.hpp"
#include
#include
#include
#include
#include
#include
#include
#include
#if defined(__APPLE__)
// macOS, iOS, or other Darwin-based OS
#include
#if TARGET_OS_MAC && !TARGET_OS_IPHONE
#include
// Specifically macOS (not iOS, tvOS, watchOS)
#endif
#endif
#if defined(__FreeBSD__)
#include
#endif
#if defined(TESSESFRAMEWORK_ENABLE_SQLITE)
extern "C" {
#include "Serialization/sqlite/sqlite3.h"
}
#if defined(GEKKO) || defined(__SWITCH__) || defined(__PS2__)
extern "C" {
sqlite3_vfs *sqlite3_demovfs();
}
#endif
#endif
#if defined(_WIN32)
#include
#undef min
#include
#include
#elif defined(__SWITCH__)
extern "C" {
#include
}
#elif defined(GEKKO)
#include
#include
#include
#include
#include
#if defined(HW_RVL)
#if defined(TESSESFRAMEWORK_USE_WII_SOCKET)
#include
#endif
#include
#endif
static void *xfb = NULL;
static GXRModeObj *rmode = NULL;
#endif
#if !defined(_WIN32)
#include
#endif
namespace Tesses::Framework {
#if defined(TESSESFRAMEWORK_ENABLE_THREADING) && \
(defined(GEKKO) || defined(__SWITCH__))
namespace Threading {
extern void JoinAllThreads();
extern void LookForFinishedThreads();
} // namespace Threading
#endif
volatile static bool isRunningSig = true;
volatile static std::atomic isRunning;
volatile static std::atomic gaming_console_events = true;
#if defined(TESSESFRAMEWORK_ENABLE_THREADING)
Threading::Mutex timers_mtx;
Threading::Mutex invokings_mtx;
std::queue> invokings;
#endif
void TF_Invoke(std::function cb) {
#if defined(TESSESFRAMEWORK_ENABLE_THREADING)
invokings_mtx.Lock();
invokings.push(cb);
invokings_mtx.Unlock();
#else
cb();
#endif
}
void TF_Sleep(uint32_t sleepMS) {
#if defined(_WIN32)
Sleep((DWORD)sleepMS);
#else
struct timespec ts;
ts.tv_sec = (time_t)(sleepMS / 1000);
ts.tv_nsec = (sleepMS % 1000) * 1000000;
nanosleep(&ts, NULL);
#endif
}
void TF_ConnectToSelf(uint16_t port) {
Tesses::Framework::Streams::NetworkStream ns("127.0.0.1", port, false,
false, false);
}
bool TF_IsRunning() { return isRunning; }
static void _sigInt(int c) { isRunningSig = false; }
void TF_RunEventLoop() {
TF_InitEventLoop();
while (isRunning) {
TF_RunEventLoopItteration();
}
}
#if defined(__SWITCH__)
bool initedConsole = false;
PadState default_pad;
#endif
uint64_t ittr = 0;
static std::shared_ptr timer_handler =
std::make_shared();
std::shared_ptr
TF_Timer_Handler::Make(std::shared_ptr handler) {
auto timer = new TF_Timer_Handle(handler);
std::shared_ptr handle(timer);
#if defined(TESSESFRAMEWORK_ENABLE_THREADING)
timers_mtx.Lock();
#endif
handler->handles.push_back(handle);
#if defined(TESSESFRAMEWORK_ENABLE_THREADING)
timers_mtx.Unlock();
#endif
return handle;
}
std::shared_ptr TF_Timer() {
return TF_Timer_Handler::Make(timer_handler);
}
std::shared_ptr TF_Timer(std::function cb,
int64_t interval, bool enabled) {
auto handle = TF_Timer();
handle->SetCallback(cb);
handle->SetIntervalFromMilliseconds(interval);
handle->SetEnabled(enabled);
return handle;
}
std::shared_ptr
TF_Timer(std::function cb,
std::chrono::duration interval, bool enabled) {
auto handle = TF_Timer();
handle->SetCallback(cb);
handle->SetIntervalFromDuration(interval);
handle->SetEnabled(enabled);
return handle;
}
void TF_Timer_Handler::Update() {
std::chrono::time_point
cur = std::chrono::time_point_cast(
std::chrono::steady_clock::now());
std::vector> cbs;
#if defined(TESSESFRAMEWORK_ENABLE_THREADING)
timers_mtx.Lock();
#endif
for (auto index = this->handles.begin(); index != this->handles.end();
index++) {
if (index->expired()) {
this->handles.erase(index);
index--;
} else {
auto handle = index->lock();
if (handle && handle->enabled &&
(handle->last + handle->interval) <= cur && handle->cb) {
handle->last = cur;
cbs.push_back(handle->cb);
}
}
}
#if defined(TESSESFRAMEWORK_ENABLE_THREADING)
timers_mtx.Unlock();
#endif
for (auto item : cbs) {
item();
}
}
void TF_Timer_Handle::SetCallback(std::function cb) {
#if defined(TESSESFRAMEWORK_ENABLE_THREADING)
timers_mtx.Lock();
#endif
this->cb = cb;
#if defined(TESSESFRAMEWORK_ENABLE_THREADING)
timers_mtx.Unlock();
#endif
}
TF_Timer_Handle::TF_Timer_Handle(std::shared_ptr handler)
: timerHandler(handler) {}
void TF_Timer_Handle::SetEnabled(bool enabled) {
#if defined(TESSESFRAMEWORK_ENABLE_THREADING)
timers_mtx.Lock();
#endif
this->enabled = enabled;
#if defined(TESSESFRAMEWORK_ENABLE_THREADING)
timers_mtx.Unlock();
#endif
}
bool TF_Timer_Handle::GetEnabled() { return this->enabled; }
void TF_Timer_Handle::SetIntervalFromDuration(std::chrono::milliseconds ms) {
#if defined(TESSESFRAMEWORK_ENABLE_THREADING)
timers_mtx.Lock();
#endif
this->interval = ms;
#if defined(TESSESFRAMEWORK_ENABLE_THREADING)
timers_mtx.Unlock();
#endif
}
void TF_Timer_Handle::SetIntervalFromMilliseconds(int64_t ms) {
SetIntervalFromDuration(std::chrono::milliseconds(ms));
}
std::chrono::duration
TF_Timer_Handle::GetIntervalDuration() {
return this->interval;
}
int64_t TF_Timer_Handle::GetIntervalMilliseconds() {
return this->interval.count();
}
void TF_RunEventLoopItteration() {
#if defined(TESSESFRAMEWORK_ENABLE_THREADING) && \
(defined(GEKKO) || defined(__SWITCH__))
Tesses::Framework::Threading::LookForFinishedThreads();
#endif
#if defined(TESSESFRAMEWORK_ENABLE_THREADING)
invokings_mtx.Lock();
auto invokes = invokings;
invokings_mtx.Unlock();
while (!invokes.empty()) {
invokes.front()();
invokes.pop();
}
#endif
if (!isRunningSig)
isRunning = false;
#if defined(GEKKO)
if (gaming_console_events) {
PAD_ScanPads();
if (PAD_ButtonsDown(0) & PAD_BUTTON_START)
isRunning = false;
}
#elif defined(__SWITCH__)
if (gaming_console_events) {
if (!appletMainLoop())
isRunning = false;
padUpdate(&default_pad);
u64 kDown = padGetButtonsDown(&default_pad);
if (kDown & HidNpadButton_Plus)
isRunning = false;
if (initedConsole)
consoleUpdate(NULL);
}
#endif
#if defined(_WIN32)
MSG winMSG;
if (PeekMessage(&winMSG, NULL, WM_QUIT, WM_QUIT, 1)) {
isRunning = false;
}
#endif
timer_handler->Update();
}
void TF_SetIsRunning(bool _isRunning) { isRunning = _isRunning; }
void TF_Quit() {
isRunning = false;
#if defined(TESSESFRAMEWORK_ENABLE_THREADING) && \
(defined(GEKKO) || defined(__SWITCH__))
Tesses::Framework::Threading::JoinAllThreads();
#endif
}
void TF_InitEventLoop() {
signal(SIGINT, _sigInt);
signal(SIGTERM, _sigInt);
}
void TF_Init() {
#if defined(TESSESFRAMEWORK_ENABLE_SQLITE)
sqlite3_initialize();
#if defined(GEKKO) || defined(__SWITCH__) || defined(__PS2__)
sqlite3_vfs_register(sqlite3_demovfs(), 1);
#endif
#endif
tzset();
#if defined(_WIN32)
signal(SIGINT, _sigInt);
signal(SIGTERM, _sigInt);
#endif
isRunning = true;
#if defined(_WIN32)
WSADATA wsaData;
int iResult;
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed: %d\n", iResult);
return;
}
#elif defined(GEKKO)
fatInitDefault();
VIDEO_Init();
PAD_Init();
#if defined(HW_RVL)
#if defined(TESSESFRAMEWORK_USE_WII_SOCKET)
wiisocket_init();
#endif
WPAD_Init();
#endif
#elif defined(__SWITCH__)
padConfigureInput(1, HidNpadStyleSet_NpadStandard);
padInitializeDefault(&default_pad);
socketInitializeDefault();
// Initialize the default gamepad (which reads handheld mode inputs as well as
// the first connected controller)
#else
signal(SIGPIPE, SIG_IGN);
#endif
}
bool TF_GetConsoleEventsEnabled() { return gaming_console_events; }
void TF_SetConsoleEventsEnabled(bool flag) { gaming_console_events = flag; }
void TF_InitConsole() {
#if defined(GEKKO)
rmode = VIDEO_GetPreferredMode(NULL);
// Allocate memory for the display in the uncached region
xfb = MEM_K0_TO_K1(SYS_AllocateFramebuffer(rmode));
// Initialise the console, required for printf
console_init(xfb, 20, 20, rmode->fbWidth, rmode->xfbHeight,
rmode->fbWidth * VI_DISPLAY_PIX_SZ);
// SYS_STDIO_Report(true);
// Set up the video registers with the chosen mode
VIDEO_Configure(rmode);
// Tell the video hardware where our display memory is
VIDEO_SetNextFramebuffer(xfb);
// Make the display visible
VIDEO_SetBlack(false);
// Flush the video register changes to the hardware
VIDEO_Flush();
// Wait for Video setup to complete
VIDEO_WaitVSync();
if (rmode->viTVMode & VI_NON_INTERLACE)
VIDEO_WaitVSync();
// The console understands VT terminal escape codes
// This positions the cursor on row 2, column 0
// we can use variables for this with format codes too
// e.g. printf ("\x1b[%d;%dH", row, column );
printf("\x1b[2;0H");
#elif defined(__SWITCH__)
consoleInit(NULL);
initedConsole = true;
#endif
}
void TF_InitWithConsole() {
TF_Init();
TF_InitConsole();
#if defined(TESSESFRAMEWORK_LOGTOFILE)
printf("Enabled Logging\n");
#endif
}
#if defined(TESSESFRAMEWORK_LOGTOFILE)
#if defined(TESSESFRAMEWORK_ENABLE_THREADING)
Tesses::Framework::Threading::Mutex log_mtx;
#endif
void TF_Log(std::string txtToLog) {
#if defined(TESSESFRAMEWORK_ENABLE_THREADING)
log_mtx.Lock();
#endif
FILE *f = fopen("TF_Log.log", "a");
fprintf(f, "%s\n", txtToLog.c_str());
fclose(f);
#if defined(TESSESFRAMEWORK_ENABLE_THREADING)
log_mtx.Unlock();
#endif
}
#endif
static std::string TF_FileSizeBin(uint64_t bytes) {
if (bytes == 1)
return "1 Byte";
if (bytes < 1024ULL)
return std::to_string(bytes) + " Bytes";
if (bytes < 1024ULL * 1024ULL)
return std::to_string(bytes / 1024ULL) + " kiB";
if (bytes < 1024ULL * 1024ULL * 1024ULL)
return std::to_string(bytes / (1024ULL * 1024ULL)) + " MiB";
if (bytes < 1024ULL * 1024ULL * 1024ULL * 1024ULL)
return std::to_string(bytes / (1024ULL * 1024ULL * 1024ULL)) + " GiB";
if (bytes < 1024ULL * 1024ULL * 1024ULL * 1024ULL * 1024ULL)
return std::to_string(bytes / (1024ULL * 1024ULL * 1024ULL * 1024ULL)) +
" TiB";
return std::to_string(bytes /
(1024ULL * 1024ULL * 1024ULL * 1024ULL * 1024ULL)) +
" PiB";
}
static std::string TF_FileSizeDec(uint64_t bytes) {
if (bytes == 1)
return "1 Byte";
if (bytes < 1000ULL)
return std::to_string(bytes) + " Bytes";
if (bytes < 1000ULL * 1000ULL)
return std::to_string(bytes / 1000ULL) + " kB";
if (bytes < 1000ULL * 1000ULL * 1000ULL)
return std::to_string(bytes / (1000ULL * 1000ULL)) + " MB";
if (bytes < 1000ULL * 1000ULL * 1000ULL * 1000ULL)
return std::to_string(bytes / (1000ULL * 1000ULL * 1000ULL)) + " GB";
if (bytes < 1000ULL * 1000ULL * 1000ULL * 1000ULL * 1000ULL)
return std::to_string(bytes / (1000ULL * 1000ULL * 1000ULL * 1000ULL)) +
" TB";
return std::to_string(bytes /
(1000ULL * 1000ULL * 1000ULL * 1000ULL * 1000ULL)) +
" PB";
}
std::string TF_FileSize(uint64_t bytes, bool usesBin) {
return usesBin ? TF_FileSizeBin(bytes) : TF_FileSizeDec(bytes);
}
std::optional _argv0 = std::nullopt;
std::string TF_GetExecutableName() {
#if defined(_WIN32)
std::u16string str;
str.resize(MAX_PATH);
// GetModuleFileName with NULL gets the current executable's path
DWORD result = GetModuleFileNameW(NULL, (LPWSTR)str.data(), MAX_PATH);
if (result > 0 && result < MAX_PATH) {
str.resize(result);
std::string path;
Text::StringConverter::UTF8::FromUTF16(path, str);
return path;
}
#elif defined(__linux__)
auto path =
Filesystem::LocalFS->ReadLink((Filesystem::VFSPath) "/proc/self/exe");
return path.ToString();
#elif defined(__FreeBSD__)
int mib[4];
size_t len = 0;
mib[0] = CTL_KERN;
mib[1] = KERN_PROC;
mib[2] = KERN_PROC_PATHNAME;
mib[3] = -1;
if (sysctl(mib, 4, NULL, &len, NULL, 0) < 0) {
return "";
}
std::string path;
path.resize(len);
if (sysctl(mib, 4, path.data(), &len, NULL, 0) < 0) {
return "";
}
path.resize(len-1);
return path;
#elif defined(__NetBSD__)
auto path = Filesystem::LocalFS->ReadLink(
(Filesystem::VFSPath) "/proc/curproc/exe");
return path.ToString();
#elif defined( \
__DragonFly__) // platform doesn't work due to std::filesystem issues
auto path = Filesystem::LocalFS->ReadLink(
(Filesystem::VFSPath) "/proc/curproc/file");
return path.ToString();
#elif TARGET_OS_MAC && !TARGET_OS_IPHONE
std::string path;
path.resize(1025);
uint32_t bufsize = (uint32_t)path.size();
if (_NSGetExecutablePath(path.data(), &bufsize) == 0) {
path.resize(bufsize-1);
return path;
} else {
path.resize(bufsize);
if (_NSGetExecutablePath(path.data(), &bufsize) == 0)
{
path.resize(bufsize-1);
return path;
}
}
#endif
return "";
}
void TF_AllowPortable() {
std::string path = TF_GetExecutableName();
if (!path.empty())
TF_AllowPortable(path);
}
void TF_AllowPortable(std::string argv0) {
using namespace Tesses::Framework::Serialization::Json;
using namespace Tesses::Framework::Platform::Environment;
using namespace Tesses::Framework::Filesystem;
_argv0 = argv0;
VFSPath path(argv0);
auto realPath = path.MakeAbsolute();
auto dir = realPath.GetParent();
auto portable = dir / "portable.json";
if (LocalFS->FileExists(portable)) {
std::string portable_str;
Helpers::ReadAllText(LocalFS, portable, portable_str);
auto jsonObj = Json::Decode(portable_str);
JObject dict;
JObject dict2;
if (TryGetJToken(jsonObj, dict) &&
dict.TryGetValueAsType("portable_data", dict2)) {
if (dict.TryGetValueAsType("portable_type", portable_str)) {
if (portable_str == "PortableApps.com") {
// do the special stuffs for PortableApps.com based apps
auto paf_documents =
GetVariable("PortableApps.comDocuments");
auto paf_music = GetVariable("PortableApps.comMusic");
auto paf_pictures = GetVariable("PortableApps.comPictures");
auto paf_videos = GetVariable("PortableApps.comVideos");
auto paf_data = GetVariable("PAL:DataDir");
bool bV = false;
if (!dict2.TryGetValueAsType("system_documents", bV) ||
!bV) {
if (paf_documents) {
portable_config.documents =
LocalFS->SystemToVFSPath(*paf_documents);
}
}
if (!dict2.TryGetValueAsType("system_pictures", bV) ||
!bV) {
if (paf_pictures) {
portable_config.pictures =
LocalFS->SystemToVFSPath(*paf_pictures);
}
}
if (!dict2.TryGetValueAsType("system_videos", bV) || !bV) {
if (paf_videos) {
portable_config.videos =
LocalFS->SystemToVFSPath(*paf_videos);
}
}
if (!dict2.TryGetValueAsType("system_music", bV) || !bV) {
if (paf_music) {
portable_config.music =
LocalFS->SystemToVFSPath(*paf_music);
}
}
if (dict2.TryGetValueAsType("user", portable_str)) {
if (portable_str == "app") {
if (paf_data)
portable_config.user =
LocalFS->SystemToVFSPath(*paf_data) /
"TF_User";
} else if (portable_str == "documents") {
if (paf_documents)
portable_config.user =
LocalFS->SystemToVFSPath(*paf_documents) /
"TF_User";
}
}
if (dict2.TryGetValueAsType("desktop", portable_str)) {
if (portable_str == "tf_user") {
if (portable_config.user)
portable_config.desktop =
*(portable_config.user) / "Desktop";
} else if (portable_str == "documents") {
if (paf_documents)
portable_config.desktop =
LocalFS->SystemToVFSPath(*paf_documents) /
"Desktop";
}
}
if (dict2.TryGetValueAsType("downloads", portable_str)) {
if (portable_str == "tf_user") {
if (portable_config.user)
portable_config.downloads =
*(portable_config.user) / "Downloads";
} else if (portable_str == "documents") {
if (paf_documents)
portable_config.downloads =
LocalFS->SystemToVFSPath(*paf_documents) /
"Downloads";
}
}
if (!dict2.TryGetValueAsType("system_config", bV) || !bV) {
if (portable_config.user)
portable_config.config =
*(portable_config.user) / "Config";
}
if (!dict2.TryGetValueAsType("system_cache", bV) || !bV) {
if (portable_config.user)
portable_config.cache =
*(portable_config.user) / "Cache";
}
if (!dict2.TryGetValueAsType("system_data", bV) || !bV) {
if (portable_config.user)
portable_config.data =
*(portable_config.user) / "Data";
}
if (!dict2.TryGetValueAsType("system_state", bV) || !bV) {
if (portable_config.user)
portable_config.state =
*(portable_config.user) / "State";
}
if (!dict2.TryGetValueAsType("system_temp", bV) || !bV) {
if (portable_config.user)
portable_config.temp =
*(portable_config.user) / "Temp";
}
} else if (portable_str == "relative") {
if (dict2.TryGetValueAsType("user", portable_str)) {
if (portable_str != "system") {
auto userDir = dir / portable_str;
portable_config.user =
userDir.CollapseRelativeParents();
}
}
if (dict2.TryGetValueAsType("documents", portable_str)) {
if (portable_str != "system") {
if (portable_str == "default") {
if (portable_config.user) {
portable_config.documents =
*(portable_config.user) / "Documents";
}
} else {
auto userDir = dir / portable_str;
portable_config.documents =
userDir.CollapseRelativeParents();
}
}
}
if (dict2.TryGetValueAsType("downloads", portable_str)) {
if (portable_str != "system") {
if (portable_str == "default") {
if (portable_config.user) {
portable_config.downloads =
*(portable_config.user) / "Downloads";
}
} else {
auto userDir = dir / portable_str;
portable_config.downloads =
userDir.CollapseRelativeParents();
}
}
}
if (dict2.TryGetValueAsType("desktop", portable_str)) {
if (portable_str != "system") {
if (portable_str == "default") {
if (portable_config.user) {
portable_config.desktop =
*(portable_config.user) / "Desktop";
}
} else {
auto userDir = dir / portable_str;
portable_config.desktop =
userDir.CollapseRelativeParents();
}
}
}
if (dict2.TryGetValueAsType("pictures", portable_str)) {
if (portable_str != "system") {
if (portable_str == "default") {
if (portable_config.user) {
portable_config.pictures =
*(portable_config.user) / "Pictures";
}
} else {
auto userDir = dir / portable_str;
portable_config.pictures =
userDir.CollapseRelativeParents();
}
}
}
if (dict2.TryGetValueAsType("videos", portable_str)) {
if (portable_str != "system") {
if (portable_str == "default") {
if (portable_config.user) {
portable_config.videos =
*(portable_config.user) / "Videos";
}
} else {
auto userDir = dir / portable_str;
portable_config.videos =
userDir.CollapseRelativeParents();
}
}
}
if (dict2.TryGetValueAsType("music", portable_str)) {
if (portable_str != "system") {
if (portable_str == "default") {
if (portable_config.user) {
portable_config.music =
*(portable_config.user) / "Music";
}
} else {
auto userDir = dir / portable_str;
portable_config.music =
userDir.CollapseRelativeParents();
}
}
}
if (dict2.TryGetValueAsType("config", portable_str)) {
if (portable_str != "system") {
if (portable_str == "default") {
if (portable_config.user) {
portable_config.config =
*(portable_config.user) / "Config";
}
} else {
auto userDir = dir / portable_str;
portable_config.config =
userDir.CollapseRelativeParents();
}
}
}
if (dict2.TryGetValueAsType("cache", portable_str)) {
if (portable_str != "system") {
if (portable_str == "default") {
if (portable_config.user) {
portable_config.cache =
*(portable_config.user) / "Cache";
}
} else {
auto userDir = dir / portable_str;
portable_config.cache =
userDir.CollapseRelativeParents();
}
}
}
if (dict2.TryGetValueAsType("data", portable_str)) {
if (portable_str != "system") {
if (portable_str == "default") {
if (portable_config.user) {
portable_config.data =
*(portable_config.user) / "Data";
}
} else {
auto userDir = dir / portable_str;
portable_config.data =
userDir.CollapseRelativeParents();
}
}
}
if (dict2.TryGetValueAsType("state", portable_str)) {
if (portable_str != "system") {
if (portable_str == "default") {
if (portable_config.user) {
portable_config.state =
*(portable_config.user) / "State";
}
} else {
auto userDir = dir / portable_str;
portable_config.state =
userDir.CollapseRelativeParents();
}
}
}
if (dict2.TryGetValueAsType("temp", portable_str)) {
if (portable_str != "system") {
if (portable_str == "default") {
if (portable_config.user) {
portable_config.temp =
*(portable_config.user) / "Temp";
}
} else {
auto userDir = dir / portable_str;
portable_config.temp =
userDir.CollapseRelativeParents();
}
}
}
} else if (portable_str == "absolute") {
if (dict2.TryGetValueAsType("user", portable_str)) {
if (portable_str != "system") {
VFSPath userDir = portable_str;
portable_config.user =
userDir.CollapseRelativeParents();
}
}
if (dict2.TryGetValueAsType("documents", portable_str)) {
if (portable_str != "system") {
if (portable_str == "default") {
if (portable_config.user) {
portable_config.documents =
*(portable_config.user) / "Documents";
}
} else {
VFSPath userDir = portable_str;
portable_config.documents =
userDir.CollapseRelativeParents();
}
}
}
if (dict2.TryGetValueAsType("downloads", portable_str)) {
if (portable_str != "system") {
if (portable_str == "default") {
if (portable_config.user) {
portable_config.downloads =
*(portable_config.user) / "Downloads";
}
} else {
VFSPath userDir = portable_str;
portable_config.downloads =
userDir.CollapseRelativeParents();
}
}
}
if (dict2.TryGetValueAsType("desktop", portable_str)) {
if (portable_str != "system") {
if (portable_str == "default") {
if (portable_config.user) {
portable_config.desktop =
*(portable_config.user) / "Desktop";
}
} else {
VFSPath userDir = portable_str;
portable_config.desktop =
userDir.CollapseRelativeParents();
}
}
}
if (dict2.TryGetValueAsType("pictures", portable_str)) {
if (portable_str != "system") {
if (portable_str == "default") {
if (portable_config.user) {
portable_config.pictures =
*(portable_config.user) / "Pictures";
}
} else {
VFSPath userDir = portable_str;
portable_config.pictures =
userDir.CollapseRelativeParents();
}
}
}
if (dict2.TryGetValueAsType("videos", portable_str)) {
if (portable_str != "system") {
if (portable_str == "default") {
if (portable_config.user) {
portable_config.videos =
*(portable_config.user) / "Videos";
}
} else {
VFSPath userDir = portable_str;
portable_config.videos =
userDir.CollapseRelativeParents();
}
}
}
if (dict2.TryGetValueAsType("music", portable_str)) {
if (portable_str != "system") {
if (portable_str == "default") {
if (portable_config.user) {
portable_config.music =
*(portable_config.user) / "Music";
}
} else {
VFSPath userDir = portable_str;
portable_config.music =
userDir.CollapseRelativeParents();
}
}
}
if (dict2.TryGetValueAsType("config", portable_str)) {
if (portable_str != "system") {
if (portable_str == "default") {
if (portable_config.user) {
portable_config.config =
*(portable_config.user) / "Config";
}
} else {
VFSPath userDir = portable_str;
portable_config.config =
userDir.CollapseRelativeParents();
}
}
}
if (dict2.TryGetValueAsType("cache", portable_str)) {
if (portable_str != "system") {
if (portable_str == "default") {
if (portable_config.user) {
portable_config.cache =
*(portable_config.user) / "Cache";
}
} else {
VFSPath userDir = portable_str;
portable_config.cache =
userDir.CollapseRelativeParents();
}
}
}
if (dict2.TryGetValueAsType("data", portable_str)) {
if (portable_str != "system") {
if (portable_str == "default") {
if (portable_config.user) {
portable_config.data =
*(portable_config.user) / "Data";
}
} else {
VFSPath userDir = portable_str;
portable_config.data =
userDir.CollapseRelativeParents();
}
}
}
if (dict2.TryGetValueAsType("state", portable_str)) {
if (portable_str != "system") {
if (portable_str == "default") {
if (portable_config.user) {
portable_config.state =
*(portable_config.user) / "State";
}
} else {
VFSPath userDir = portable_str;
portable_config.state =
userDir.CollapseRelativeParents();
}
}
}
if (dict2.TryGetValueAsType("temp", portable_str)) {
if (portable_str != "system") {
if (portable_str == "default") {
if (portable_config.user) {
portable_config.temp =
*(portable_config.user) / "Temp";
}
} else {
VFSPath userDir = portable_str;
portable_config.temp =
userDir.CollapseRelativeParents();
}
}
}
}
}
}
}
}
} // namespace Tesses::Framework