SceneSwitcher/switcher-data-structs.hpp
2017-10-29 00:41:31 +02:00

289 lines
7.4 KiB
C++

#pragma once
#include <condition_variable>
#include <chrono>
#include <string>
#include <vector>
#include <thread>
#include <regex>
#include <mutex>
#include <fstream>
#include "utility.hpp"
#define DEFAULT_INTERVAL 300
#define READ_FILE_FUNC "File based"
#define ROUND_TRIP_FUNC "Scene Sequence"
#define IDLE_FUNC "Idle detection"
#define EXE_FUNC "Executable"
#define SCREEN_REGION_FUNC "Screen region"
#define WINDOW_TITLE_FUNC "Window title"
#define DEFAULT_PRIORITY_0 READ_FILE_FUNC
#define DEFAULT_PRIORITY_1 ROUND_TRIP_FUNC
#define DEFAULT_PRIORITY_2 IDLE_FUNC
#define DEFAULT_PRIORITY_3 EXE_FUNC
#define DEFAULT_PRIORITY_4 SCREEN_REGION_FUNC
#define DEFAULT_PRIORITY_5 WINDOW_TITLE_FUNC
using namespace std;
struct SceneSwitch
{
OBSWeakSource scene;
string window;
OBSWeakSource transition;
bool fullscreen;
inline SceneSwitch(
OBSWeakSource scene_, const char* window_, OBSWeakSource transition_, bool fullscreen_)
: scene(scene_)
, window(window_)
, transition(transition_)
, fullscreen(fullscreen_)
{
}
};
struct ExecutableSceneSwitch
{
OBSWeakSource mScene;
OBSWeakSource mTransition;
QString mExe;
bool mInFocus;
inline ExecutableSceneSwitch(
OBSWeakSource scene, OBSWeakSource transition, const QString& exe, bool inFocus)
: mScene(scene)
, mTransition(transition)
, mExe(exe)
, mInFocus(inFocus)
{
}
};
struct ScreenRegionSwitch
{
OBSWeakSource scene;
OBSWeakSource transition;
int minX, minY, maxX, maxY;
string regionStr;
inline ScreenRegionSwitch(OBSWeakSource scene_, OBSWeakSource transition_, int minX_, int minY_,
int maxX_, int maxY_, string regionStr_)
: scene(scene_)
, transition(transition_)
, minX(minX_)
, minY(minY_)
, maxX(maxX_)
, maxY(maxY_)
, regionStr(regionStr_)
{
}
};
struct SceneRoundTripSwitch
{
OBSWeakSource scene1;
OBSWeakSource scene2;
OBSWeakSource transition;
int delay;
string sceneRoundTripStr;
inline SceneRoundTripSwitch(OBSWeakSource scene1_, OBSWeakSource scene2_,
OBSWeakSource transition_, int delay_, string str)
: scene1(scene1_)
, scene2(scene2_)
, transition(transition_)
, delay(delay_)
, sceneRoundTripStr(str)
{
}
};
struct SceneTransition
{
OBSWeakSource scene1;
OBSWeakSource scene2;
OBSWeakSource transition;
string sceneTransitionStr;
inline SceneTransition(OBSWeakSource scene1_, OBSWeakSource scene2_, OBSWeakSource transition_,
string sceneTransitionStr_)
: scene1(scene1_)
, scene2(scene2_)
, transition(transition_)
, sceneTransitionStr(sceneTransitionStr_)
{
}
};
struct DefaultSceneTransition
{
OBSWeakSource scene;
OBSWeakSource transition;
string sceneTransitionStr;
inline DefaultSceneTransition(OBSWeakSource scene_, OBSWeakSource transition_,
string sceneTransitionStr_)
: scene(scene_)
, transition(transition_)
, sceneTransitionStr(sceneTransitionStr_)
{
}
};
struct FileIOData
{
bool readEnabled;
string readPath;
bool writeEnabled;
string writePath;
};
struct IdleData
{
bool idleEnable;
int time;
OBSWeakSource scene;
OBSWeakSource transition;
};
struct SwitcherData
{
thread th;
condition_variable cv;
mutex m;
mutex transitionMutex;
bool transitionActive = false;
bool waitForTransition = false;
condition_variable transitionCv;
bool stop = false;
vector<SceneSwitch> switches;
string lastTitle;
OBSWeakSource nonMatchingScene;
int interval = DEFAULT_INTERVAL;
bool switchIfNotMatching = false;
bool startAtLaunch = false;
vector<ScreenRegionSwitch> screenRegionSwitches;
vector<OBSWeakSource> pauseScenesSwitches;
vector<string> pauseWindowsSwitches;
vector<string> ignoreWindowsSwitches;
vector<SceneRoundTripSwitch> sceneRoundTripSwitches;
bool autoStopEnable = false;
OBSWeakSource autoStopScene;
string waitSceneName; //indicates which scene was active when we startet waiting on something
vector<SceneTransition> sceneTransitions;
vector<DefaultSceneTransition> defaultSceneTransitions;
vector<ExecutableSceneSwitch> executableSwitches;
FileIOData fileIO;
IdleData idleData;
vector<string> ignoreIdleWindows;
vector<string> functionNamesByPriority = vector<string>{
string(DEFAULT_PRIORITY_0),
string(DEFAULT_PRIORITY_1),
string(DEFAULT_PRIORITY_2),
string(DEFAULT_PRIORITY_3),
string(DEFAULT_PRIORITY_4),
string(DEFAULT_PRIORITY_5),
};
void Thread();
void Start();
void Stop();
bool sceneChangedDuringWait();
bool prioFuncsValid();
void writeSceneInfoToFile();
void setDefaultSceneTransitions(unique_lock<mutex>& lock);
void autoStopStreamAndRecording();
bool checkPause();
void checkSceneRoundTrip(bool& match, OBSWeakSource& scene, OBSWeakSource& transition, unique_lock<mutex>& lock);
void checkIdleSwitch(bool& match, OBSWeakSource& scene, OBSWeakSource& transition);
void checkWindowTitleSwitch(bool& match, OBSWeakSource& scene, OBSWeakSource& transition);
void checkExeSwitch(bool& match, OBSWeakSource& scene, OBSWeakSource& transition);
void checkScreenRegionSwitch(bool& match, OBSWeakSource& scene, OBSWeakSource& transition);
void checkSwitchInfoFromFile(bool& match, OBSWeakSource& scene, OBSWeakSource& transition);
void Prune()
{
for (size_t i = 0; i < switches.size(); i++)
{
SceneSwitch& s = switches[i];
if (!WeakSourceValid(s.scene) || !WeakSourceValid(s.transition))
switches.erase(switches.begin() + i--);
}
if (nonMatchingScene && !WeakSourceValid(nonMatchingScene))
{
switchIfNotMatching = false;
nonMatchingScene = nullptr;
}
for (size_t i = 0; i < screenRegionSwitches.size(); i++)
{
ScreenRegionSwitch& s = screenRegionSwitches[i];
if (!WeakSourceValid(s.scene) || !WeakSourceValid(s.transition))
screenRegionSwitches.erase(screenRegionSwitches.begin() + i--);
}
for (size_t i = 0; i < pauseScenesSwitches.size(); i++)
{
OBSWeakSource& scene = pauseScenesSwitches[i];
if (!WeakSourceValid(scene))
pauseScenesSwitches.erase(pauseScenesSwitches.begin() + i--);
}
for (size_t i = 0; i < sceneRoundTripSwitches.size(); i++)
{
SceneRoundTripSwitch& s = sceneRoundTripSwitches[i];
if (!WeakSourceValid(s.scene1) || !WeakSourceValid(s.scene2)
|| !WeakSourceValid(s.transition))
sceneRoundTripSwitches.erase(sceneRoundTripSwitches.begin() + i--);
}
if (!WeakSourceValid(autoStopScene))
{
autoStopScene = nullptr;
autoStopEnable = false;
}
for (size_t i = 0; i < sceneTransitions.size(); i++)
{
SceneTransition& s = sceneTransitions[i];
if (!WeakSourceValid(s.scene1) || !WeakSourceValid(s.scene2)
|| !WeakSourceValid(s.transition))
sceneTransitions.erase(sceneTransitions.begin() + i--);
}
for (size_t i = 0; i < defaultSceneTransitions.size(); i++)
{
DefaultSceneTransition& s = defaultSceneTransitions[i];
if (!WeakSourceValid(s.scene) || !WeakSourceValid(s.transition))
defaultSceneTransitions.erase(defaultSceneTransitions.begin() + i--);
}
for (size_t i = 0; i < executableSwitches.size(); i++)
{
ExecutableSceneSwitch& s = executableSwitches[i];
if (!WeakSourceValid(s.mScene) || !WeakSourceValid(s.mTransition))
executableSwitches.erase(executableSwitches.begin() + i--);
}
if (!WeakSourceValid(idleData.scene) || !WeakSourceValid(idleData.transition))
{
idleData.idleEnable = false;
}
}
inline ~SwitcherData()
{
Stop();
}
};