UI: Rewrite scene collection system to enable user-provided storage

This change enables loading scene collections from locations different
than OBS' own configuration directory.

It also rewrites profile management in the app to work off an in-memory
collection of profiles found on disk and does not require iterating
over directory contents for most profile interactions by the app.
This commit is contained in:
PatTheMav
2024-09-03 16:29:58 +02:00
committed by Ryan Foster
parent 607d37b423
commit 3e0592dc20
6 changed files with 711 additions and 475 deletions

View File

@@ -2332,29 +2332,13 @@ void OBSBasic::OBSInit()
{
ProfileScope("OBSBasic::OBSInit");
const char *sceneCollection = config_get_string(
App()->GlobalConfig(), "Basic", "SceneCollectionFile");
char savePath[1024];
char fileName[1024];
int ret;
if (!sceneCollection)
throw "Failed to get scene collection name";
ret = snprintf(fileName, sizeof(fileName),
"obs-studio/basic/scenes/%s.json", sceneCollection);
if (ret <= 0)
throw "Failed to create scene collection file name";
ret = GetConfigPath(savePath, sizeof(savePath), fileName);
if (ret <= 0)
throw "Failed to get scene collection json file path";
if (!InitBasicConfig())
throw "Failed to load basic.ini";
if (!ResetAudio())
throw "Failed to initialize audio";
int ret = 0;
ret = ResetVideo();
switch (ret) {
@@ -2401,6 +2385,12 @@ void OBSBasic::OBSInit()
AddExtraModulePaths();
}
/* Modules can access frontend information (i.e. profile and scene collection data) during their initialization, and some modules (e.g. obs-websockets) are known to use the filesystem location of the current profile in their own code.
Thus the profile and scene collection discovery needs to happen before any access to that information (but after intializing global settings) to ensure legacy code gets valid path information.
*/
RefreshSceneCollections(true);
blog(LOG_INFO, "---------------------------------");
obs_load_all_modules2(&mfi);
blog(LOG_INFO, "---------------------------------");
@@ -2482,7 +2472,19 @@ void OBSBasic::OBSInit()
{
ProfileScope("OBSBasic::Load");
disableSaving--;
Load(savePath);
try {
const OBSSceneCollection &currentCollection =
GetCurrentSceneCollection();
ActivateSceneCollection(currentCollection);
} catch (const std::invalid_argument &) {
const std::string collectionName =
config_get_string(App()->GetUserConfig(),
"Basic", "SceneCollection");
SetupNewSceneCollection(collectionName);
}
disableSaving++;
}
@@ -2500,7 +2502,6 @@ void OBSBasic::OBSInit()
Qt::QueuedConnection,
Q_ARG(bool, true));
RefreshSceneCollections();
disableSaving--;
auto addDisplay = [this](OBSQTDisplay *window) {
@@ -3411,26 +3412,14 @@ void OBSBasic::SaveProjectDeferred()
projectChanged = false;
const char *sceneCollection = config_get_string(
App()->GlobalConfig(), "Basic", "SceneCollectionFile");
try {
const OBSSceneCollection &currentCollection =
GetCurrentSceneCollection();
char savePath[1024];
char fileName[1024];
int ret;
if (!sceneCollection)
return;
ret = snprintf(fileName, sizeof(fileName),
"obs-studio/basic/scenes/%s.json", sceneCollection);
if (ret <= 0)
return;
ret = GetConfigPath(savePath, sizeof(savePath), fileName);
if (ret <= 0)
return;
Save(savePath);
Save(currentCollection.collectionFile.u8string().c_str());
} catch (const std::invalid_argument &error) {
blog(LOG_ERROR, "%s", error.what());
}
}
OBSSource OBSBasic::GetProgramSource()