diff --git a/frontend/OBSStudioAPI.cpp b/frontend/OBSStudioAPI.cpp index 7e8ab72bb9eff3..d5aefcffd009bf 100644 --- a/frontend/OBSStudioAPI.cpp +++ b/frontend/OBSStudioAPI.cpp @@ -664,8 +664,8 @@ void OBSStudioAPI::obs_frontend_add_undo_redo_action(const char *name, const und void OBSStudioAPI::obs_frontend_get_canvases(obs_frontend_canvas_list *canvas_list) { - for (const auto &canvas : main->canvases) { - obs_canvas_t *ref = obs_canvas_get_ref(canvas); + for (const auto &kv : main->canvases) { + obs_canvas_t *ref = obs_canvas_get_ref(kv.first); if (ref) da_push_back(canvas_list->canvases, &ref); } @@ -674,7 +674,7 @@ void OBSStudioAPI::obs_frontend_get_canvases(obs_frontend_canvas_list *canvas_li obs_canvas_t *OBSStudioAPI::obs_frontend_add_canvas(const char *name, obs_video_info *ovi, int flags) { auto &canvas = main->AddCanvas(std::string(name), ovi, flags); - return obs_canvas_get_ref(canvas); + return obs_canvas_get_ref(canvas->canvas); } bool OBSStudioAPI::obs_frontend_remove_canvas(obs_canvas_t *canvas) diff --git a/frontend/settings/OBSBasicSettings_Stream.cpp b/frontend/settings/OBSBasicSettings_Stream.cpp index ce74a1cb1babf4..df570ffee5252a 100644 --- a/frontend/settings/OBSBasicSettings_Stream.cpp +++ b/frontend/settings/OBSBasicSettings_Stream.cpp @@ -173,10 +173,11 @@ void OBSBasicSettings::LoadStream1Settings() ui->multitrackVideoAdditionalCanvas->clear(); ui->multitrackVideoAdditionalCanvas->addItem(QTStr("None")); for (const auto &canvas : main->GetCanvases()) { - if (obs_canvas_get_flags(canvas) & EPHEMERAL) + if (obs_canvas_get_flags(canvas.first) & EPHEMERAL) continue; - ui->multitrackVideoAdditionalCanvas->addItem(obs_canvas_get_name(canvas), obs_canvas_get_uuid(canvas)); + ui->multitrackVideoAdditionalCanvas->addItem(obs_canvas_get_name(canvas.first), + obs_canvas_get_uuid(canvas.first)); } if (config_has_user_value(main->Config(), "Stream1", "MultitrackExtraCanvas")) { diff --git a/frontend/utility/OBSCanvas.cpp b/frontend/utility/OBSCanvas.cpp index d7c19e53ecfd7d..b8144d833dea42 100644 --- a/frontend/utility/OBSCanvas.cpp +++ b/frontend/utility/OBSCanvas.cpp @@ -23,11 +23,6 @@ namespace OBS { Canvas::Canvas(obs_canvas_t *canvas) : canvas(canvas) {} -Canvas::Canvas(Canvas &&other) noexcept -{ - canvas = std::exchange(other.canvas, nullptr); -} - Canvas::~Canvas() noexcept { if (!canvas) @@ -38,13 +33,6 @@ Canvas::~Canvas() noexcept canvas = nullptr; } -Canvas &Canvas::operator=(Canvas &&other) noexcept -{ - canvas = std::exchange(other.canvas, canvas); - - return *this; -} - std::optional Canvas::Save() const { if (!canvas) @@ -55,37 +43,37 @@ std::optional Canvas::Save() const return std::nullopt; } -std::unique_ptr Canvas::Load(obs_data_t *data) +std::shared_ptr Canvas::Load(obs_data_t *data) { if (OBSDataAutoRelease canvas_data = obs_data_get_obj(data, "info")) { if (obs_canvas_t *canvas = obs_load_canvas(canvas_data)) { - return std::make_unique(canvas); + return std::make_shared(canvas); } } return nullptr; } -std::vector Canvas::LoadCanvases(obs_data_array_t *canvases) +std::map> Canvas::LoadCanvases(obs_data_array_t *canvases) { auto cb = [](obs_data_t *data, void *param) -> void { - auto vec = static_cast *>(param); + auto vec = static_cast> *>(param); if (auto canvas = Canvas::Load(data)) - vec->emplace_back(std::move(*canvas)); + (*vec)[canvas->canvas] = canvas; }; - std::vector ret; + std::map> ret; obs_data_array_enum(canvases, cb, &ret); return ret; } -OBSDataArrayAutoRelease Canvas::SaveCanvases(const std::vector &canvases) +OBSDataArrayAutoRelease Canvas::SaveCanvases(const std::map> &canvases) { OBSDataArrayAutoRelease savedCanvases = obs_data_array_create(); - for (auto &canvas : canvases) { - auto canvas_data = canvas.Save(); + for (auto kv : canvases) { + auto canvas_data = kv.second->Save(); if (!canvas_data) continue; diff --git a/frontend/utility/OBSCanvas.hpp b/frontend/utility/OBSCanvas.hpp index 2c3cde121db553..144b5ec015ff71 100644 --- a/frontend/utility/OBSCanvas.hpp +++ b/frontend/utility/OBSCanvas.hpp @@ -20,6 +20,7 @@ #include #include #include +#include #include "obs.h" #include "obs.hpp" @@ -37,16 +38,16 @@ class Canvas { Canvas() = delete; Canvas(Canvas &other) = delete; - Canvas &operator=(Canvas &&other) noexcept; + Canvas &operator=(Canvas &&other) = delete; operator obs_canvas_t *() const { return canvas; } [[nodiscard]] std::optional Save() const; - static std::unique_ptr Load(obs_data_t *data); - static std::vector LoadCanvases(obs_data_array_t *canvases); - static OBSDataArrayAutoRelease SaveCanvases(const std::vector &canvases); + static std::shared_ptr Load(obs_data_t *data); + static std::map> LoadCanvases(obs_data_array_t *canvases); + static OBSDataArrayAutoRelease SaveCanvases(const std::map> &canvases); -private: +public: obs_canvas_t *canvas = nullptr; }; } // namespace OBS diff --git a/frontend/widgets/OBSBasic.hpp b/frontend/widgets/OBSBasic.hpp index ca213433e0beb8..e37a8b63516b6d 100644 --- a/frontend/widgets/OBSBasic.hpp +++ b/frontend/widgets/OBSBasic.hpp @@ -1120,14 +1120,15 @@ private slots: * ------------------------------------- */ private: - std::vector canvases; + std::map> canvases; static void CanvasRemoved(void *data, calldata_t *params); public: - const std::vector &GetCanvases() const noexcept { return canvases; } + const std::map> &GetCanvases() const noexcept { return canvases; } - const OBS::Canvas &AddCanvas(const std::string &name, obs_video_info *ovi = nullptr, int flags = 0); + const std::shared_ptr AddCanvas(const std::string &name, obs_video_info *ovi = nullptr, + int flags = 0); public slots: bool RemoveCanvas(OBSCanvas canvas); diff --git a/frontend/widgets/OBSBasic_Canvases.cpp b/frontend/widgets/OBSBasic_Canvases.cpp index 9b1f346efa305a..6bbe41e0169928 100644 --- a/frontend/widgets/OBSBasic_Canvases.cpp +++ b/frontend/widgets/OBSBasic_Canvases.cpp @@ -23,12 +23,13 @@ void OBSBasic::CanvasRemoved(void *data, calldata_t *params) QMetaObject::invokeMethod(static_cast(data), "RemoveCanvas", Q_ARG(OBSCanvas, OBSCanvas(canvas))); } -const OBS::Canvas &OBSBasic::AddCanvas(const std::string &name, obs_video_info *ovi, int flags) +const std::shared_ptr OBSBasic::AddCanvas(const std::string &name, obs_video_info *ovi, int flags) { OBSCanvas canvas = obs_canvas_create(name.c_str(), ovi, flags); - auto &it = canvases.emplace_back(canvas); + canvases[canvas] = std::make_shared(canvas); + OnEvent(OBS_FRONTEND_EVENT_CANVAS_ADDED); - return it; + return canvases[canvas]; } bool OBSBasic::RemoveCanvas(OBSCanvas canvas) @@ -36,9 +37,8 @@ bool OBSBasic::RemoveCanvas(OBSCanvas canvas) if (!canvas) return false; - auto canvas_it = std::find(std::begin(canvases), std::end(canvases), canvas); - if (canvas_it != std::end(canvases)) { - canvases.erase(canvas_it); + if (canvases.count(canvas)) { + canvases.erase(canvas); OnEvent(OBS_FRONTEND_EVENT_CANVAS_REMOVED); return true; } diff --git a/frontend/widgets/OBSBasic_SceneCollections.cpp b/frontend/widgets/OBSBasic_SceneCollections.cpp index ee9e4e6086f735..49b7fb044f4368 100644 --- a/frontend/widgets/OBSBasic_SceneCollections.cpp +++ b/frontend/widgets/OBSBasic_SceneCollections.cpp @@ -1535,8 +1535,8 @@ void OBSBasic::ClearSceneData() obs_enum_scenes(cb, nullptr); obs_enum_sources(cb, nullptr); - for (const auto &canvas : canvases) { - obs_canvas_enum_scenes(canvas, cb, nullptr); + for (const auto &kv : canvases) { + obs_canvas_enum_scenes(kv.first, cb, nullptr); } canvases.clear();