#pragma once #include "Web_Event.h" #include #include #include #include #include #include #include namespace renderive::web { using Web_Transport_Events = std::variant; using Render_2D_Web_Events = std::variant; using Web_Demo_Control_Events = std::variant; struct Web_Transport_Event_Decoder { using event_type = Web_Transport_Events; [[nodiscard]] static std::optional 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 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 decode(const Json::Value& root, std::string_view source); }; template concept Web_Event_Decoder = requires(const Json::Value& root, std::string_view source) { typename Decoder::event_type; { Decoder::decode(root, source) } -> std::same_as>; }; [[nodiscard]] std::optional parse_web_event(std::string_view message); template struct Is_Variant : std::false_type {}; template struct Is_Variant> : std::true_type {}; template class Basic_Web_Event_Adapter final { public: [[nodiscard]] static std::optional decode(std::string_view message) { const auto root = parse_web_event(message); if (!root) return std::nullopt; std::optional result; ([&] { if (result) return; auto decoded = Decoders::decode(*root, message); if (decoded) result = widen(std::move(*decoded)); }(), ...); return result; } private: template static Event_Variant widen(Decoded decoded) { if constexpr (Is_Variant>::value) { return std::visit([](auto&& value) -> Event_Variant { return Event_Variant(std::forward(value)); }, std::move(decoded)); } else { return Event_Variant(std::move(decoded)); } } }; using Web_Event_Adapter = Basic_Web_Event_Adapter; } // namespace renderive::web