obs-StreamFX/source/obs/obs-source.hpp

668 lines
17 KiB
C++

/*
* Modern effects for a modern Streamer
* Copyright (C) 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"
namespace streamfx::obs {
class source {
obs_source_t* _ref;
bool _is_owner;
public:
FORCE_INLINE ~source()
{
release();
};
/** Empty/Invalid hard reference.
*
*/
FORCE_INLINE source() : _ref(nullptr), _is_owner(false){};
/** Create a new hard reference from an existing pointer.
*
* @param source The source object to reference.
* @param add_reference Should we increment the reference counter (duplicate ownership) or leave as it is (transfer ownership)?
*/
FORCE_INLINE source(obs_source_t* source, bool duplicate_reference = false, bool take_ownership = true)
: _is_owner(take_ownership)
{
if (duplicate_reference) {
_ref = obs_source_get_ref(source);
} else {
_ref = source;
}
};
/** Create a new hard reference for a given source by name.
*
* Attention: May fail if the name does not exactly match.
*/
FORCE_INLINE source(std::string_view name) : _is_owner(true)
{
_ref = obs_get_source_by_name(name.data());
};
/** Create a new hard reference for a new source.
*
* Attention: May fail.
*/
FORCE_INLINE source(std::string_view id, std::string_view name, obs_data_t* settings, obs_data_t* hotkeys)
: _is_owner(true)
{
_ref = obs_source_create(id.data(), name.data(), settings, hotkeys);
if (!_ref) {
throw std::runtime_error("Failed to create source with given parameters.");
}
};
/** Create a new hard reference for a new private source.
*
* Attention: May fail.
*/
FORCE_INLINE source(std::string_view id, std::string_view name, obs_data_t* settings) : _is_owner(true)
{
_ref = obs_source_create_private(id.data(), name.data(), settings);
if (!_ref) {
throw std::runtime_error("Failed to create source with given parameters.");
}
};
FORCE_INLINE source(source&& move) noexcept
{
_ref = move._ref;
_is_owner = move._is_owner;
move._ref = nullptr;
};
FORCE_INLINE ::streamfx::obs::source& operator=(source&& move) noexcept
{
release();
_ref = move._ref;
_is_owner = move._is_owner;
move._ref = nullptr;
return *this;
};
FORCE_INLINE source(const source& copy)
{
if (copy._is_owner) {
_ref = obs_source_get_ref(copy._ref);
} else {
_ref = copy._ref;
}
_is_owner = copy._is_owner;
};
FORCE_INLINE ::streamfx::obs::source& operator=(const source& copy)
{
release();
if (copy._is_owner) {
_ref = obs_source_get_ref(copy._ref);
} else {
_ref = copy._ref;
}
_is_owner = copy._is_owner;
return *this;
};
public:
/** Retrieve the underlying pointer for manual manipulation.
*
* Attention: Ownership remains with the class instance.
*/
FORCE_INLINE obs_source_t* get() const
{
return _ref;
};
/** Release the underlying pointer.
*
* Useful if you need to respond to the "source_remove" or "remove" signals.
*
* EXPORT void obs_source_release(obs_source_t *source);
*/
FORCE_INLINE void release()
{
if (_ref && _is_owner) {
obs_source_release(_ref);
_ref = nullptr;
_is_owner = false;
}
};
/** Duplicate the source if possible.
*
* Will create a duplicate the source entirely unless forbidden. If forbidden, will instead just return a reference.
*
* EXPORT obs_source_t *obs_source_duplicate(obs_source_t *source, const char *desired_name, bool create_private);
*/
FORCE_INLINE ::streamfx::obs::source duplicate(std::string_view name, bool is_private)
{
return obs_source_duplicate(_ref, name.data(), is_private);
};
public:
/** Get the source info identifier for this reference.
*
* May have a version appended to the end.
*
* EXPORT const char *obs_source_get_id(const obs_source_t *source);
*/
FORCE_INLINE std::string_view id() const
{
return obs_source_get_id(_ref);
};
/** Get the source info identifier for this reference.
*
* EXPORT const char *obs_source_get_unversioned_id(const obs_source_t *source);
*/
FORCE_INLINE std::string_view unversioned_id() const
{
return obs_source_get_unversioned_id(_ref);
};
/** What type is this source?
*
*/
FORCE_INLINE obs_source_type type() const
{
return obs_source_get_type(_ref);
};
/** Get the output flags.
*
* EXPORT uint32_t obs_source_get_output_flags(const obs_source_t *source);
*/
FORCE_INLINE uint32_t output_flags() const
{
return obs_source_get_output_flags(_ref);
};
/** Get the flags
*
* EXPORT uint32_t obs_source_get_flags(const obs_source_t *source);
*/
FORCE_INLINE uint32_t flags() const
{
return obs_source_get_flags(_ref);
};
/** Set the flags
*
* EXPORT void obs_source_set_default_flags(obs_source_t* source, uint32_t flags);
*/
FORCE_INLINE void default_flags(uint32_t flags)
{
obs_source_set_default_flags(_ref, flags);
};
/** Set the flags
*
* EXPORT void obs_source_set_flags(obs_source_t *source, uint32_t flags);
*/
FORCE_INLINE void flags(uint32_t flags)
{
obs_source_set_flags(_ref, flags);
};
/** What is the source type called?
*
* EXPORT const char *obs_source_get_display_name(const char *id);
*/
FORCE_INLINE std::string_view display_name() const
{
return obs_source_get_display_name(id().data());
};
/** What is this source called?
*
* EXPORT const char *obs_source_get_name(const obs_source_t *source);
*/
FORCE_INLINE std::string_view name() const
{
return obs_source_get_name(_ref);
};
/** Change the name of the source.
*
* Triggers 'rename' on the source itself, as well as 'source_rename' globally if not private.
*
* EXPORT void obs_source_set_name(obs_source_t *source, const char *name);
*/
FORCE_INLINE void name(std::string_view new_name)
{
obs_source_set_name(_ref, new_name.data());
};
/**
*
* EXPORT bool obs_source_enabled(const obs_source_t *source);
*/
FORCE_INLINE bool enabled() const
{
return obs_source_enabled(_ref);
};
/**
*
* EXPORT void obs_source_set_enabled(obs_source_t *source, bool enabled);
*/
FORCE_INLINE void enabled(bool enabled)
{
obs_source_set_enabled(_ref, enabled);
};
/**
*
* EXPORT bool obs_source_is_hidden(obs_source_t *source);
*/
FORCE_INLINE bool hidden() const
{
return obs_source_is_hidden(_ref);
};
/**
*
* EXPORT void obs_source_set_hidden(obs_source_t *source, bool hidden);
*/
FORCE_INLINE void hidden(bool v)
{
obs_source_set_hidden(_ref, v);
};
public /* Size */:
/** Get the base width of the source, if supported.
*
* This will be the size without any other scaling factors applied.
*
* EXPORT uint32_t obs_source_get_base_width(obs_source_t *source);
*/
FORCE_INLINE uint32_t base_width() const
{
return obs_source_get_base_width(_ref);
};
/** Get the base height of the source, if supported.
*
* This will be the size without any other scaling factors applied.
*
* EXPORT uint32_t obs_source_get_base_height(obs_source_t *source);
*/
FORCE_INLINE uint32_t base_height() const
{
return obs_source_get_base_height(_ref);
};
/** Get the reported width of the source, if supported.
*
* EXPORT uint32_t obs_source_get_width(obs_source_t *source);
*/
FORCE_INLINE uint32_t width() const
{
return obs_source_get_width(_ref);
};
/** Get the reported height of the source, if supported.
*
* EXPORT uint32_t obs_source_get_height(obs_source_t *source);
*/
FORCE_INLINE uint32_t height() const
{
return obs_source_get_height(_ref);
};
/** Get the reported size of the source, if supported.
*
* EXPORT uint32_t obs_source_get_width(obs_source_t *source);
* EXPORT uint32_t obs_source_get_height(obs_source_t *source);
*/
FORCE_INLINE std::pair<uint32_t, uint32_t> size() const
{
return {width(), height()};
};
public /* Configuration */:
/** Is the source configurable?
*
* EXPORT bool obs_source_configurable(const obs_source_t *source);
*/
FORCE_INLINE bool configurable()
{
return obs_source_configurable(_ref);
};
/** Retrieve the properties for the source.
*
* EXPORT obs_properties_t *obs_get_source_properties(const char *id);
*/
FORCE_INLINE obs_properties_t* properties()
{
return obs_source_properties(_ref);
};
/** Signal for properties to be updated.
*
* EXPORT void obs_source_update_properties(obs_source_t *source);
*/
FORCE_INLINE void update_properties()
{
obs_source_update_properties(_ref);
};
/** Retrieve the default values for the settings.
*
* EXPORT obs_data_t *obs_get_source_defaults(const char *id);
*/
FORCE_INLINE obs_data_t* defaults()
{
return obs_get_source_defaults(id().data());
};
/** Retrieve the private settings.
*
* EXPORT obs_data_t *obs_source_get_private_settings(obs_source_t *item);
*/
FORCE_INLINE obs_data_t* private_settings()
{
return obs_source_get_private_settings(_ref);
};
/** Retrieve the current settings.
*
* EXPORT obs_data_t *obs_source_get_settings(const obs_source_t *source);
*/
FORCE_INLINE obs_data_t* settings()
{
return obs_source_get_settings(_ref);
};
/** Update the settings with new ones.
*
* Does not remove previously existing entries.
*
* EXPORT void obs_source_update(obs_source_t *source, obs_data_t *settings);
*/
FORCE_INLINE void update(obs_data_t* settings)
{
obs_source_update(_ref, settings);
};
/** Reset the settings, then update with new settings.
*
* EXPORT void obs_source_reset_settings(obs_source_t *source, obs_data_t *settings);
*/
FORCE_INLINE void reset_settings(obs_data_t* settings = nullptr)
{
obs_source_reset_settings(_ref, settings);
};
/** Signal the source to load.
*
* EXPORT void obs_source_load(obs_source_t *source);
*/
FORCE_INLINE void load()
{
obs_source_load(_ref);
};
/** Signal the source and all its filters to load.
*
* EXPORT void obs_source_load2(obs_source_t *source);
*/
FORCE_INLINE void load2()
{
obs_source_load2(_ref);
};
/** Signal the source to save.
*
* EXPORT void obs_source_save(obs_source_t *source);
*/
FORCE_INLINE void save()
{
obs_source_save(_ref);
};
public /* Interaction */:
/**
*
* EXPORT void obs_source_send_mouse_click(obs_source_t *source, const struct obs_mouse_event *event, int32_t type, bool mouse_up, uint32_t click_count);
*/
FORCE_INLINE void send_mouse_press(const obs_mouse_event* event, int32_t type, bool released, uint32_t count)
{
return obs_source_send_mouse_click(_ref, event, type, released, count);
};
/**
*
* EXPORT void obs_source_send_mouse_move(obs_source_t *source, const struct obs_mouse_event *event, bool mouse_leave);
*/
FORCE_INLINE void send_mouse_move(const obs_mouse_event* event, bool leave)
{
return obs_source_send_mouse_move(_ref, event, leave);
};
/**
*
* EXPORT void obs_source_send_mouse_wheel(obs_source_t *source, const struct obs_mouse_event *event, int x_delta, int y_delta);
*/
FORCE_INLINE void send_mouse_wheel(const obs_mouse_event* event, int32_t x_delta, int32_t y_delta)
{
return obs_source_send_mouse_wheel(_ref, event, x_delta, y_delta);
};
/**
*
* EXPORT void obs_source_send_key_click(obs_source_t *source, const struct obs_key_event *event, bool key_up);
*/
FORCE_INLINE void send_key_press(const obs_key_event* event, bool released)
{
return obs_source_send_key_click(_ref, event, released);
};
/**
*
* EXPORT void obs_source_send_focus(obs_source_t *source, bool focus);
*/
FORCE_INLINE void send_focus(bool in_focus)
{
return obs_source_send_focus(_ref, in_focus);
};
public /* Filters */:
/**
*
* EXPORT void obs_source_filter_add(obs_source_t *source, obs_source_t *filter);
*/
FORCE_INLINE void add_filter(::streamfx::obs::source& filter)
{
return obs_source_filter_add(_ref, filter.get());
};
/**
*
* EXPORT void obs_source_filter_remove(obs_source_t *source, obs_source_t *filter);
*/
FORCE_INLINE void remove_filter(::streamfx::obs::source& filter)
{
return obs_source_filter_remove(_ref, filter.get());
};
/**
*
* EXPORT obs_source_t *obs_filter_get_parent(const obs_source_t *filter);
*/
FORCE_INLINE ::streamfx::obs::source get_filter_parent()
{
return obs_filter_get_parent(_ref);
};
/**
*
* EXPORT obs_source_t *obs_filter_get_target(const obs_source_t *filter);
*/
FORCE_INLINE ::streamfx::obs::source get_filter_target()
{
return obs_filter_get_target(_ref);
};
/**
*
* EXPORT void obs_source_skip_video_filter(obs_source_t *filter);
*/
FORCE_INLINE void skip_video_filter()
{
return obs_source_skip_video_filter(_ref);
};
/**
*
* EXPORT bool obs_source_process_filter_begin(obs_source_t *filter, enum gs_color_format format, enum obs_allow_direct_render allow_direct);
*/
FORCE_INLINE bool process_filter_begin(gs_color_format format, obs_allow_direct_render allow_direct)
{
return obs_source_process_filter_begin(_ref, format, allow_direct);
};
/**
*
* EXPORT void obs_source_process_filter_end(obs_source_t *filter, gs_effect_t *effect, uint32_t width, uint32_t height);
*/
FORCE_INLINE void process_filter_end(gs_effect_t* effect, uint32_t width, uint32_t height)
{
obs_source_process_filter_end(_ref, effect, width, height);
};
/**
*
* EXPORT void obs_source_process_filter_tech_end(obs_source_t *filter, gs_effect_t *effect, uint32_t width, uint32_t height, const char *tech_name);
*/
FORCE_INLINE void process_filter_tech_end(gs_effect_t* effect, uint32_t width, uint32_t height,
std::string_view tech_name)
{
obs_source_process_filter_tech_end(_ref, effect, width, height, tech_name.data());
};
public /* Active/Showing References */:
/** Is the source visible in main view?
*
* EXPORT bool obs_source_active(const obs_source_t *source);
*/
FORCE_INLINE bool active() const
{
return obs_source_active(_ref);
}
/** Add a active reference (visible in main view).
*
* EXPORT void obs_source_inc_active(obs_source_t *source);
*/
FORCE_INLINE void increment_active()
{
obs_source_inc_active(_ref);
}
/** Remove a active reference (visible in main view).
*
* EXPORT void obs_source_dec_active(obs_source_t *source);
*/
FORCE_INLINE void decrement_active()
{
obs_source_dec_active(_ref);
}
/** Is the source visible in auxiliary views?
*
* EXPORT bool obs_source_showing(const obs_source_t *source);
*/
FORCE_INLINE bool showing() const
{
return obs_source_showing(_ref);
}
/** Add a showing reference (visible in auxiliary view).
*
* EXPORT void obs_source_inc_showing(obs_source_t *source);
* EXPORT void obs_source_dec_showing(obs_source_t *source);
*/
FORCE_INLINE void increment_showing()
{
obs_source_inc_showing(_ref);
}
/** Add a showing reference (visible in auxiliary view).
*
* EXPORT void obs_source_inc_showing(obs_source_t *source);
* EXPORT void obs_source_dec_showing(obs_source_t *source);
*/
FORCE_INLINE void decrement_showing()
{
obs_source_dec_showing(_ref);
}
public /* ToDo */:
/**
*
* EXPORT obs_missing_files_t* obs_source_get_missing_files(const obs_source_t *source);
*/
obs_missing_files_t* get_missing_files();
/**
*
* EXPORT void obs_source_replace_missing_file(obs_missing_file_cb cb, obs_source_t *source, const char *new_path, void *data);
*/
void replace_missing_file(obs_missing_file_cb cb, std::string_view path, void* data);
public:
FORCE_INLINE operator obs_source_t*() const
{
return _ref;
}
FORCE_INLINE obs_source_t* operator*() const
{
return _ref;
}
FORCE_INLINE operator bool() const
{
return _ref != nullptr;
};
FORCE_INLINE bool operator==(source const& rhs) const
{
return _ref == rhs._ref;
};
FORCE_INLINE bool operator<(source const& rhs) const
{
return _ref < rhs._ref;
};
FORCE_INLINE bool operator==(obs_source_t* const& rhs) const
{
return _ref == rhs;
};
};
} // namespace streamfx::obs