Use QMetaObject::invokeMethod in libobs callbacks

Doing this ensures Qt thread safety when adding/removing sources and
scenes, because it will defer the function call to the main thread.
This commit is contained in:
jp9000
2014-02-02 17:03:55 -07:00
parent cfa62354cd
commit 37ed83acec
4 changed files with 54 additions and 49 deletions

View File

@@ -63,11 +63,8 @@ void OBSBasic::OBSInit()
/* TODO: this is a test */
obs_load_module("test-input");
#ifdef _WIN32
/* HACK: fixes a windows qt bug with native widgets with native
* repaint */
/* HACK: fixes a qt bug with native widgets with native repaint */
ui->previewContainer->repaint();
#endif
}
OBSBasic::~OBSBasic()
@@ -91,7 +88,22 @@ OBSSceneItem OBSBasic::GetCurrentSceneItem()
return item ? item->data(Qt::UserRole).value<OBSSceneItem>() : nullptr;
}
void OBSBasic::AddScene(obs_source_t source)
void OBSBasic::UpdateSources(OBSScene scene)
{
ui->sources->clear();
obs_scene_enum_items(scene,
[] (obs_scene_t scene, obs_sceneitem_t item, void *p)
{
OBSBasic *window = static_cast<OBSBasic*>(p);
window->AddSceneItem(item);
return true;
}, this);
}
/* Qt callbacks for invokeMethod */
void OBSBasic::AddScene(OBSSource source)
{
const char *name = obs_source_getname(source);
obs_scene_t scene = obs_scene_fromsource(source);
@@ -106,7 +118,7 @@ void OBSBasic::AddScene(obs_source_t source)
this);
}
void OBSBasic::RemoveScene(obs_source_t source)
void OBSBasic::RemoveScene(OBSSource source)
{
const char *name = obs_source_getname(source);
@@ -121,7 +133,7 @@ void OBSBasic::RemoveScene(obs_source_t source)
}
}
void OBSBasic::AddSceneItem(obs_sceneitem_t item)
void OBSBasic::AddSceneItem(OBSSceneItem item)
{
obs_scene_t scene = obs_sceneitem_getscene(item);
obs_source_t source = obs_sceneitem_getsource(item);
@@ -138,7 +150,7 @@ void OBSBasic::AddSceneItem(obs_sceneitem_t item)
sourceSceneRefs[source] = sourceSceneRefs[source] + 1;
}
void OBSBasic::RemoveSceneItem(obs_sceneitem_t item)
void OBSBasic::RemoveSceneItem(OBSSceneItem item)
{
obs_scene_t scene = obs_sceneitem_getscene(item);
@@ -163,20 +175,7 @@ void OBSBasic::RemoveSceneItem(obs_sceneitem_t item)
}
}
void OBSBasic::UpdateSources(obs_scene_t scene)
{
ui->sources->clear();
obs_scene_enum_items(scene,
[] (obs_scene_t scene, obs_sceneitem_t item, void *p)
{
OBSBasic *window = static_cast<OBSBasic*>(p);
window->AddSceneItem(item);
return true;
}, this);
}
void OBSBasic::UpdateSceneSelection(obs_source_t source)
void OBSBasic::UpdateSceneSelection(OBSSource source)
{
if (source) {
obs_source_type type;
@@ -208,7 +207,8 @@ void OBSBasic::SceneItemAdded(void *data, calldata_t params)
obs_scene_t scene = (obs_scene_t)calldata_ptr(params, "scene");
obs_sceneitem_t item = (obs_sceneitem_t)calldata_ptr(params, "item");
window->AddSceneItem(item);
QMetaObject::invokeMethod(window, "AddSceneItem",
Q_ARG(OBSSceneItem, OBSSceneItem(item)));
}
void OBSBasic::SceneItemRemoved(void *data, calldata_t params)
@@ -218,7 +218,8 @@ void OBSBasic::SceneItemRemoved(void *data, calldata_t params)
obs_scene_t scene = (obs_scene_t)calldata_ptr(params, "scene");
obs_sceneitem_t item = (obs_sceneitem_t)calldata_ptr(params, "item");
window->RemoveSceneItem(item);
QMetaObject::invokeMethod(window, "RemoveSceneItem",
Q_ARG(OBSSceneItem, OBSSceneItem(item)));
}
void OBSBasic::SourceAdded(void *data, calldata_t params)
@@ -229,7 +230,9 @@ void OBSBasic::SourceAdded(void *data, calldata_t params)
obs_source_gettype(source, &type, NULL);
if (type == SOURCE_SCENE)
static_cast<OBSBasic*>(data)->AddScene(source);
QMetaObject::invokeMethod(static_cast<OBSBasic*>(data),
"AddScene",
Q_ARG(OBSSource, OBSSource(source)));
}
void OBSBasic::SourceRemoved(void *data, calldata_t params)
@@ -240,7 +243,9 @@ void OBSBasic::SourceRemoved(void *data, calldata_t params)
obs_source_gettype(source, &type, NULL);
if (type == SOURCE_SCENE)
static_cast<OBSBasic*>(data)->RemoveScene(source);
QMetaObject::invokeMethod(static_cast<OBSBasic*>(data),
"RemoveScene",
Q_ARG(OBSSource, OBSSource(source)));
}
void OBSBasic::ChannelChanged(void *data, calldata_t params)
@@ -249,7 +254,9 @@ void OBSBasic::ChannelChanged(void *data, calldata_t params)
uint32_t channel = calldata_uint32(params, "channel");
if (channel == 0)
static_cast<OBSBasic*>(data)->UpdateSceneSelection(source);
QMetaObject::invokeMethod(static_cast<OBSBasic*>(data),
"UpdateSceneSelection",
Q_ARG(OBSSource, OBSSource(source)));
}
/* Main class functions */

View File

@@ -32,15 +32,19 @@ class OBSBasic : public OBSMainWindow {
private:
std::unordered_map<obs_source_t, int> sourceSceneRefs;
OBSScene GetCurrentScene();
OBSScene GetCurrentScene();
OBSSceneItem GetCurrentSceneItem();
void AddSceneItem(obs_sceneitem_t item);
void RemoveSceneItem(obs_sceneitem_t item);
void AddScene(obs_source_t scene);
void RemoveScene(obs_source_t scene);
void UpdateSources(obs_scene_t scene);
void UpdateSceneSelection(obs_source_t source);
void UpdateSources(OBSScene scene);
private slots:
void AddSceneItem(OBSSceneItem item);
void RemoveSceneItem(OBSSceneItem item);
void AddScene(OBSSource source);
void RemoveScene(OBSSource source);
void UpdateSceneSelection(OBSSource source);
private:
/* OBS Callbacks */
static void SceneItemAdded(void *data, calldata_t params);
static void SceneItemRemoved(void *data, calldata_t params);