SceneSwitcher/lib/legacy/switch-random.cpp
2024-08-15 01:02:03 +02:00

230 lines
5.2 KiB
C++

#include "advanced-scene-switcher.hpp"
#include "layout-helpers.hpp"
#include "switcher-data.hpp"
#include "utility.hpp"
#include "ui-helpers.hpp"
#include <random>
namespace advss {
bool RandomSwitch::pause = false;
static QObject *addPulse = nullptr;
void AdvSceneSwitcher::on_randomAdd_clicked()
{
std::lock_guard<std::mutex> lock(switcher->m);
switcher->randomSwitches.emplace_back();
listAddClicked(ui->randomSwitches,
new RandomSwitchWidget(this,
&switcher->randomSwitches.back()),
addPulse);
ui->randomHelp->setVisible(false);
}
void AdvSceneSwitcher::on_randomRemove_clicked()
{
QListWidgetItem *item = ui->randomSwitches->currentItem();
if (!item) {
return;
}
{
std::lock_guard<std::mutex> lock(switcher->m);
int idx = ui->randomSwitches->currentRow();
auto &switches = switcher->randomSwitches;
switches.erase(switches.begin() + idx);
}
delete item;
}
bool SwitcherData::checkRandom(OBSWeakSource &scene, OBSWeakSource &transition,
int &delay)
{
if (randomSwitches.size() == 0 || RandomSwitch::pause) {
return false;
}
std::deque<RandomSwitch> rs(randomSwitches);
std::random_device rng;
std::mt19937 urng(rng());
std::shuffle(rs.begin(), rs.end(), urng);
bool match = false;
for (RandomSwitch &r : rs) {
if (!r.initialized()) {
continue;
}
if (randomSwitches.size() != 1) {
if (r.targetType == SwitchTargetType::Scene &&
r.scene == lastRandomScene) {
continue;
} else if (r.targetType ==
SwitchTargetType::SceneGroup &&
r.group && r.group == lastRandomSceneGroup) {
continue;
}
}
scene = r.getScene();
transition = r.transition;
delay = (int)r.delay * 1000;
match = true;
lastRandomScene = r.scene;
lastRandomSceneGroup = r.group;
if (VerboseLoggingEnabled()) {
r.logMatch();
}
break;
}
return match;
}
void SwitcherData::saveRandomSwitches(obs_data_t *obj)
{
obs_data_array_t *randomArray = obs_data_array_create();
for (RandomSwitch &s : randomSwitches) {
obs_data_t *array_obj = obs_data_create();
s.save(array_obj);
obs_data_array_push_back(randomArray, array_obj);
obs_data_release(array_obj);
}
obs_data_set_array(obj, "randomSwitches", randomArray);
obs_data_array_release(randomArray);
}
void SwitcherData::loadRandomSwitches(obs_data_t *obj)
{
randomSwitches.clear();
obs_data_array_t *randomArray =
obs_data_get_array(obj, "randomSwitches");
size_t count = obs_data_array_count(randomArray);
for (size_t i = 0; i < count; i++) {
obs_data_t *array_obj = obs_data_array_item(randomArray, i);
randomSwitches.emplace_back();
randomSwitches.back().load(array_obj);
obs_data_release(array_obj);
}
obs_data_array_release(randomArray);
}
void AdvSceneSwitcher::SetupRandomTab()
{
for (auto &s : switcher->randomSwitches) {
QListWidgetItem *item;
item = new QListWidgetItem(ui->randomSwitches);
ui->randomSwitches->addItem(item);
RandomSwitchWidget *sw = new RandomSwitchWidget(this, &s);
item->setSizeHint(sw->minimumSizeHint());
ui->randomSwitches->setItemWidget(item, sw);
}
if (switcher->randomSwitches.size() == 0) {
if (!switcher->disableHints) {
addPulse = HighlightWidget(ui->randomAdd,
QColor(Qt::green));
}
ui->randomHelp->setVisible(true);
} else {
ui->randomHelp->setVisible(false);
}
ui->randomDisabledWarning->setStyleSheet("QLabel{ \
border-style: outset; \
border-width: 2px; \
border-radius: 7px; \
border-color: rgb(0,0,0,0) \
}");
if (switcher->switchIfNotMatching != NoMatchBehavior::RANDOM_SWITCH) {
if (!switcher->disableHints) {
HighlightWidget(ui->randomDisabledWarning,
QColor(Qt::red), QColor(0, 0, 0, 0));
}
} else {
ui->randomDisabledWarning->setVisible(false);
}
}
void RandomSwitch::save(obs_data_t *obj)
{
SceneSwitcherEntry::save(obj, "targetType", "scene");
obs_data_set_double(obj, "delay", delay);
}
void RandomSwitch::load(obs_data_t *obj)
{
SceneSwitcherEntry::load(obj, "targetType", "scene");
delay = obs_data_get_double(obj, "delay");
}
RandomSwitchWidget::RandomSwitchWidget(QWidget *parent, RandomSwitch *s)
: SwitchWidget(parent, s, false, true)
{
delay = new QDoubleSpinBox();
QWidget::connect(delay, SIGNAL(valueChanged(double)), this,
SLOT(DelayChanged(double)));
delay->setSuffix("s");
delay->setMaximum(999999999.9);
if (s) {
delay->setValue(s->delay);
}
QHBoxLayout *mainLayout = new QHBoxLayout;
std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
{"{{scenes}}", scenes},
{"{{transitions}}", transitions},
{"{{delay}}", delay}};
PlaceWidgets(obs_module_text("AdvSceneSwitcher.randomTab.entry"),
mainLayout, widgetPlaceholders);
setLayout(mainLayout);
switchData = s;
loading = false;
}
RandomSwitch *RandomSwitchWidget::getSwitchData()
{
return switchData;
}
void RandomSwitchWidget::setSwitchData(RandomSwitch *s)
{
switchData = s;
}
void RandomSwitchWidget::swapSwitchData(RandomSwitchWidget *s1,
RandomSwitchWidget *s2)
{
SwitchWidget::swapSwitchData(s1, s2);
RandomSwitch *t = s1->getSwitchData();
s1->setSwitchData(s2->getSwitchData());
s2->setSwitchData(t);
}
void RandomSwitchWidget::DelayChanged(double d)
{
if (loading || !switchData) {
return;
}
std::lock_guard<std::mutex> lock(switcher->m);
switchData->delay = d;
}
} // namespace advss