From 2c13bcac152951e79291fac265f64b1a3dd67e25 Mon Sep 17 00:00:00 2001 From: lisyarus Date: Fri, 21 Apr 2023 17:26:30 +0300 Subject: [PATCH] Implement react::join --- libs/react/include/psemek/react/join.hpp | 59 ++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 libs/react/include/psemek/react/join.hpp diff --git a/libs/react/include/psemek/react/join.hpp b/libs/react/include/psemek/react/join.hpp new file mode 100644 index 00000000..c7cfb0e7 --- /dev/null +++ b/libs/react/include/psemek/react/join.hpp @@ -0,0 +1,59 @@ +#pragma once + +#include + +namespace psemek::react +{ + + template + value join(value> x) + { + auto node = std::make_shared>(); + auto weak_node = std::weak_ptr{node}; + + auto internal_subscriber = [weak_node]{ + if (auto node = weak_node.lock()) + { + node->cached_value = std::nullopt; + node->internal_signal(); + } + }; + + auto inner_external_subscriber = [weak_node](T const &){ + if (auto node = weak_node.lock()) + if (!node->cached_value) + node->external_signal(node->value()); + }; + + auto inner_internal_token = std::make_shared::subscription_token>(); + auto inner_external_token = std::make_shared::subscription_token>(); + + auto external_subscriber = [weak_node, inner_internal_token, inner_external_token, internal_subscriber, inner_external_subscriber](value const & x){ + if (auto node = weak_node.lock()) + { + if (!node->cached_value) + { + *inner_internal_token = x.subscribe(detail::internal_tag{}, internal_subscriber); + *inner_external_token = x.subscribe(inner_external_subscriber); + node->external_signal(node->value()); + } + } + }; + + auto internal_token = x.subscribe(detail::internal_tag{}, internal_subscriber); + auto external_token = x.subscribe(external_subscriber); + + node->getter = [ + inner_internal_token, + inner_external_token, + internal_token, + external_token, + x + ]{ + return **x; + }; + + return value(detail::internal_tag{}, std::move(node)); + } + +}