Skip to content

Commit

Permalink
Requests: Additions and code cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
tt2468 committed Sep 3, 2021
1 parent 82d8a3d commit 333737f
Show file tree
Hide file tree
Showing 11 changed files with 142 additions and 22 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ set(obs-websocket_SOURCES
src/requesthandler/RequestHandler_Sources.cpp
src/requesthandler/RequestHandler_Scenes.cpp
src/requesthandler/RequestHandler_Inputs.cpp
src/requesthandler/RequestHandler_SceneItems.cpp
src/requesthandler/RequestHandler_Stream.cpp
src/requesthandler/rpc/Request.cpp
src/requesthandler/rpc/RequestResult.cpp
Expand Down
6 changes: 6 additions & 0 deletions src/requesthandler/RequestHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,12 @@ const std::map<std::string, RequestMethodHandler> RequestHandler::_handlerMap
{"GetInputPropertiesListPropertyItems", &RequestHandler::GetInputPropertiesListPropertyItems},
{"PressInputPropertiesButton", &RequestHandler::PressInputPropertiesButton},

// Scene Items
{"GetSceneItemList", &RequestHandler::GetSceneItemList},
{"GetGroupSceneItemList", &RequestHandler::GetGroupSceneItemList},
{"CreateSceneItem", &RequestHandler::CreateSceneItem},
{"RemoveSceneItem", &RequestHandler::RemoveSceneItem},

// Stream
{"GetStreamStatus", &RequestHandler::GetStreamStatus},
{"ToggleStream", &RequestHandler::ToggleStream},
Expand Down
7 changes: 7 additions & 0 deletions src/requesthandler/RequestHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "rpc/RequestResult.h"
#include "../obs-websocket.h"
#include "../utils/Obs.h"
#include "../plugin-macros.generated.h"

class RequestHandler;
typedef RequestResult(RequestHandler::*RequestMethodHandler)(const Request&);
Expand Down Expand Up @@ -81,6 +82,12 @@ class RequestHandler {
RequestResult GetInputPropertiesListPropertyItems(const Request&);
RequestResult PressInputPropertiesButton(const Request&);

// Scene Items
RequestResult GetSceneItemList(const Request&);
RequestResult GetGroupSceneItemList(const Request&);
RequestResult CreateSceneItem(const Request&);
RequestResult RemoveSceneItem(const Request&);

// Stream
RequestResult GetStreamStatus(const Request&);
RequestResult ToggleStream(const Request&);
Expand Down
1 change: 0 additions & 1 deletion src/requesthandler/RequestHandler_Config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
#include <util/config-file.h>

#include "RequestHandler.h"
#include "../plugin-macros.generated.h"

RequestResult RequestHandler::GetPersistentData(const Request& request)
{
Expand Down
1 change: 0 additions & 1 deletion src/requesthandler/RequestHandler_General.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
#include "../eventhandler/types/EventSubscription.h"
#include "../obs-websocket.h"
#include "../WebSocketServer.h"
#include "../plugin-macros.generated.h"

RequestResult RequestHandler::GetVersion(const Request& request)
{
Expand Down
71 changes: 71 additions & 0 deletions src/requesthandler/RequestHandler_SceneItems.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#include "RequestHandler.h"

RequestResult RequestHandler::GetSceneItemList(const Request& request)
{
RequestStatus::RequestStatus statusCode;
std::string comment;
OBSSourceAutoRelease scene = request.ValidateScene("sceneName", statusCode, comment);
if (!scene)
return RequestResult::Error(statusCode, comment);

json responseData;
responseData["sceneItems"] = Utils::Obs::ListHelper::GetSceneItemList(obs_scene_from_source(scene));

return RequestResult::Success(responseData);
}

RequestResult RequestHandler::GetGroupSceneItemList(const Request& request)
{
RequestStatus::RequestStatus statusCode;
std::string comment;
OBSSourceAutoRelease scene = request.ValidateScene("sceneName", statusCode, comment, OBS_WEBSOCKET_SCENE_FILTER_GROUP_ONLY);
if (!scene)
return RequestResult::Error(statusCode, comment);

json responseData;
responseData["sceneItems"] = Utils::Obs::ListHelper::GetSceneItemList(obs_group_from_source(scene));

return RequestResult::Success(responseData);
}

RequestResult RequestHandler::CreateSceneItem(const Request& request)
{
RequestStatus::RequestStatus statusCode;
std::string comment;
OBSSourceAutoRelease sceneSource = request.ValidateScene("sceneName", statusCode, comment);
if (!sceneSource)
return RequestResult::Error(statusCode, comment);

OBSScene scene = obs_scene_from_source(sceneSource);

OBSSourceAutoRelease source = request.ValidateSource("sourceName", statusCode, comment);
if (!source)
return RequestResult::Error(statusCode, comment);

if (request.RequestData["sceneName"] == request.RequestData["sourceName"])
return RequestResult::Error(RequestStatus::CannotAct, "You cannot create scene item of a scene within itself.");

bool sceneItemEnabled = true;
if (request.RequestData.contains("sceneItemEnabled") && request.RequestData["sceneItemEnabled"].is_boolean())
sceneItemEnabled = request.RequestData["sceneItemEnabled"];

obs_sceneitem_t *sceneItem = Utils::Obs::ActionHelper::CreateSceneItem(source, scene, sceneItemEnabled);

json responseData;
responseData["sceneItemId"] = obs_sceneitem_get_id(sceneItem);

return RequestResult::Success(responseData);
}

RequestResult RequestHandler::RemoveSceneItem(const Request& request)
{
RequestStatus::RequestStatus statusCode;
std::string comment;
OBSSceneItemAutoRelease sceneItem = request.ValidateSceneItem("sceneName", "sceneItemId", statusCode, comment);
if (!sceneItem)
return RequestResult::Error(statusCode, comment);

obs_sceneitem_remove(sceneItem);

return RequestResult::Success();
}
1 change: 0 additions & 1 deletion src/requesthandler/RequestHandler_Scenes.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#include "RequestHandler.h"
#include "../plugin-macros.generated.h"

RequestResult RequestHandler::GetSceneList(const Request& request)
{
Expand Down
1 change: 0 additions & 1 deletion src/requesthandler/RequestHandler_Sources.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
#include <QDir>

#include "RequestHandler.h"
#include "../plugin-macros.generated.h"

QImage TakeSourceScreenshot(obs_source_t *source, bool &success, uint32_t requestedWidth = 0, uint32_t requestedHeight = 0)
{
Expand Down
1 change: 0 additions & 1 deletion src/requesthandler/RequestHandler_Stream.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#include "RequestHandler.h"
#include "../plugin-macros.generated.h"

RequestResult RequestHandler::GetStreamStatus(const Request& request)
{
Expand Down
63 changes: 47 additions & 16 deletions src/requesthandler/rpc/Request.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,52 +136,58 @@ const bool Request::ValidateArray(const std::string keyName, RequestStatus::Requ
return true;
}

obs_source_t *Request::ValidateScene(const std::string keyName, RequestStatus::RequestStatus &statusCode, std::string &comment) const
obs_source_t *Request::ValidateSource(const std::string keyName, RequestStatus::RequestStatus &statusCode, std::string &comment) const
{
if (!ValidateString(keyName, statusCode, comment))
return nullptr;

std::string sceneName = RequestData[keyName];
std::string sourceName = RequestData[keyName];

obs_source_t *ret = obs_get_source_by_name(sceneName.c_str());
obs_source_t *ret = obs_get_source_by_name(sourceName.c_str());
if (!ret) {
statusCode = RequestStatus::ResourceNotFound;
comment = std::string("No scene was found by the name of `") + sceneName + "`.";
comment = std::string("No source was found by the name of `") + sourceName + "`.";
return nullptr;
}

return ret;
}

obs_source_t *Request::ValidateScene(const std::string keyName, RequestStatus::RequestStatus &statusCode, std::string &comment, const ObsWebSocketSceneFilter filter) const
{
obs_source_t *ret = ValidateSource(keyName, statusCode, comment);
if (!ret)
return nullptr;

if (obs_source_get_type(ret) != OBS_SOURCE_TYPE_SCENE) {
obs_source_release(ret);
statusCode = RequestStatus::InvalidResourceType;
comment = "The specified source is not a scene.";
return nullptr;
}

OBSScene scene = obs_scene_from_source(ret);
if (obs_scene_is_group(scene)) {
bool isGroup = obs_source_is_group(ret);
if (filter == OBS_WEBSOCKET_SCENE_FILTER_SCENE_ONLY && isGroup) {
obs_source_release(ret);
statusCode = RequestStatus::InvalidResourceType;
comment = "The specified source is not a scene.";
return nullptr;
} else if (filter == OBS_WEBSOCKET_SCENE_FILTER_GROUP_ONLY && !isGroup) {
obs_source_release(ret);
statusCode = RequestStatus::InvalidResourceType;
comment = "The specified source is not a group.";
return nullptr;
}

return ret;
}

obs_source_t *Request::ValidateInput(const std::string keyName, RequestStatus::RequestStatus &statusCode, std::string &comment) const
{
if (!ValidateString(keyName, statusCode, comment))
obs_source_t *ret = ValidateSource(keyName, statusCode, comment);
if (!ret)
return nullptr;

std::string inputName = RequestData[keyName];

obs_source_t *ret = obs_get_source_by_name(inputName.c_str());
if (!ret) {
statusCode = RequestStatus::ResourceNotFound;
comment = std::string("No input was found by the name of `") + inputName + "`.";
return nullptr;
}

if (obs_source_get_type(ret) != OBS_SOURCE_TYPE_INPUT) {
obs_source_release(ret);
statusCode = RequestStatus::InvalidResourceType;
Expand All @@ -191,3 +197,28 @@ obs_source_t *Request::ValidateInput(const std::string keyName, RequestStatus::R

return ret;
}

obs_sceneitem_t *Request::ValidateSceneItem(const std::string sceneKeyName, const std::string sceneItemIdKeyName, RequestStatus::RequestStatus &statusCode, std::string &comment, const ObsWebSocketSceneFilter filter) const
{
OBSSource sceneSource = ValidateScene(sceneKeyName, statusCode, comment, filter);
obs_source_release(sceneSource);
if (!sceneSource)
return nullptr;

if (!ValidateNumber(sceneItemIdKeyName, statusCode, comment, 0))
return nullptr;

OBSScene scene = obs_scene_from_source(sceneSource);

int64_t sceneItemId = RequestData[sceneItemIdKeyName];

OBSSceneItem sceneItem = obs_scene_find_sceneitem_by_id(scene, sceneItemId);
if (!sceneItem) {
statusCode = RequestStatus::ResourceNotFound;
comment = std::string("No scene items were found in scene `") + RequestData[sceneKeyName].get<std::string>() + "` with the ID `" + std::to_string(sceneItemId) + "`.";
return nullptr;
}

obs_sceneitem_addref(sceneItem);
return sceneItem;
}
11 changes: 10 additions & 1 deletion src/requesthandler/rpc/Request.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@
#include "../../WebSocketSession.h"
#include "../../utils/Json.h"

enum ObsWebSocketSceneFilter {
OBS_WEBSOCKET_SCENE_FILTER_SCENE_ONLY,
OBS_WEBSOCKET_SCENE_FILTER_GROUP_ONLY,
OBS_WEBSOCKET_SCENE_FILTER_SCENE_OR_GROUP,
};

struct Request
{
Request(SessionPtr session, const std::string requestType, const json requestData = nullptr);
Expand All @@ -20,8 +26,11 @@ struct Request
const bool ValidateObject(const std::string keyName, RequestStatus::RequestStatus &statusCode, std::string &comment, const bool allowEmpty = false) const;
const bool ValidateArray(const std::string keyName, RequestStatus::RequestStatus &statusCode, std::string &comment, const bool allowEmpty = false) const;

obs_source_t *ValidateScene(const std::string keyName, RequestStatus::RequestStatus &statusCode, std::string &comment) const;
// All return values have incremented refcounts
obs_source_t *ValidateSource(const std::string keyName, RequestStatus::RequestStatus &statusCode, std::string &comment) const;
obs_source_t *ValidateScene(const std::string keyName, RequestStatus::RequestStatus &statusCode, std::string &comment, const ObsWebSocketSceneFilter filter = OBS_WEBSOCKET_SCENE_FILTER_SCENE_ONLY) const;
obs_source_t *ValidateInput(const std::string keyName, RequestStatus::RequestStatus &statusCode, std::string &comment) const;
obs_sceneitem_t *ValidateSceneItem(const std::string sceneKeyName, const std::string sceneItemIdKeyName, RequestStatus::RequestStatus &statusCode, std::string &comment, const ObsWebSocketSceneFilter filter = OBS_WEBSOCKET_SCENE_FILTER_SCENE_ONLY) const;

SessionPtr Session;
const uint8_t RpcVersion;
Expand Down

0 comments on commit 333737f

Please sign in to comment.