obs-StreamFX/source/obs/obs-source-tracker.hpp
Michael Fabian 'Xaymar' Dirks 6dd661a41c obs/source-tracker: Fix missing sources and modernize singleton design
In some rare cases, a bug is observed where some sources end up missing despite being visible in the OBS Studio UI. This is most likely related to us actually missing the events due to plugin load order. We can fix this by explicitly enumerating sources in the constructor.

Additionally in order to reduce the human error factor, we should avoid explicit initialize() and finalize() calls for our singleton. Instead the get() function should do all of the heavy lifting, including thread safety, so that the human writing the code will have next to no chances to break it.
2023-04-05 18:58:20 +02:00

77 lines
2.8 KiB
C++

/*
* Modern effects for a modern Streamer
* Copyright (C) 2017-2018 Michael Fabian Dirks
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#pragma once
#include "common.hpp"
#include <functional>
#include <map>
#include <mutex>
namespace streamfx::obs {
class source_tracker {
std::map<std::string, std::shared_ptr<obs_weak_source_t>> _sources;
std::mutex _mutex;
static void source_create_handler(void* ptr, calldata_t* data) noexcept;
static void source_destroy_handler(void* ptr, calldata_t* data) noexcept;
static void source_rename_handler(void* ptr, calldata_t* data) noexcept;
protected:
void insert_source(obs_source_t* source);
void remove_source(obs_source_t* source);
void rename_source(std::string_view old_name, std::string_view new_name, obs_source_t* source);
public:
// Callback function for enumerating sources.
//
// @param std::string Name of the Source
// @param obs_source_t* Source
// @return true to abort enumeration, false to keep going.
typedef std::function<bool(std::string, obs_source_t*)> enumerate_cb_t;
// Filter function for enumerating sources.
//
// @param std::string Name of the Source
// @param obs_source_t* Source
// @return true to skip, false to pass along.
typedef std::function<bool(std::string, obs_source_t*)> filter_cb_t;
protected:
source_tracker();
public:
~source_tracker();
//! Enumerate all tracked sources
//
// @param enumerate_cb The function called for each tracked source.
// @param filter_cb Filter function to narrow down results.
void enumerate(enumerate_cb_t enumerate_cb, filter_cb_t filter_cb = nullptr);
public:
static bool filter_sources(std::string name, obs_source_t* source);
static bool filter_audio_sources(std::string name, obs_source_t* source);
static bool filter_video_sources(std::string name, obs_source_t* source);
static bool filter_transitions(std::string name, obs_source_t* source);
static bool filter_scenes(std::string name, obs_source_t* source);
public: // Singleton
static std::shared_ptr<streamfx::obs::source_tracker> get();
};
} // namespace streamfx::obs