Optimize util::signal & support signal<Args...>
This commit is contained in:
parent
d7c8d8710c
commit
4befa1cad7
9 changed files with 44 additions and 62 deletions
|
|
@ -25,7 +25,7 @@ namespace psemek::react
|
|||
node->external_signal(node->value());
|
||||
};
|
||||
|
||||
auto inner_internal_token = std::make_shared<util::signal<void>::subscription_token>();
|
||||
auto inner_internal_token = std::make_shared<util::signal<>::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){
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ namespace psemek::react
|
|||
}
|
||||
};
|
||||
|
||||
std::vector<util::signal<void>::subscription_token> internal_tokens;
|
||||
std::vector<util::signal<>::subscription_token> internal_tokens;
|
||||
std::vector<typename util::signal<T>::subscription_token> external_tokens;
|
||||
|
||||
internal_tokens.reserve(args.size());
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ namespace psemek::react
|
|||
: value<void>(detail::internal_tag{}, std::make_shared<detail::node<void>>())
|
||||
{}
|
||||
|
||||
source(util::signal<void>::subscriber subscriber)
|
||||
source(util::signal<>::subscriber subscriber)
|
||||
: source()
|
||||
{
|
||||
subscribtion_token_ = subscribe(std::move(subscriber));
|
||||
|
|
@ -96,7 +96,7 @@ namespace psemek::react
|
|||
}
|
||||
|
||||
private:
|
||||
util::signal<void>::subscription_token subscribtion_token_;
|
||||
util::signal<>::subscription_token subscribtion_token_;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
|
|
|
|||
|
|
@ -20,7 +20,9 @@ namespace psemek::react
|
|||
template <typename T>
|
||||
struct node
|
||||
{
|
||||
util::signal<void> internal_signal;
|
||||
using external_subscriber = typename util::signal<T>::subscriber;
|
||||
|
||||
util::signal<> internal_signal;
|
||||
util::signal<T> external_signal;
|
||||
util::function<T()> getter;
|
||||
std::optional<T> cached_value;
|
||||
|
|
@ -37,8 +39,10 @@ namespace psemek::react
|
|||
template <>
|
||||
struct node<void>
|
||||
{
|
||||
util::signal<void> internal_signal;
|
||||
util::signal<void> external_signal;
|
||||
using external_subscriber = typename util::signal<>::subscriber;
|
||||
|
||||
util::signal<> internal_signal;
|
||||
util::signal<> external_signal;
|
||||
|
||||
void value()
|
||||
{}
|
||||
|
|
@ -99,7 +103,7 @@ namespace psemek::react
|
|||
return node_->value();
|
||||
}
|
||||
|
||||
[[nodiscard]] auto subscribe(typename util::signal<T>::subscriber subscriber, bool call = false) const
|
||||
[[nodiscard]] auto subscribe(typename detail::node<T>::external_subscriber subscriber, bool call = false) const
|
||||
{
|
||||
if (call)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -20,16 +20,16 @@ namespace psemek::ui::impl
|
|||
virtual void set_child_keys(std::vector<std::optional<key>> keys);
|
||||
|
||||
virtual std::vector<std::unique_ptr<component>> release_children();
|
||||
virtual util::signal<void>::subscription_token release_children_token();
|
||||
virtual std::vector<util::signal<void>::subscription_token> release_child_tokens();
|
||||
virtual util::signal<>::subscription_token release_children_token();
|
||||
virtual std::vector<util::signal<>::subscription_token> release_child_tokens();
|
||||
virtual std::vector<std::optional<key>> release_child_keys();
|
||||
|
||||
util::span<std::unique_ptr<component> const> children() const override;
|
||||
|
||||
private:
|
||||
util::signal<void>::subscription_token children_token_;
|
||||
util::signal<>::subscription_token children_token_;
|
||||
std::vector<std::unique_ptr<component>> children_;
|
||||
std::vector<util::signal<void>::subscription_token> child_tokens_;
|
||||
std::vector<util::signal<>::subscription_token> child_tokens_;
|
||||
std::vector<std::optional<key>> child_keys_;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -15,13 +15,13 @@ namespace psemek::ui::impl
|
|||
util::span<std::unique_ptr<component> const> children() const override;
|
||||
|
||||
virtual void set_child(std::unique_ptr<component> child);
|
||||
virtual void set_child_token(util::signal<void>::subscription_token token);
|
||||
virtual void set_child_token(util::signal<>::subscription_token token);
|
||||
virtual component * child() const;
|
||||
virtual std::unique_ptr<component> release_child();
|
||||
virtual util::signal<void>::subscription_token release_child_token();
|
||||
virtual util::signal<>::subscription_token release_child_token();
|
||||
|
||||
private:
|
||||
util::signal<void>::subscription_token child_token_;
|
||||
util::signal<>::subscription_token child_token_;
|
||||
std::unique_ptr<component> child_;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -28,12 +28,12 @@ namespace psemek::ui::impl
|
|||
return std::move(children_);
|
||||
}
|
||||
|
||||
util::signal<void>::subscription_token container::release_children_token()
|
||||
util::signal<>::subscription_token container::release_children_token()
|
||||
{
|
||||
return std::move(children_token_);
|
||||
}
|
||||
|
||||
std::vector<util::signal<void>::subscription_token> container::release_child_tokens()
|
||||
std::vector<util::signal<>::subscription_token> container::release_child_tokens()
|
||||
{
|
||||
return std::move(child_tokens_);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ namespace psemek::ui::impl
|
|||
child_ = std::move(child);
|
||||
}
|
||||
|
||||
void single_container::set_child_token(util::signal<void>::subscription_token token)
|
||||
void single_container::set_child_token(util::signal<>::subscription_token token)
|
||||
{
|
||||
child_token_ = std::move(token);
|
||||
}
|
||||
|
|
@ -28,7 +28,7 @@ namespace psemek::ui::impl
|
|||
return std::move(child_);
|
||||
}
|
||||
|
||||
util::signal<void>::subscription_token single_container::release_child_token()
|
||||
util::signal<>::subscription_token single_container::release_child_token()
|
||||
{
|
||||
return std::move(child_token_);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,16 +2,17 @@
|
|||
|
||||
#include <psemek/util/function.hpp>
|
||||
|
||||
#include <list>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
namespace psemek::util
|
||||
{
|
||||
|
||||
template <typename T>
|
||||
template <typename ... Args>
|
||||
struct signal
|
||||
{
|
||||
using subscriber = function<void(T const &)>;
|
||||
using subscriber = function<void(Args const & ...)>;
|
||||
|
||||
using subscription_token = std::shared_ptr<void>;
|
||||
|
||||
[[nodiscard]] subscription_token subscribe(subscriber callback) const
|
||||
|
|
@ -21,59 +22,36 @@ namespace psemek::util
|
|||
return token;
|
||||
}
|
||||
|
||||
void operator()(T const & value)
|
||||
void operator()(Args const & ... args)
|
||||
{
|
||||
auto begin = subscribers_.begin();
|
||||
auto end = subscribers_.end();
|
||||
auto subscribers = std::move(subscribers_);
|
||||
|
||||
auto begin = subscribers.begin();
|
||||
auto end = subscribers.end();
|
||||
auto alive_end = begin;
|
||||
|
||||
for (auto it = begin; it != end;)
|
||||
{
|
||||
if (auto callback = it->lock())
|
||||
{
|
||||
(*callback)(value);
|
||||
(*callback)(args...);
|
||||
if (alive_end != it)
|
||||
*alive_end = std::move(*it);
|
||||
++it;
|
||||
++alive_end;
|
||||
}
|
||||
else
|
||||
it = subscribers_.erase(it);
|
||||
++it;
|
||||
}
|
||||
subscribers.erase(alive_end, end);
|
||||
|
||||
for (auto & s : subscribers_)
|
||||
subscribers.push_back(std::move(s));
|
||||
subscribers_ = std::move(subscribers);
|
||||
}
|
||||
|
||||
private:
|
||||
mutable std::list<std::weak_ptr<subscriber>> subscribers_;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct signal<void>
|
||||
{
|
||||
using subscriber = function<void()>;
|
||||
using subscription_token = std::shared_ptr<void>;
|
||||
|
||||
[[nodiscard]] subscription_token subscribe(subscriber callback) const
|
||||
{
|
||||
auto token = std::make_shared<subscriber>(std::move(callback));
|
||||
subscribers_.push_back(std::weak_ptr{token});
|
||||
return token;
|
||||
}
|
||||
|
||||
void operator()()
|
||||
{
|
||||
auto begin = subscribers_.begin();
|
||||
auto end = subscribers_.end();
|
||||
|
||||
for (auto it = begin; it != end;)
|
||||
{
|
||||
if (auto callback = it->lock())
|
||||
{
|
||||
(*callback)();
|
||||
++it;
|
||||
}
|
||||
else
|
||||
it = subscribers_.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
mutable std::list<std::weak_ptr<subscriber>> subscribers_;
|
||||
mutable std::vector<std::weak_ptr<subscriber>> subscribers_;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue