Skip to content

Commit

Permalink
UI: Rewrite scene collection system to enable user-provided storage
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
PatTheMav authored and RytoEX committed Sep 12, 2024
1 parent 607d37b commit 3e0592d
Show file tree
Hide file tree
Showing 6 changed files with 663 additions and 427 deletions.
21 changes: 8 additions & 13 deletions UI/api-interface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ template<typename T> static T GetOBSRef(QListWidgetItem *item)
return item->data(static_cast<int>(QtDataRole::OBSRef)).value<T>();
}

void EnumSceneCollections(function<bool(const char *, const char *)> &&cb);

extern volatile bool streaming_active;
extern volatile bool recording_active;
extern volatile bool recording_paused;
Expand Down Expand Up @@ -168,19 +166,17 @@ struct OBSStudioAPI : obs_frontend_callbacks {
void obs_frontend_get_scene_collections(
std::vector<std::string> &strings) override
{
auto addCollection = [&](const char *name, const char *) {
strings.emplace_back(name);
return true;
};

EnumSceneCollections(addCollection);
for (auto &[collectionName, collection] :
main->GetSceneCollectionCache()) {
strings.emplace_back(collectionName);
}
}

char *obs_frontend_get_current_scene_collection(void) override
{
const char *cur_name = config_get_string(
App()->GlobalConfig(), "Basic", "SceneCollection");
return bstrdup(cur_name);
const OBSSceneCollection &currentCollection =
main->GetCurrentSceneCollection();
return bstrdup(currentCollection.name.c_str());
}

void obs_frontend_set_current_scene_collection(
Expand All @@ -206,10 +202,9 @@ struct OBSStudioAPI : obs_frontend_callbacks {
bool obs_frontend_add_scene_collection(const char *name) override
{
bool success = false;
QMetaObject::invokeMethod(main, "AddSceneCollection",
QMetaObject::invokeMethod(main, "NewSceneCollection",
WaitConnection(),
Q_RETURN_ARG(bool, success),
Q_ARG(bool, true),
Q_ARG(QString, QT_UTF8(name)));
return success;
}
Expand Down
75 changes: 33 additions & 42 deletions UI/obs-app.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1220,27 +1220,48 @@ static void move_basic_to_profiles(void)
static void move_basic_to_scene_collections(void)
{
char path[512];
char new_path[512];

if (GetConfigPath(path, 512, "obs-studio/basic") <= 0)
return;
if (!os_file_exists(path))
if (GetAppConfigPath(path, 512, "obs-studio/basic") <= 0) {
return;
}

const std::filesystem::path basicPath = std::filesystem::u8path(path);

if (GetConfigPath(new_path, 512, "obs-studio/basic/scenes") <= 0)
if (!std::filesystem::exists(basicPath)) {
return;
if (os_file_exists(new_path))
}

const std::filesystem::path sceneCollectionPath =
App()->userScenesLocation /
std::filesystem::u8path("obs-studio/basic/scenes");

if (std::filesystem::exists(sceneCollectionPath)) {
return;
}

if (os_mkdir(new_path) == MKDIR_ERROR)
try {
std::filesystem::create_directories(sceneCollectionPath);
} catch (const std::filesystem::filesystem_error &error) {
blog(LOG_ERROR,
"Failed to create scene collection directory for migration from basic scene collection\n%s",
error.what());
return;
}

strcat(path, "/scenes.json");
strcat(new_path, "/");
strcat(new_path, Str("Untitled"));
strcat(new_path, ".json");
const std::filesystem::path sourceFile =
basicPath / std::filesystem::u8path("scenes.json");
const std::filesystem::path destinationFile =
(sceneCollectionPath / std::filesystem::u8path(Str("Untitled")))
.replace_extension(".json");

os_rename(path, new_path);
try {
std::filesystem::rename(sourceFile, destinationFile);
} catch (const std::filesystem::filesystem_error &error) {
blog(LOG_ERROR,
"Failed to rename basic scene collection file:\n%s",
error.what());
return;
}
}

void OBSApp::AppInit()
Expand Down Expand Up @@ -2524,36 +2545,6 @@ bool GetClosestUnusedFileName(std::string &path, const char *extension)
return true;
}

bool GetUnusedSceneCollectionFile(std::string &name, std::string &file)
{
char path[512];
int ret;

if (!GetFileSafeName(name.c_str(), file)) {
blog(LOG_WARNING, "Failed to create safe file name for '%s'",
name.c_str());
return false;
}

ret = GetConfigPath(path, sizeof(path), "obs-studio/basic/scenes/");
if (ret <= 0) {
blog(LOG_WARNING, "Failed to get scene collection config path");
return false;
}

file.insert(0, path);

if (!GetClosestUnusedFileName(file, "json")) {
blog(LOG_WARNING, "Failed to get closest file name for %s",
file.c_str());
return false;
}

file.erase(file.size() - 5, 5);
file.erase(0, strlen(path));
return true;
}

bool WindowPositionValid(QRect rect)
{
for (QScreen *screen : QGuiApplication::screens()) {
Expand Down
Loading

0 comments on commit 3e0592d

Please sign in to comment.