From a3b75c174570813ca0bc640598d6424d8917da01 Mon Sep 17 00:00:00 2001 From: Michele Caini Date: Thu, 14 Jul 2016 22:36:20 +0200 Subject: [PATCH] added common base class Resource for Request and Handle --- src/uvw.hpp | 1 + src/uvw/async.hpp | 2 +- src/uvw/check.hpp | 2 +- src/uvw/handle.hpp | 86 ++++++++++++-------------------------------- src/uvw/idle.hpp | 2 +- src/uvw/loop.hpp | 2 +- src/uvw/prepare.hpp | 2 +- src/uvw/request.hpp | 24 +++++-------- src/uvw/resource.hpp | 79 ++++++++++++++++++++++++++++++++++++++++ src/uvw/signal.hpp | 2 +- src/uvw/stream.hpp | 5 ++- src/uvw/tcp.hpp | 2 +- src/uvw/timer.hpp | 2 +- src/uvw/tty.hpp | 2 +- 14 files changed, 122 insertions(+), 91 deletions(-) create mode 100644 src/uvw/resource.hpp diff --git a/src/uvw.hpp b/src/uvw.hpp index 52900628..b672220a 100644 --- a/src/uvw.hpp +++ b/src/uvw.hpp @@ -7,6 +7,7 @@ #include "uvw/loop.hpp" #include "uvw/prepare.hpp" #include "uvw/request.hpp" +#include "uvw/resource.hpp" #include "uvw/self.hpp" #include "uvw/signal.hpp" #include "uvw/stream.hpp" diff --git a/src/uvw/async.hpp b/src/uvw/async.hpp index 23f4a5e6..ab9c521a 100644 --- a/src/uvw/async.hpp +++ b/src/uvw/async.hpp @@ -19,7 +19,7 @@ class Async final: public Handle { } explicit Async(std::shared_ptr ref) - : Handle{HandleType{}, std::move(ref)} + : Handle{ResourceType{}, std::move(ref)} { } public: diff --git a/src/uvw/check.hpp b/src/uvw/check.hpp index fc6a2f06..920e802c 100644 --- a/src/uvw/check.hpp +++ b/src/uvw/check.hpp @@ -19,7 +19,7 @@ class Check final: public Handle { } explicit Check(std::shared_ptr ref) - : Handle{HandleType{}, std::move(ref)} + : Handle{ResourceType{}, std::move(ref)} { } public: diff --git a/src/uvw/handle.hpp b/src/uvw/handle.hpp index ef59b779..7f105d51 100644 --- a/src/uvw/handle.hpp +++ b/src/uvw/handle.hpp @@ -4,42 +4,14 @@ #include #include #include -#include "emitter.hpp" -#include "self.hpp" -#include "loop.hpp" +#include "resource.hpp" namespace uvw { -template -struct HandleType; - -template<> struct HandleType { }; -template<> struct HandleType { }; -template<> struct HandleType { }; -template<> struct HandleType { }; -template<> struct HandleType { }; -template<> struct HandleType { }; -template<> struct HandleType { }; -template<> struct HandleType { }; - - template -class Handle: public BaseHandle, public Emitter, public Self { - struct BaseWrapper { - virtual ~BaseWrapper() = default; - virtual void * get() const noexcept = 0; - }; - - template - struct Wrapper: BaseWrapper { - Wrapper(): handle{std::make_unique()} { } - void * get() const noexcept override { return handle.get(); } - private: - std::unique_ptr handle; - }; - +class Handle: public BaseHandle, public Resource { static void closeCallback(uv_handle_t *handle) { Handle &ref = *(static_cast(handle->data)); auto ptr = ref.shared_from_this(); @@ -49,25 +21,15 @@ class Handle: public BaseHandle, public Emitter, public Self { protected: template - explicit Handle(HandleType, std::shared_ptr ref) + explicit Handle(ResourceType rt, std::shared_ptr ref) : BaseHandle{}, - Emitter{}, - Self{}, - wrapper{std::make_unique>()}, - pLoop{std::move(ref)} - { - this->template get()->data = static_cast(this); - } - - uv_loop_t* parent() const noexcept { return pLoop->loop.get(); } - - template - U* get() const noexcept { return reinterpret_cast(wrapper->get()); } + Resource{std::move(rt), std::move(ref)} + { } template bool initialize(F &&f, Args&&... args) { if(!this->self()) { - auto err = std::forward(f)(parent(), get(), std::forward(args)...); + auto err = std::forward(f)(this->parent(), this->template get(), std::forward(args)...); if(err) { this->publish(ErrorEvent{err}); @@ -79,36 +41,32 @@ protected: return this->self(); } - template - auto invoke(F &&f, Args&&... args) { - auto err = std::forward(f)(std::forward(args)...); - if(err) { Emitter::publish(ErrorEvent{err}); } - return err; - } - public: - virtual ~Handle() { - static_assert(std::is_base_of, T>::value, "!"); + bool active() const noexcept override { + return !(uv_is_active(this->template get()) == 0); } - Loop& loop() const noexcept { return *pLoop; } + bool closing() const noexcept override { + return !(uv_is_closing(this->template get()) == 0); + } - bool active() const noexcept override { return !(uv_is_active(get()) == 0); } - bool closing() const noexcept override { return !(uv_is_closing(get()) == 0); } + void reference() noexcept override { + uv_ref(this->template get()); + } - void reference() noexcept override { uv_ref(get()); } - void unreference() noexcept override { uv_unref(get()); } - bool referenced() const noexcept override { return !(uv_has_ref(get()) == 0); } + void unreference() noexcept override { + uv_unref(this->template get()); + } + + bool referenced() const noexcept override { + return !(uv_has_ref(this->template get()) == 0); + } void close() noexcept override { if(!closing()) { - uv_close(get(), &Handle::closeCallback); + uv_close(this->template get(), &Handle::closeCallback); } } - -private: - std::unique_ptr wrapper; - std::shared_ptr pLoop; }; diff --git a/src/uvw/idle.hpp b/src/uvw/idle.hpp index 8374bb57..2d175f79 100644 --- a/src/uvw/idle.hpp +++ b/src/uvw/idle.hpp @@ -19,7 +19,7 @@ class Idle final: public Handle { } explicit Idle(std::shared_ptr ref) - : Handle{HandleType{}, std::move(ref)} + : Handle{ResourceType{}, std::move(ref)} { } public: diff --git a/src/uvw/loop.hpp b/src/uvw/loop.hpp index b01095dd..95f4b08f 100644 --- a/src/uvw/loop.hpp +++ b/src/uvw/loop.hpp @@ -26,7 +26,7 @@ public: class Loop final: public Emitter, public std::enable_shared_from_this { template - friend class Handle; + friend class Resource; using Deleter = std::function; diff --git a/src/uvw/prepare.hpp b/src/uvw/prepare.hpp index 0929dee2..c5948494 100644 --- a/src/uvw/prepare.hpp +++ b/src/uvw/prepare.hpp @@ -19,7 +19,7 @@ class Prepare final: public Handle { } explicit Prepare(std::shared_ptr ref) - : Handle{HandleType{}, std::move(ref)} + : Handle{ResourceType{}, std::move(ref)} { } public: diff --git a/src/uvw/request.hpp b/src/uvw/request.hpp index a50a8da6..3a37a723 100644 --- a/src/uvw/request.hpp +++ b/src/uvw/request.hpp @@ -1,28 +1,22 @@ #pragma once +#include +#include #include +#include "resource.hpp" namespace uvw { -template -struct RequestType; - -template<> struct RequestType { }; -template<> struct RequestType { }; -template<> struct RequestType { }; -template<> struct RequestType { }; -template<> struct RequestType { }; -template<> struct RequestType { }; -template<> struct RequestType { }; -template<> struct RequestType { }; - - template -struct Request: T { - // TODO room for a pointer to a memory pool and a better memory management +class Request: public Resource { +protected: + template + explicit Request(ResourceType rt, std::shared_ptr ref) + : Resource{std::move(rt), std::move(ref)} + { } }; diff --git a/src/uvw/resource.hpp b/src/uvw/resource.hpp new file mode 100644 index 00000000..d09e892e --- /dev/null +++ b/src/uvw/resource.hpp @@ -0,0 +1,79 @@ +#pragma once + + +#include +#include +#include +#include "emitter.hpp" +#include "self.hpp" +#include "loop.hpp" + + +namespace uvw { + + +template +struct ResourceType; + +template<> struct ResourceType { }; +template<> struct ResourceType { }; +template<> struct ResourceType { }; +template<> struct ResourceType { }; +template<> struct ResourceType { }; +template<> struct ResourceType { }; +template<> struct ResourceType { }; +template<> struct ResourceType { }; + + +template +class Resource: public Emitter, public Self { + struct BaseWrapper { + virtual ~BaseWrapper() = default; + virtual void * get() const noexcept = 0; + }; + + template + struct Wrapper: BaseWrapper { + Wrapper(): resource{std::make_unique()} { } + void * get() const noexcept override { return resource.get(); } + private: + std::unique_ptr resource; + }; + +protected: + template + explicit Resource(ResourceType, std::shared_ptr ref) + : Emitter{}, + Self{}, + wrapper{std::make_unique>()}, + pLoop{std::move(ref)} + { + this->template get()->data = static_cast(this); + } + + uv_loop_t* parent() const noexcept { return pLoop->loop.get(); } + + template + U* get() const noexcept { return reinterpret_cast(wrapper->get()); } + + template + auto invoke(F &&f, Args&&... args) { + auto err = std::forward(f)(std::forward(args)...); + if(err) { Emitter::publish(ErrorEvent{err}); } + return err; + } + +public: + virtual ~Resource() { + static_assert(std::is_base_of, T>::value, "!"); + } + + Loop& loop() const noexcept { return *pLoop; } + +private: + std::unique_ptr wrapper; + std::shared_ptr pLoop; +}; + + +} diff --git a/src/uvw/signal.hpp b/src/uvw/signal.hpp index 66747061..5a7a20e2 100644 --- a/src/uvw/signal.hpp +++ b/src/uvw/signal.hpp @@ -19,7 +19,7 @@ class Signal final: public Handle { } explicit Signal(std::shared_ptr ref) - : Handle{HandleType{}, std::move(ref)} + : Handle{ResourceType{}, std::move(ref)} { } public: diff --git a/src/uvw/stream.hpp b/src/uvw/stream.hpp index 3c0adf01..20947f73 100644 --- a/src/uvw/stream.hpp +++ b/src/uvw/stream.hpp @@ -57,9 +57,8 @@ class Stream: public Handle { protected: template - Stream(HandleType rt, std::shared_ptr ref) - : Handle{std::move(rt), - std::move(ref)}, + Stream(ResourceType rt, std::shared_ptr ref) + : Handle{std::move(rt), std::move(ref)}, sdown{std::make_unique()} { } diff --git a/src/uvw/tcp.hpp b/src/uvw/tcp.hpp index ec31b91c..969db4ab 100644 --- a/src/uvw/tcp.hpp +++ b/src/uvw/tcp.hpp @@ -22,7 +22,7 @@ class Tcp final: public Stream { } explicit Tcp(std::shared_ptr ref) - : Stream{HandleType{}, std::move(ref)}, + : Stream{ResourceType{}, std::move(ref)}, conn{std::make_unique()} { } diff --git a/src/uvw/timer.hpp b/src/uvw/timer.hpp index c321af80..37747755 100644 --- a/src/uvw/timer.hpp +++ b/src/uvw/timer.hpp @@ -20,7 +20,7 @@ class Timer final: public Handle { } explicit Timer(std::shared_ptr ref) - : Handle{HandleType{}, std::move(ref)} + : Handle{ResourceType{}, std::move(ref)} { } public: diff --git a/src/uvw/tty.hpp b/src/uvw/tty.hpp index 2a7ecc24..243fd949 100644 --- a/src/uvw/tty.hpp +++ b/src/uvw/tty.hpp @@ -31,7 +31,7 @@ class TTY final: public Stream { explicit TTY(std::shared_ptr ref, details::FileDescriptor, bool readable) - : Stream{HandleType{}, std::move(ref)}, + : Stream{ResourceType{}, std::move(ref)}, fd{FD}, rw{readable ? 1 : 0} { }