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