requests(ReorderSceneItems): atomic reorder + bring back GetSceneItemFromId

This commit is contained in:
Stéphane Lepin 2019-08-31 02:38:20 +02:00
parent cee0cbebc2
commit 73b5261c49
3 changed files with 82 additions and 17 deletions

View File

@ -185,7 +185,7 @@ obs_sceneitem_t* Utils::GetSceneItemFromItem(obs_scene_t* scene, obs_data_t* ite
const char* name = obs_data_item_get_string(nameInfoItem);
if (idInfoItem) {
obs_sceneitem_t* sceneItem = obs_scene_find_sceneitem_by_id(scene, id);
obs_sceneitem_t* sceneItem = GetSceneItemFromId(scene, id);
obs_source_t* sceneItemSource = obs_sceneitem_get_source(sceneItem);
QString sceneItemName = obs_source_get_name(sceneItemSource);
@ -215,7 +215,6 @@ obs_sceneitem_t* Utils::GetSceneItemFromName(obs_scene_t* scene, QString name) {
current_search search;
search.query = name;
search.result = nullptr;
search.enumCallback = nullptr;
search.enumCallback = [](
obs_scene_t* scene,
@ -248,6 +247,49 @@ obs_sceneitem_t* Utils::GetSceneItemFromName(obs_scene_t* scene, QString name) {
return search.result;
}
obs_sceneitem_t* Utils::GetSceneItemFromId(obs_scene_t* scene, int64_t id) {
if (!scene) {
return nullptr;
}
struct current_search {
int query;
obs_sceneitem_t* result;
bool (*enumCallback)(obs_scene_t*, obs_sceneitem_t*, void*);
};
current_search search;
search.query = id;
search.result = nullptr;
search.enumCallback = [](
obs_scene_t* scene,
obs_sceneitem_t* currentItem,
void* param)
{
current_search* search = reinterpret_cast<current_search*>(param);
if (obs_sceneitem_is_group(currentItem)) {
obs_sceneitem_group_enum_items(currentItem, search->enumCallback, search);
if (search->result) {
return false;
}
}
if (obs_sceneitem_get_id(currentItem) == search->query) {
search->result = currentItem;
obs_sceneitem_addref(search->result);
return false;
}
return true;
};
obs_scene_enum_items(scene, search.enumCallback, &search);
return search.result;
}
bool Utils::IsValidAlignment(const uint32_t alignment) {
switch (alignment) {
case OBS_ALIGN_CENTER:

View File

@ -37,7 +37,10 @@ class Utils {
static obs_data_array_t* GetSceneItems(obs_source_t* source);
static obs_data_t* GetSceneItemData(obs_sceneitem_t* item);
// These two functions support nested lookup into groups
static obs_sceneitem_t* GetSceneItemFromName(obs_scene_t* scene, QString name);
static obs_sceneitem_t* GetSceneItemFromId(obs_scene_t* scene, int64_t id);
static obs_sceneitem_t* GetSceneItemFromItem(obs_scene_t* scene, obs_data_t* item);
static obs_scene_t* GetSceneFromNameOrCurrent(QString sceneName);
static obs_data_t* GetSceneItemPropertiesData(obs_sceneitem_t* item);

View File

@ -104,26 +104,46 @@ HandlerResponse WSRequestHandler::HandleReorderSceneItems(WSRequestHandler* req)
return req->SendErrorResponse("sceneItem order not specified");
}
QVector<struct obs_sceneitem_order_info> orderList;
struct obs_sceneitem_order_info info;
struct reorder_context {
obs_data_array_t* items;
bool success;
QString errorMessage;
};
size_t itemCount = obs_data_array_count(items);
for (int i = 0; i < itemCount; i++) {
OBSDataAutoRelease item = obs_data_array_item(items, i);
struct reorder_context ctx;
ctx.success = false;
ctx.items = items;
OBSSceneItemAutoRelease sceneItem = Utils::GetSceneItemFromItem(scene, item);
if (!sceneItem) {
return req->SendErrorResponse("Invalid sceneItem id or name specified");
obs_scene_atomic_update(scene, [](void* param, obs_scene_t* scene) {
auto ctx = reinterpret_cast<struct reorder_context*>(param);
QVector<struct obs_sceneitem_order_info> orderList;
struct obs_sceneitem_order_info info;
size_t itemCount = obs_data_array_count(ctx->items);
for (int i = 0; i < itemCount; i++) {
OBSDataAutoRelease item = obs_data_array_item(ctx->items, i);
OBSSceneItemAutoRelease sceneItem = Utils::GetSceneItemFromItem(scene, item);
if (!sceneItem) {
ctx->success = false;
ctx->errorMessage = "Invalid sceneItem id or name specified";
return;
}
info.group = nullptr;
info.item = sceneItem;
orderList.insert(0, info);
}
info.group = nullptr;
info.item = sceneItem;
orderList.insert(0, info);
}
ctx->success = obs_scene_reorder_items2(scene, orderList.data(), orderList.size());
if (!ctx->success) {
ctx->errorMessage = "Invalid sceneItem order";
}
}, &ctx);
bool success = obs_scene_reorder_items2(scene, orderList.data(), orderList.size());
if (!success) {
return req->SendErrorResponse("Invalid sceneItem order");
if (!ctx.success) {
return req->SendErrorResponse(ctx.errorMessage);
}
return req->SendOKResponse();