Switch name Producer/Consumer -> Sender/Receiver

The producer/consumer was created for:
https://github.com/ArthurSonzogni/FTXUI/pull/11

This patch makes rename everything from Producer/Consumer toward
Sender/Receiver.
This commit is contained in:
ArthurSonzogni
2020-03-25 00:07:41 +01:00
parent 09a1b16613
commit 0a7b556a12
7 changed files with 128 additions and 126 deletions

View File

@@ -2,10 +2,10 @@
#define FTXUI_COMPONENT_EVENT_HPP
#include <array>
#include <ftxui/component/receiver.hpp>
#include <functional>
#include <string>
#include <vector>
#include <ftxui/component/producer_consumer.hpp>
namespace ftxui {
@@ -21,7 +21,7 @@ struct Event {
static Event Character(const std::string&);
static Event Special(const std::string&);
static void Convert(Consumer<char>& in, Producer<Event>& out, char c);
static void Convert(Receiver<char>& in, Sender<Event>& out, char c);
// --- Arrow ---
static Event ArrowLeft;

View File

@@ -1,101 +0,0 @@
#ifndef FTXUI_COMPONENTS_CONSUMER_PRODUCER_H_
#define FTXUI_COMPONENTS_CONSUMER_PRODUCER_H_
#include <atomic>
#include <condition_variable>
#include <functional>
#include <memory>
#include <mutex>
#include <queue>
namespace ftxui {
// Usage:
//
// Initialization:
// ---------------
//
// auto consumer = MakeConsumer<std:string>();
// auto producer_1 = consumer.MakeProducer();
// auto producer_2 = consumer.MakeProducer();
//
// Then move one producers elsewhere, potentially in a different thread.
// ----------------------
// [thread 1] producer_1->Send("hello");
// [thread 2] producer_2->Send("world");
//
// On the consumer side:
// ---------------------
// char c;
// while(consumer_->Receive(&c)) // Return true as long as there is a producer.
// print(c)
//
// Consumer::Receive returns true when the last Producer is released.
// clang-format off
template<class T> class ProducerImpl;
template<class T> class ConsumerImpl;
template<class T> using Producer = std::unique_ptr<ProducerImpl<T>>;
template<class T> using Consumer = std::unique_ptr<ConsumerImpl<T>>;
template<class T> Consumer<T> MakeConsumer();
// clang-format on
// ---- Implementation part ----
template <class T>
class ProducerImpl {
public:
void Send(T t) { consumer_->Receive(std::move(t)); }
~ProducerImpl() { consumer_->producers_--; }
private:
friend class ConsumerImpl<T>;
ProducerImpl(ConsumerImpl<T>* consumer) : consumer_(consumer) {}
ConsumerImpl<T>* consumer_;
};
template <class T>
class ConsumerImpl {
public:
Producer<T> MakeProducer() {
producers_++;
return std::unique_ptr<ProducerImpl<T>>(new ProducerImpl<T>(this));
}
bool Receive(T* t) {
while (producers_) {
std::unique_lock<std::mutex> lock(mutex_);
while (queue_.empty())
notifier_.wait(lock);
if (queue_.empty())
continue;
*t = std::move(queue_.front());
queue_.pop();
return true;
}
return false;
}
private:
friend class ProducerImpl<T>;
void Receive(T t) {
std::unique_lock<std::mutex> lock(mutex_);
queue_.push(std::move(t));
notifier_.notify_one();
}
std::mutex mutex_;
std::queue<T> queue_;
std::condition_variable notifier_;
std::atomic<int> producers_ = 0;
};
template <class T>
Consumer<T> MakeConsumer() {
return std::make_unique<ConsumerImpl<T>>();
}
} // namespace ftxui
#endif // FTXUI_COMPONENTS_CONSUMER_PRODUCER_H_

View File

@@ -0,0 +1,103 @@
#ifndef FTXUI_COMPONENT_RECEIVER_HPP_
#define FTXUI_COMPONENT_RECEIVER_HPP_
#include <atomic>
#include <condition_variable>
#include <functional>
#include <memory>
#include <mutex>
#include <queue>
namespace ftxui {
// Usage:
//
// Initialization:
// ---------------
//
// auto receiver = MakeReceiver<std:string>();
// auto sender_1= receiver.MakeSender();
// auto sender_2 = receiver.MakeSender();
//
// Then move the senders elsewhere, potentially in a different thread.
//
// On the producer side:
// ----------------------
// [thread 1] sender_1->Send("hello");
// [thread 2] sender_2->Send("world");
//
// On the consumer side:
// ---------------------
// char c;
// while(receiver->Receive(&c)) // Return true as long as there is a producer.
// print(c)
//
// Receiver::Receive() returns true when there are no more senders.
// clang-format off
template<class T> class SenderImpl;
template<class T> class ReceiverImpl;
template<class T> using Sender = std::unique_ptr<SenderImpl<T>>;
template<class T> using Receiver = std::unique_ptr<ReceiverImpl<T>>;
template<class T> Receiver<T> MakeReceiver();
// clang-format on
// ---- Implementation part ----
template <class T>
class SenderImpl {
public:
void Send(T t) { sender_->Receive(std::move(t)); }
~SenderImpl() { sender_->senders_--; }
private:
friend class ReceiverImpl<T>;
SenderImpl(ReceiverImpl<T>* consumer) : sender_(consumer) {}
ReceiverImpl<T>* sender_;
};
template <class T>
class ReceiverImpl {
public:
Sender<T> MakeSender() {
senders_++;
return std::unique_ptr<SenderImpl<T>>(new SenderImpl<T>(this));
}
bool Receive(T* t) {
while (senders_) {
std::unique_lock<std::mutex> lock(mutex_);
while (queue_.empty())
notifier_.wait(lock);
if (queue_.empty())
continue;
*t = std::move(queue_.front());
queue_.pop();
return true;
}
return false;
}
private:
friend class SenderImpl<T>;
void Receive(T t) {
std::unique_lock<std::mutex> lock(mutex_);
queue_.push(std::move(t));
notifier_.notify_one();
}
std::mutex mutex_;
std::queue<T> queue_;
std::condition_variable notifier_;
std::atomic<int> senders_ = 0;
};
template <class T>
Receiver<T> MakeReceiver() {
return std::make_unique<ReceiverImpl<T>>();
}
} // namespace ftxui
#endif // FTXUI_COMPONENT_RECEIVER_HPP_

View File

@@ -3,6 +3,7 @@
#include <atomic>
#include <condition_variable>
#include <ftxui/component/receiver.hpp>
#include <functional>
#include <memory>
#include <mutex>
@@ -10,7 +11,6 @@
#include "ftxui/component/event.hpp"
#include "ftxui/screen/screen.hpp"
#include <ftxui/component/producer_consumer.hpp>
namespace ftxui {
class Component;
@@ -41,13 +41,13 @@ class ScreenInteractive : public Screen {
Dimension dimension_ = Dimension::Fixed;
ScreenInteractive(int dimx, int dimy, Dimension dimension);
Producer<Event> event_producer_;
Consumer<Event> event_consumer_;
Sender<Event> event_sender_;
Receiver<Event> event_receiver_;
std::string set_cursor_position;
std::string reset_cursor_position;
std::atomic<bool>quit_ = false;
std::atomic<bool> quit_ = false;
};
} // namespace ftxui