更完
This commit is contained in:
@@ -2,14 +2,95 @@
|
||||
|
||||
#include "Web_Event.h"
|
||||
|
||||
#include <json/json.h>
|
||||
|
||||
#include <concepts>
|
||||
#include <optional>
|
||||
#include <string_view>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <variant>
|
||||
|
||||
namespace renderive::web {
|
||||
|
||||
class Web_Event_Adapter final {
|
||||
public:
|
||||
[[nodiscard]] static std::optional<Web_Event> decode(std::string_view message);
|
||||
using Web_Transport_Events = std::variant<Frame_Request, Viewport_Resize, Gallery_Request>;
|
||||
using Render_2D_Web_Events = std::variant<Event, Pointer_Event, Wheel_Event, Key_Event>;
|
||||
using Web_Demo_Control_Events = std::variant<Set_Demo_Mode,
|
||||
Set_Center_Frequency,
|
||||
Set_Bandwidth,
|
||||
Set_Gain,
|
||||
Set_Max_Hold,
|
||||
Set_Smoothing,
|
||||
Clear_Selection>;
|
||||
|
||||
struct Web_Transport_Event_Decoder {
|
||||
using event_type = Web_Transport_Events;
|
||||
[[nodiscard]] static std::optional<event_type> decode(const Json::Value& root,
|
||||
std::string_view source);
|
||||
};
|
||||
|
||||
struct Render_2D_Web_Event_Decoder {
|
||||
using event_type = Render_2D_Web_Events;
|
||||
[[nodiscard]] static std::optional<event_type> decode(const Json::Value& root,
|
||||
std::string_view source);
|
||||
};
|
||||
|
||||
struct Web_Demo_Control_Decoder {
|
||||
using event_type = Web_Demo_Control_Events;
|
||||
[[nodiscard]] static std::optional<event_type> decode(const Json::Value& root,
|
||||
std::string_view source);
|
||||
};
|
||||
|
||||
template <class Decoder>
|
||||
concept Web_Event_Decoder = requires(const Json::Value& root, std::string_view source) {
|
||||
typename Decoder::event_type;
|
||||
{ Decoder::decode(root, source) } ->
|
||||
std::same_as<std::optional<typename Decoder::event_type>>;
|
||||
};
|
||||
|
||||
[[nodiscard]] std::optional<Json::Value> parse_web_event(std::string_view message);
|
||||
|
||||
template <class T>
|
||||
struct Is_Variant : std::false_type {};
|
||||
|
||||
template <class... Values>
|
||||
struct Is_Variant<std::variant<Values...>> : std::true_type {};
|
||||
|
||||
template <class Event_Variant, Web_Event_Decoder... Decoders>
|
||||
class Basic_Web_Event_Adapter final {
|
||||
public:
|
||||
[[nodiscard]] static std::optional<Event_Variant> decode(std::string_view message) {
|
||||
const auto root = parse_web_event(message);
|
||||
if (!root)
|
||||
return std::nullopt;
|
||||
|
||||
std::optional<Event_Variant> result;
|
||||
([&] {
|
||||
if (result)
|
||||
return;
|
||||
auto decoded = Decoders::decode(*root, message);
|
||||
if (decoded)
|
||||
result = widen(std::move(*decoded));
|
||||
}(), ...);
|
||||
return result;
|
||||
}
|
||||
|
||||
private:
|
||||
template <class Decoded>
|
||||
static Event_Variant widen(Decoded decoded) {
|
||||
if constexpr (Is_Variant<std::remove_cvref_t<Decoded>>::value) {
|
||||
return std::visit([](auto&& value) -> Event_Variant {
|
||||
return Event_Variant(std::forward<decltype(value)>(value));
|
||||
}, std::move(decoded));
|
||||
} else {
|
||||
return Event_Variant(std::move(decoded));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
using Web_Event_Adapter = Basic_Web_Event_Adapter<Web_Event,
|
||||
Web_Transport_Event_Decoder,
|
||||
Render_2D_Web_Event_Decoder,
|
||||
Web_Demo_Control_Decoder>;
|
||||
|
||||
} // namespace renderive::web
|
||||
|
||||
Reference in New Issue
Block a user