mirror of
https://github.com/WarmUpTill/SceneSwitcher.git
synced 2026-03-22 01:44:49 -05:00
196 lines
5.1 KiB
C++
196 lines
5.1 KiB
C++
#include "macro-condition-game-capture.hpp"
|
|
#include "layout-helpers.hpp"
|
|
|
|
namespace advss {
|
|
|
|
const std::string MacroConditionGameCapture::id = "game_capture";
|
|
|
|
#ifdef _WIN32
|
|
bool MacroConditionGameCapture::_registered = MacroConditionFactory::Register(
|
|
MacroConditionGameCapture::id,
|
|
{MacroConditionGameCapture::Create,
|
|
MacroConditionGameCaptureEdit::Create,
|
|
"AdvSceneSwitcher.condition.gameCapture"});
|
|
#else
|
|
bool MacroConditionGameCapture::_registered =
|
|
false; // For now the 'game_capture' source only exists on Windows
|
|
#endif
|
|
|
|
bool MacroConditionGameCapture::CheckCondition()
|
|
{
|
|
auto source = OBSGetStrongRef(_source.GetSource());
|
|
if (source != _lastSource) {
|
|
SetupSignalHandler(source);
|
|
return false;
|
|
}
|
|
|
|
std::lock_guard<std::mutex> lock(_mtx);
|
|
if (_hooked) {
|
|
SetTempVarValue("title", _title);
|
|
SetTempVarValue("class", _class);
|
|
SetTempVarValue("executable", _executable);
|
|
}
|
|
|
|
return _hooked;
|
|
}
|
|
|
|
bool MacroConditionGameCapture::Save(obs_data_t *obj) const
|
|
{
|
|
MacroCondition::Save(obj);
|
|
_source.Save(obj);
|
|
return true;
|
|
}
|
|
|
|
bool MacroConditionGameCapture::Load(obs_data_t *obj)
|
|
{
|
|
MacroCondition::Load(obj);
|
|
_source.Load(obj);
|
|
SetupSignalHandler(OBSGetStrongRef(_source.GetSource()));
|
|
return true;
|
|
}
|
|
|
|
void MacroConditionGameCapture::GetCalldataInfo(calldata_t *cd)
|
|
{
|
|
const char *title = "";
|
|
if (!calldata_get_string(cd, "title", &title)) {
|
|
blog(LOG_WARNING, "%s failed to get title", __func__);
|
|
}
|
|
_title = title ? title : "";
|
|
const char *className = "";
|
|
if (!calldata_get_string(cd, "class", &className)) {
|
|
blog(LOG_WARNING, "%s failed to get class", __func__);
|
|
}
|
|
_class = className ? className : "";
|
|
const char *executable = "";
|
|
if (!calldata_get_string(cd, "executable", &executable)) {
|
|
blog(LOG_WARNING, "%s failed to get executable", __func__);
|
|
}
|
|
_executable = executable ? executable : "";
|
|
}
|
|
|
|
void MacroConditionGameCapture::HookedSignalReceived(void *data, calldata_t *cd)
|
|
{
|
|
auto condition = static_cast<MacroConditionGameCapture *>(data);
|
|
std::lock_guard<std::mutex> lock(condition->_mtx);
|
|
condition->GetCalldataInfo(cd);
|
|
condition->_hooked = true;
|
|
}
|
|
|
|
void MacroConditionGameCapture::UnhookedSignalReceived(void *data, calldata_t *)
|
|
{
|
|
auto condition = static_cast<MacroConditionGameCapture *>(data);
|
|
std::lock_guard<std::mutex> lock(condition->_mtx);
|
|
condition->_hooked = false;
|
|
}
|
|
|
|
void MacroConditionGameCapture::SetupTempVars()
|
|
{
|
|
MacroCondition::SetupTempVars();
|
|
AddTempvar(
|
|
"title",
|
|
obs_module_text("AdvSceneSwitcher.tempVar.gameCapture.title"),
|
|
obs_module_text(
|
|
"AdvSceneSwitcher.tempVar.gameCapture.title.description"));
|
|
AddTempvar(
|
|
"class",
|
|
obs_module_text("AdvSceneSwitcher.tempVar.gameCapture.class"),
|
|
obs_module_text(
|
|
"AdvSceneSwitcher.tempVar.gameCapture.class.description"));
|
|
AddTempvar(
|
|
"executable",
|
|
obs_module_text(
|
|
"AdvSceneSwitcher.tempVar.gameCapture.executable"),
|
|
obs_module_text(
|
|
"AdvSceneSwitcher.tempVar.gameCapture.executable.description"));
|
|
}
|
|
|
|
void MacroConditionGameCapture::SetupSignalHandler(obs_source_t *source)
|
|
{
|
|
signal_handler_t *sh = obs_source_get_signal_handler(source);
|
|
_hookSignal = OBSSignal(sh, "hooked", HookedSignalReceived, this);
|
|
_unhookSignal = OBSSignal(sh, "unhooked", UnhookedSignalReceived, this);
|
|
_lastSource = source;
|
|
|
|
SetupInitialState(source);
|
|
}
|
|
|
|
void MacroConditionGameCapture::SetupInitialState(obs_source_t *source)
|
|
{
|
|
std::lock_guard<std::mutex> lock(_mtx);
|
|
|
|
_hooked = false;
|
|
if (!source) {
|
|
return;
|
|
}
|
|
|
|
calldata_t cd;
|
|
calldata_init(&cd);
|
|
auto ph = obs_source_get_proc_handler(source);
|
|
if (!proc_handler_call(ph, "get_hooked", &cd)) {
|
|
blog(LOG_WARNING,
|
|
"%s failed to call proc_handler for 'get_hooked'",
|
|
__func__);
|
|
return;
|
|
}
|
|
|
|
if (!calldata_get_bool(&cd, "hooked", &_hooked)) {
|
|
blog(LOG_WARNING, "%s failed to get hooked state", __func__);
|
|
}
|
|
GetCalldataInfo(&cd);
|
|
|
|
calldata_free(&cd);
|
|
}
|
|
|
|
static QStringList getGameCaptureSourcesList()
|
|
{
|
|
auto sourceEnum = [](void *param, obs_source_t *source) -> bool /* -- */
|
|
{
|
|
QStringList *list = reinterpret_cast<QStringList *>(param);
|
|
|
|
if (strcmp(obs_source_get_unversioned_id(source),
|
|
"game_capture") == 0) {
|
|
*list << obs_source_get_name(source);
|
|
}
|
|
return true;
|
|
};
|
|
|
|
QStringList list;
|
|
obs_enum_sources(sourceEnum, &list);
|
|
list.sort();
|
|
return list;
|
|
}
|
|
|
|
MacroConditionGameCaptureEdit::MacroConditionGameCaptureEdit(
|
|
QWidget *parent, std::shared_ptr<MacroConditionGameCapture> entryData)
|
|
: QWidget(parent),
|
|
_sources(new SourceSelectionWidget(this, getGameCaptureSourcesList,
|
|
true))
|
|
{
|
|
QWidget::connect(_sources,
|
|
SIGNAL(SourceChanged(const SourceSelection &)), this,
|
|
SLOT(SourceChanged(const SourceSelection &)));
|
|
|
|
auto layout = new QHBoxLayout;
|
|
PlaceWidgets(
|
|
obs_module_text("AdvSceneSwitcher.condition.gameCapture.entry"),
|
|
layout, {{"{{sources}}", _sources}});
|
|
setLayout(layout);
|
|
|
|
_entryData = entryData;
|
|
UpdateEntryData();
|
|
_loading = false;
|
|
}
|
|
|
|
void MacroConditionGameCaptureEdit::SourceChanged(const SourceSelection &source)
|
|
{
|
|
GUARD_LOADING_AND_LOCK();
|
|
_entryData->_source = source;
|
|
}
|
|
|
|
void MacroConditionGameCaptureEdit::UpdateEntryData()
|
|
{
|
|
_sources->SetSource(_entryData->_source);
|
|
}
|
|
|
|
} // namespace advss
|