Implement react::join
This commit is contained in:
parent
d2afa09adf
commit
2c13bcac15
1 changed files with 59 additions and 0 deletions
59
libs/react/include/psemek/react/join.hpp
Normal file
59
libs/react/include/psemek/react/join.hpp
Normal file
|
|
@ -0,0 +1,59 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <psemek/react/value.hpp>
|
||||||
|
|
||||||
|
namespace psemek::react
|
||||||
|
{
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
value<T> join(value<value<T>> x)
|
||||||
|
{
|
||||||
|
auto node = std::make_shared<detail::node<T>>();
|
||||||
|
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<util::signal<void>::subscription_token>();
|
||||||
|
auto inner_external_token = std::make_shared<typename util::signal<T>::subscription_token>();
|
||||||
|
|
||||||
|
auto external_subscriber = [weak_node, inner_internal_token, inner_external_token, internal_subscriber, inner_external_subscriber](value<T> 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<T>(detail::internal_tag{}, std::move(node));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
Add table
Reference in a new issue