clean up + refactoring

This commit is contained in:
Michele Caini 2016-07-04 10:19:18 +02:00
parent 36613e5009
commit 0bb792262e
8 changed files with 62 additions and 174 deletions

View File

@ -13,7 +13,8 @@ namespace uvw {
class Check final: public Handle<Check> {
static void startCallback(Check &check, uv_check_t *) {
static void startCallback(uv_check_t *handle) {
Check &check = *(static_cast<Check*>(handle->data));
check.publish(CheckEvent{});
}
@ -25,24 +26,10 @@ public:
return std::shared_ptr<Check>{new Check{std::forward<Args>(args)...}};
}
bool init() {
return Handle<Check>::init<uv_check_t>(&uv_check_init);
}
bool init() { return initialize<uv_check_t>(&uv_check_init); }
void start() {
using CBF = CallbackFactory<void(uv_check_t *)>;
auto func = &CBF::template proto<&Check::startCallback>;
auto err = uv_check_start(get<uv_check_t>(), func);
if(err) publish(ErrorEvent{err});
}
void stop() {
auto err = uv_check_stop(get<uv_check_t>());
if(err) publish(ErrorEvent{err});
}
private:
bool initialized = false;
void start() { invoke(&uv_check_start, get<uv_check_t>(), &startCallback); }
void stop() { invoke(&uv_check_stop, get<uv_check_t>()); }
};

View File

@ -12,26 +12,6 @@
namespace uvw {
namespace details {
template<typename T> void* get(T *handle) { return handle->data; }
void* get(uv_connect_t *conn) { return conn->handle->data; }
template<typename, typename>
struct UVCallbackFactory;
template<typename T, typename H, typename... Args>
struct UVCallbackFactory<T, void(H, Args...)> {
template<void(*F)(T &, H, Args...)>
static void proto(H, Args...) noexcept;
};
}
template<typename>
struct HandleType;
@ -44,9 +24,6 @@ template<> struct HandleType<uv_tcp_t> { };
template<typename T>
class Handle: public Emitter<T>, public Self<T> {
template<typename, typename>
friend struct details::UVCallbackFactory;
struct BaseWrapper {
virtual ~BaseWrapper() = default;
virtual void * get() const noexcept = 0;
@ -60,15 +37,13 @@ class Handle: public Emitter<T>, public Self<T> {
std::unique_ptr<U> handle;
};
static void closeCallback(T &ref, uv_handle_t *) {
static void closeCallback(uv_handle_t *handle) {
T &ref = *(static_cast<T*>(handle->data));
ref.publish(CloseEvent{});
ref.reset();
}
protected:
template<typename F>
using CallbackFactory = details::UVCallbackFactory<T, F>;
template<typename U>
explicit Handle(HandleType<U>, std::shared_ptr<Loop> ref)
: Emitter<T>{}, Self<T>{},
@ -84,7 +59,7 @@ protected:
U* get() const noexcept { return reinterpret_cast<U*>(wrapper->get()); }
template<typename U, typename F>
bool init(F &&f) {
bool initialize(F &&f) {
bool ret = true;
if(!active()) {
@ -101,6 +76,12 @@ protected:
return ret;
}
template<typename F, typename... Args>
void invoke(F &&f, Args&&... args) {
auto err = std::forward<F>(f)(std::forward<Args>(args)...);
if(err) { Emitter<T>::publish(ErrorEvent{err}); }
}
public:
virtual ~Handle() {
static_assert(std::is_base_of<Handle<T>, T>::value, "!");
@ -117,9 +98,7 @@ public:
void close() noexcept {
if(!closing()) {
using CBF = CallbackFactory<void(uv_handle_t *)>;
auto func = &CBF::template proto<&Handle<T>::closeCallback>;
uv_close(get<uv_handle_t>(), func);
uv_close(get<uv_handle_t>(), &Handle<T>::closeCallback);
}
}
@ -129,18 +108,4 @@ private:
};
namespace details {
template<typename T, typename H, typename... Args>
template<void(*F)(T &, H, Args...)>
void UVCallbackFactory<T, void(H, Args...)>::proto(H handle, Args... args) noexcept {
T &ref = *(static_cast<T*>(details::get(handle)));
F(ref, handle, args...);
}
}
}

View File

@ -13,7 +13,8 @@ namespace uvw {
class Idle final: public Handle<Idle> {
static void startCallback(Idle &idle, uv_idle_t *) {
static void startCallback(uv_idle_t *handle) {
Idle &idle = *(static_cast<Idle*>(handle->data));
idle.publish(IdleEvent{});
}
@ -25,21 +26,10 @@ public:
return std::shared_ptr<Idle>{new Idle{std::forward<Args>(args)...}};
}
bool init() {
return Handle<Idle>::init<uv_idle_t>(&uv_idle_init);
}
bool init() { return initialize<uv_idle_t>(&uv_idle_init); }
void start() {
using CBF = CallbackFactory<void(uv_idle_t *)>;
auto func = &CBF::template proto<&Idle::startCallback>;
auto err = uv_idle_start(get<uv_idle_t>(), func);
if(err) publish(ErrorEvent{err});
}
void stop() {
auto err = uv_idle_stop(get<uv_idle_t>());
if(err) publish(ErrorEvent{err});
}
void start() { invoke(&uv_idle_start, get<uv_idle_t>(), &startCallback); }
void stop() { invoke(&uv_idle_stop, get<uv_idle_t>()); }
};

View File

@ -73,7 +73,7 @@ public:
void close() noexcept {
auto err = uv_loop_close(loop.get());
if(err) publish(ErrorEvent{err});
if(err) { publish(ErrorEvent{err}); }
}
bool run() noexcept {

View File

@ -13,7 +13,8 @@ namespace uvw {
class Prepare final: public Handle<Prepare> {
static void startCallback(Prepare &prepare, uv_prepare_t *) {
static void startCallback(uv_prepare_t *handle) {
Prepare &prepare = *(static_cast<Prepare*>(handle->data));
prepare.publish(PrepareEvent{});
}
@ -25,21 +26,10 @@ public:
return std::shared_ptr<Prepare>{new Prepare{std::forward<Args>(args)...}};
}
bool init() {
return Handle<Prepare>::init<uv_prepare_t>(&uv_prepare_init);
}
bool init() { return initialize<uv_prepare_t>(&uv_prepare_init); }
void start() {
using CBF = CallbackFactory<void(uv_prepare_t *)>;
auto func = &CBF::template proto<&Prepare::startCallback>;
auto err = uv_prepare_start(get<uv_prepare_t>(), func);
if(err) publish(ErrorEvent{err});
}
void stop() {
auto err = uv_prepare_stop(get<uv_prepare_t>());
if(err) publish(ErrorEvent{err});
}
void start() { invoke(&uv_prepare_start, get<uv_prepare_t>(), &startCallback); }
void stop() { invoke(&uv_prepare_stop, get<uv_prepare_t>()); }
};

View File

@ -18,12 +18,13 @@ template<typename T>
class Stream: public Handle<T> {
static constexpr unsigned int DEFAULT_BACKLOG = 128;
static void allocCallback(T &, uv_handle_t *, std::size_t suggested, uv_buf_t *buf) {
static void allocCallback(uv_handle_t *, std::size_t suggested, uv_buf_t *buf) {
buf->base = new char[suggested];
buf->len = suggested;
}
static void readCallback(T &ref, uv_stream_t *, ssize_t nread, const uv_buf_t *cbuf) {
static void readCallback(uv_stream_t *handle, ssize_t nread, const uv_buf_t *cbuf) {
T &ref = *(static_cast<T*>(handle->data));
uv_buf_t *buf = const_cast<uv_buf_t *>(cbuf);
if(nread == UV_EOF) {
@ -43,22 +44,21 @@ class Stream: public Handle<T> {
buf->len = 0;
}
static void writeCallback(T &ref, uv_write_t *req, int status) {
if(status) {
ref.publish(ErrorEvent{status});
} else {
ref.publish(WriteEvent{});
}
static void writeCallback(uv_write_t *req, int status) {
T &ref = *(static_cast<T*>(req->handle->data));
if(status) { ref.publish(ErrorEvent{status}); }
else { ref.publish(WriteEvent{}); }
delete req;
}
static void shutdownCallback(T &ref, uv_shutdown_t *, int status) {
if(status) ref.publish(ErrorEvent{status});
else ref.publish(ShutdownEvent{});
static void shutdownCallback(uv_shutdown_t *req, int status) {
T &ref = *(static_cast<T*>(req->handle->data));
if(status) { ref.publish(ErrorEvent{status}); }
else { ref.publish(ShutdownEvent{}); }
}
static void listenCallback(T &ref, uv_stream_t *, int status) {
static void listenCallback(uv_stream_t *handle, int status) {
T &ref = *(static_cast<T*>(handle->data));
if(status) ref.publish(ErrorEvent{status});
else ref.publish(ListenEvent{});
}
@ -71,17 +71,11 @@ protected:
public:
void shutdown() noexcept {
using CBF = typename Handle<T>::template CallbackFactory<void(uv_shutdown_t *, int)>;
auto func = &CBF::template proto<&Stream<T>::shutdownCallback>;
auto err = uv_shutdown(sdown.get(), this->template get<uv_stream_t>(), func);
if(err) this->publish(ErrorEvent{err});
this->invoke(&uv_shutdown, sdown.get(), this->template get<uv_stream_t>(), &shutdownCallback);
}
void listen(int backlog) noexcept {
using CBF = typename Handle<T>::template CallbackFactory<void(uv_stream_t *, int)>;
auto func = &CBF::template proto<&Stream<T>::listenCallback>;
auto err = uv_listen(this->template get<uv_stream_t>(), backlog, func);
if(err) this->publish(ErrorEvent{err});
this->invoke(&uv_listen, this->template get<uv_stream_t>(), backlog, &listenCallback);
}
void listen() noexcept {
@ -89,25 +83,17 @@ public:
}
void read() {
using CBFAlloc = typename Handle<T>::template CallbackFactory<void(uv_handle_t *, std::size_t, uv_buf_t *)>;
using CBFRead = typename Handle<T>::template CallbackFactory<void(uv_stream_t *, ssize_t, const uv_buf_t *)>;
auto allocFunc = &CBFAlloc::template proto<&Stream<T>::allocCallback>;
auto readFunc = &CBFRead::template proto<&Stream<T>::readCallback>;
auto err = uv_read_start(this->template get<uv_stream_t>(), allocFunc, readFunc);
if(err) this->publish(ErrorEvent{err});
this->invoke(&uv_read_start, this->template get<uv_stream_t>(), &allocCallback, &readCallback);
}
void stop() noexcept {
auto err = uv_read_stop(this->template get<uv_stream_t>());
if(err) this->publish(ErrorEvent{err});
this->invoke(&uv_read_stop, this->template get<uv_stream_t>());
}
void write(Buffer buf) {
using CBF = typename Handle<T>::template CallbackFactory<void(uv_write_t *, int)>;
auto func = &CBF::template proto<&Stream<T>::writeCallback>;
uv_buf_t data[] = { buf.uvBuf() };
uv_write_t *req = new uv_write_t;
auto err = uv_write(req, this->template get<uv_stream_t>(), data, 1, func);
auto err = uv_write(req, this->template get<uv_stream_t>(), data, 1, &Stream<T>::writeCallback);
if(err) {
delete req;
this->publish(ErrorEvent{err});

View File

@ -15,9 +15,10 @@ namespace uvw {
class Tcp final: public Stream<Tcp> {
static void connectCallback(Tcp &tcp, uv_connect_t *, int status) {
if(status) tcp.publish(ErrorEvent{status});
else tcp.publish(ConnectEvent{});
static void connectCallback(uv_connect_t *req, int status) {
Tcp &tcp = *(static_cast<Tcp*>(req->handle->data));
if(status) { tcp.publish(ErrorEvent{status}); }
else { tcp.publish(ConnectEvent{}); }
}
explicit Tcp(std::shared_ptr<Loop> ref)
@ -61,18 +62,14 @@ public:
return std::shared_ptr<Tcp>{new Tcp{std::forward<Args>(args)...}};
}
bool init() {
return Stream<Tcp>::init<uv_tcp_t>(&uv_tcp_init);
}
bool init() { return initialize<uv_tcp_t>(&uv_tcp_init); }
void noDelay(bool value = false) noexcept {
auto err = uv_tcp_nodelay(get<uv_tcp_t>(), value ? 1 : 0);
if(err) publish(ErrorEvent{err});
invoke(&uv_tcp_nodelay, get<uv_tcp_t>(), value ? 1 : 0);
}
void keepAlive(bool enable = false, Time time = Time{0}) noexcept {
auto err = uv_tcp_keepalive(get<uv_tcp_t>(), enable ? 1 : 0, time.count());
if(err) publish(ErrorEvent{err});
invoke(&uv_tcp_keepalive, get<uv_tcp_t>(), enable ? 1 : 0, time.count());
}
template<typename I, typename..., typename Traits = details::IpTraits<I>>
@ -80,8 +77,7 @@ public:
typename Traits::Type addr;
Traits::AddrFunc(ip.c_str(), port, &addr);
unsigned int flags = ipv6only ? UV_TCP_IPV6ONLY : 0;
auto err = uv_tcp_bind(get<uv_tcp_t>(), reinterpret_cast<const sockaddr *>(&addr), flags);
if(err) publish(ErrorEvent{err});
invoke(&uv_tcp_bind, get<uv_tcp_t>(), reinterpret_cast<const sockaddr *>(&addr), flags);
}
template<typename I, typename..., typename Traits = details::IpTraits<I>>
@ -103,10 +99,7 @@ public:
void connect(std::string ip, unsigned int port) noexcept {
typename Traits::Type addr;
Traits::AddrFunc(ip.c_str(), port, &addr);
using CBF = CallbackFactory<void(uv_connect_t *, int)>;
auto func = &CBF::proto<&Tcp::connectCallback>;
auto err = uv_tcp_connect(conn.get(), get<uv_tcp_t>(), reinterpret_cast<const sockaddr *>(&addr), func);
if(err) publish(ErrorEvent{err});
invoke(&uv_tcp_connect, conn.get(), get<uv_tcp_t>(), reinterpret_cast<const sockaddr *>(&addr), &connectCallback);
}
template<typename I, typename..., typename Traits = details::IpTraits<I>>
@ -115,15 +108,11 @@ public:
}
void accept(Tcp &tcp) noexcept {
auto err = uv_accept(get<uv_stream_t>(), tcp.get<uv_stream_t>());
if(err) publish(ErrorEvent{err});
invoke(&uv_accept, get<uv_stream_t>(), tcp.get<uv_stream_t>());
}
explicit operator bool() const noexcept { return initialized; }
private:
std::unique_ptr<uv_connect_t> conn;
bool initialized;
};

View File

@ -14,7 +14,8 @@ namespace uvw {
class Timer final: public Handle<Timer> {
static void startCallback(Timer &timer, uv_timer_t *) {
static void startCallback(uv_timer_t *handle) {
Timer &timer = *(static_cast<Timer*>(handle->data));
timer.publish(TimerEvent{});
}
@ -28,34 +29,14 @@ public:
return std::shared_ptr<Timer>{new Timer{std::forward<Args>(args)...}};
}
bool init() {
return Handle<Timer>::init<uv_timer_t>(&uv_timer_init);
}
bool init() { return initialize<uv_timer_t>(&uv_timer_init); }
void start(Time timeout, Time repeat) {
using CBF = CallbackFactory<void(uv_timer_t *)>;
auto func = &CBF::template proto<&Timer::startCallback>;
auto err = uv_timer_start(get<uv_timer_t>(), func, timeout.count(), repeat.count());
if(err) publish(ErrorEvent{err});
}
void start(Time timeout, Time repeat) { invoke(uv_timer_start, get<uv_timer_t>(), &startCallback, timeout.count(), repeat.count()); }
void stop() { invoke(&uv_timer_stop, get<uv_timer_t>()); }
void again() { invoke(&uv_timer_again, get<uv_timer_t>()); }
void stop() {
auto err = uv_timer_stop(get<uv_timer_t>());
if(err) publish(ErrorEvent{err});
}
void again() {
auto err = uv_timer_again(get<uv_timer_t>());
if(err) publish(ErrorEvent{err});
}
void repeat(Time repeat) {
uv_timer_set_repeat(get<uv_timer_t>(), repeat.count());
}
Time repeat() {
return Time{uv_timer_get_repeat(get<uv_timer_t>())};
}
void repeat(Time repeat) { uv_timer_set_repeat(get<uv_timer_t>(), repeat.count()); }
Time repeat() { return Time{uv_timer_get_repeat(get<uv_timer_t>())}; }
};