FTXUI 6.1.9
C++ functional terminal UI.
Loading...
Searching...
No Matches
receiver.hpp
Go to the documentation of this file.
1// Copyright 2020 Arthur Sonzogni. All rights reserved.
2// Use of this source code is governed by the MIT license that can be found in
3// the LICENSE file.
4#ifndef FTXUI_COMPONENT_RECEIVER_HPP_
5#define FTXUI_COMPONENT_RECEIVER_HPP_
6
7#include <algorithm> // for copy, max
8#include <atomic> // for atomic, __atomic_base
9#include <condition_variable> // for condition_variable
10#include <memory> // for unique_ptr, make_unique
11#include <mutex> // for mutex, unique_lock
12#include <queue> // for queue
13#include <utility> // for move
14
15namespace ftxui {
16
17// Deprecated
18//
19// Usage:
20//
21// Initialization:
22// ---------------
23//
24// auto receiver = MakeReceiver<std:string>();
25// auto sender_1= receiver->MakeSender();
26// auto sender_2 = receiver->MakeSender();
27//
28// Then move the senders elsewhere, potentially in a different thread.
29//
30// On the producer side:
31// ----------------------
32// [thread 1] sender_1->Send("hello");
33// [thread 2] sender_2->Send("world");
34//
35// On the consumer side:
36// ---------------------
37// char c;
38// while(receiver->Receive(&c)) // Return true as long as there is a producer.
39// print(c)
40//
41// Receiver::Receive() returns true when there are no more senders.
42
43// clang-format off
44// Deprecated:
45template<class T> class SenderImpl;
46// Deprecated:
47template<class T> class ReceiverImpl;
48// Deprecated:
49
50// Deprecated:
51template<class T> using Sender = std::unique_ptr<SenderImpl<T>>;
52// Deprecated:
53template<class T> using Receiver = std::unique_ptr<ReceiverImpl<T>>;
54// Deprecated:
55template<class T> Receiver<T> MakeReceiver();
56// clang-format on
57
58// ---- Implementation part ----
59
60template <class T>
61// Deprecated:
63 public:
64 SenderImpl(const SenderImpl&) = delete;
66 SenderImpl& operator=(const SenderImpl&) = delete;
68 void Send(T t) { receiver_->Receive(std::move(t)); }
69 ~SenderImpl() { receiver_->ReleaseSender(); }
70
71 Sender<T> Clone() { return receiver_->MakeSender(); }
72
73 private:
74 friend class ReceiverImpl<T>;
75 explicit SenderImpl(ReceiverImpl<T>* consumer) : receiver_(consumer) {}
76 ReceiverImpl<T>* receiver_;
77};
78
79template <class T>
81 public:
83 std::unique_lock<std::mutex> lock(mutex_);
84 senders_++;
85 return std::unique_ptr<SenderImpl<T>>(new SenderImpl<T>(this));
86 }
87 ReceiverImpl() = default;
88
89 bool Receive(T* t) {
90 while (senders_ || !queue_.empty()) {
91 std::unique_lock<std::mutex> lock(mutex_);
92 if (queue_.empty()) {
93 notifier_.wait(lock);
94 }
95 if (queue_.empty()) {
96 continue;
97 }
98 *t = std::move(queue_.front());
99 queue_.pop();
100 return true;
101 }
102 return false;
103 }
104
106 std::unique_lock<std::mutex> lock(mutex_);
107 if (queue_.empty()) {
108 return false;
109 }
110 *t = queue_.front();
111 queue_.pop();
112 return true;
113 }
114
115 bool HasPending() {
116 std::unique_lock<std::mutex> lock(mutex_);
117 return !queue_.empty();
118 }
119
120 bool HasQuitted() {
121 std::unique_lock<std::mutex> lock(mutex_);
122 return queue_.empty() && !senders_;
123 }
124
125 private:
126 friend class SenderImpl<T>;
127
128 void Receive(T t) {
129 {
130 std::unique_lock<std::mutex> lock(mutex_);
131 queue_.push(std::move(t));
132 }
133 notifier_.notify_one();
134 }
135
136 void ReleaseSender() {
137 senders_--;
138 notifier_.notify_one();
139 }
140
141 std::mutex mutex_;
142 std::queue<T> queue_;
143 std::condition_variable notifier_;
144 std::atomic<int> senders_{0};
145};
146
147template <class T>
149 return std::make_unique<ReceiverImpl<T>>();
150}
151
152} // namespace ftxui
153
154#endif // FTXUI_COMPONENT_RECEIVER_HPP_
ReceiverImpl()=default
bool Receive(T *t)
Definition receiver.hpp:89
bool ReceiveNonBlocking(T *t)
Definition receiver.hpp:105
friend class SenderImpl< T >
Definition receiver.hpp:126
Sender< T > MakeSender()
Definition receiver.hpp:82
friend class ReceiverImpl< T >
Definition receiver.hpp:74
SenderImpl & operator=(const SenderImpl &)=delete
Sender< T > Clone()
Definition receiver.hpp:71
SenderImpl(SenderImpl &&)=delete
SenderImpl(const SenderImpl &)=delete
SenderImpl & operator=(SenderImpl &&)=delete
The FTXUI ftxui:: namespace.
Definition animation.hpp:10
Receiver< T > MakeReceiver()
Definition receiver.hpp:148
std::unique_ptr< ReceiverImpl< T > > Receiver
Definition receiver.hpp:53
std::unique_ptr< SenderImpl< T > > Sender
Definition receiver.hpp:51