WIP: more and more functionalities
This commit is contained in:
parent
928fb1269f
commit
79d2774ac5
@ -32,7 +32,7 @@ public:
|
||||
using CBF = CallbackFactory<void(uv_check_t *)>;
|
||||
auto func = CBF::on<&Check::startCallback>(*this, cb);
|
||||
auto err = uv_check_start(get<uv_check_t>(), func);
|
||||
if(err) { cb(UVWError{err}, *this); }
|
||||
if(err) { error(err); }
|
||||
}
|
||||
|
||||
UVWError stop() noexcept { return UVWError{uv_check_stop(get<uv_check_t>())}; }
|
||||
|
||||
@ -12,7 +12,6 @@
|
||||
namespace uvw {
|
||||
|
||||
|
||||
class BaseResource;
|
||||
class Loop;
|
||||
|
||||
|
||||
@ -50,9 +49,6 @@ public:
|
||||
constexpr operator R&() noexcept { return *res; }
|
||||
constexpr operator const R&() const noexcept { return *res; }
|
||||
|
||||
template<typename T, std::enable_if_t<std::is_base_of<T, R>::value>* = nullptr>
|
||||
constexpr operator Handle<T>() { return Handle<T>{res}; }
|
||||
|
||||
private:
|
||||
std::shared_ptr<R> res;
|
||||
};
|
||||
@ -109,6 +105,11 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
template<typename R>
|
||||
Handle<R> handle(std::shared_ptr<R> ptr) {
|
||||
return Handle<R>{std::move(ptr)};
|
||||
}
|
||||
|
||||
template<typename R, typename... Args>
|
||||
Handle<R> handle(Args&&... args) {
|
||||
return Handle<R>{shared_from_this(), std::forward<Args>(args)...};
|
||||
|
||||
@ -67,11 +67,18 @@ protected:
|
||||
|
||||
template<typename U>
|
||||
explicit Resource(HandleType<U>, std::shared_ptr<Loop> r)
|
||||
: pLoop{std::move(r)}, handle{std::make_shared<U>()}
|
||||
: uvHandle{std::make_shared<U>()}, pLoop{std::move(r)}
|
||||
{ }
|
||||
|
||||
void error(int error) {
|
||||
auto ptr = std::static_pointer_cast<T>(leak);
|
||||
auto cb = std::move(callback);
|
||||
leak.reset();
|
||||
cb(UVWError{error}, *ptr);
|
||||
}
|
||||
|
||||
template<typename U>
|
||||
U* get() const noexcept { return reinterpret_cast<U*>(handle.get()); }
|
||||
U* get() const noexcept { return reinterpret_cast<U*>(uvHandle.get()); }
|
||||
|
||||
uv_loop_t* parent() const noexcept { return pLoop->loop.get(); }
|
||||
|
||||
@ -84,7 +91,8 @@ public:
|
||||
void operator=(const Resource &) = delete;
|
||||
void operator=(Resource &&) = delete;
|
||||
|
||||
std::shared_ptr<Loop> loop() const noexcept { return pLoop; }
|
||||
Handle<T> handle() noexcept { return pLoop->handle(Resource<T>::shared_from_this()); }
|
||||
Loop& loop() const noexcept { return *pLoop; }
|
||||
|
||||
bool active() const noexcept { return !(uv_is_active(get<uv_handle_t>()) == 0); }
|
||||
bool closing() const noexcept { return !(uv_is_closing(get<uv_handle_t>()) == 0); }
|
||||
@ -100,8 +108,8 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
std::shared_ptr<void> uvHandle;
|
||||
std::shared_ptr<Loop> pLoop;
|
||||
std::shared_ptr<void> handle;
|
||||
std::shared_ptr<void> leak;
|
||||
std::function<void(UVWError, T &)> callback;
|
||||
};
|
||||
@ -134,7 +142,7 @@ template<typename T, typename H, typename... Args>
|
||||
template<void(*F)(T &, std::function<void(UVWError, T &)> &, H, Args...)>
|
||||
void UVCallbackFactory<T, void(H, Args...)>::protoOnce(H handle, Args... args) {
|
||||
T &ref = *(static_cast<T*>(details::get(handle)));
|
||||
std::shared_ptr<T> ptr = std::static_pointer_cast<T>(ref.leak);
|
||||
auto ptr = std::static_pointer_cast<T>(ref.leak);
|
||||
auto cb = std::move(ref.callback);
|
||||
ref.leak.reset();
|
||||
F(*ptr, cb, handle, std::forward<Args>(args)...);
|
||||
|
||||
@ -11,6 +11,8 @@ namespace uvw {
|
||||
|
||||
template<typename T>
|
||||
class Stream: public Resource<T> {
|
||||
static constexpr unsigned int DEFAULT_BACKLOG = 128;
|
||||
|
||||
static void listenCallback(T &t, std::function<void(UVWError, T &)> &cb, uv_stream_t *, int status) {
|
||||
cb(UVWError{status}, t);
|
||||
}
|
||||
@ -21,11 +23,15 @@ protected:
|
||||
public:
|
||||
// TODO shutdown
|
||||
|
||||
void listen(std::function<void(UVWError, T &)> cb) noexcept {
|
||||
listen(DEFAULT_BACKLOG, std::move(cb));
|
||||
}
|
||||
|
||||
void listen(int backlog, std::function<void(UVWError, T &)> cb) noexcept {
|
||||
using CBF = typename Resource<T>::template CallbackFactory<void(uv_stream_t *, int)>;
|
||||
auto func = CBF::on<&Stream<T>::listenCallback>(*static_cast<T*>(this), cb);
|
||||
auto func = CBF::template on<&Stream<T>::listenCallback>(*static_cast<T*>(this), cb);
|
||||
auto err = uv_listen(this->template get<uv_stream_t>(), backlog, func);
|
||||
if(err) { cb(UVWError{err}, *static_cast<T*>(this)); }
|
||||
if(err) { Stream<T>::error(err); }
|
||||
}
|
||||
|
||||
// TODO read
|
||||
|
||||
@ -34,7 +34,7 @@ class Tcp final: public Stream<Tcp> {
|
||||
public:
|
||||
using Time = std::chrono::duration<uint64_t>;
|
||||
|
||||
enum { IPv4, IPv6 };
|
||||
enum IP { IPv4, IPv6 };
|
||||
|
||||
template<typename... Args>
|
||||
static std::shared_ptr<Tcp> create(Args&&... args) {
|
||||
@ -49,8 +49,15 @@ public:
|
||||
return UVWError{uv_tcp_keepalive(get<uv_tcp_t>(), enable ? 1 : 0, time.count())};
|
||||
}
|
||||
|
||||
template<int>
|
||||
void connect(std::string, int, std::function<void(UVWError, Tcp &)>) noexcept;
|
||||
template<IP>
|
||||
UVWError bind(std::string, unsigned int, bool = false);
|
||||
|
||||
template<IP>
|
||||
void connect(std::string, unsigned int, std::function<void(UVWError, Tcp &)>) noexcept;
|
||||
|
||||
UVWError accept(Tcp &tcp) {
|
||||
return UVWError{uv_accept(get<uv_stream_t>(), tcp.get<uv_stream_t>())};
|
||||
}
|
||||
|
||||
explicit operator bool() { return initialized; }
|
||||
|
||||
@ -61,24 +68,41 @@ private:
|
||||
|
||||
|
||||
template<>
|
||||
void Tcp::connect<Tcp::IPv4>(std::string ip, int port, std::function<void(UVWError, Tcp &)> cb) noexcept {
|
||||
UVWError Tcp::bind<Tcp::IPv4>(std::string ip, unsigned int port, bool ipv6only) {
|
||||
sockaddr_in addr;
|
||||
uv_ip4_addr(ip.c_str(), port, &addr);
|
||||
unsigned int flags = ipv6only ? UV_TCP_IPV6ONLY : 0;
|
||||
return UVWError(uv_tcp_bind(get<uv_tcp_t>(), reinterpret_cast<const sockaddr*>(&addr), flags));}
|
||||
|
||||
|
||||
template<>
|
||||
UVWError Tcp::bind<Tcp::IPv6>(std::string ip, unsigned int port, bool ipv6only) {
|
||||
sockaddr_in6 addr;
|
||||
uv_ip6_addr(ip.c_str(), port, &addr);
|
||||
unsigned int flags = ipv6only ? UV_TCP_IPV6ONLY : 0;
|
||||
return UVWError(uv_tcp_bind(get<uv_tcp_t>(), reinterpret_cast<const sockaddr*>(&addr), flags));
|
||||
}
|
||||
|
||||
|
||||
template<>
|
||||
void Tcp::connect<Tcp::IPv4>(std::string ip, unsigned int port, std::function<void(UVWError, Tcp &)> cb) noexcept {
|
||||
sockaddr_in addr;
|
||||
uv_ip4_addr(ip.c_str(), port, &addr);
|
||||
using CBF = CallbackFactory<void(uv_connect_t *, int)>;
|
||||
auto func = CBF::template once<&Tcp::connectCallback>(*this, cb);
|
||||
auto err = uv_tcp_connect(conn.get(), get<uv_tcp_t>(), reinterpret_cast<const sockaddr*>(&addr), func);
|
||||
if(err) { cb(UVWError{err}, *this); }
|
||||
if(err) { error(err); }
|
||||
}
|
||||
|
||||
|
||||
template<>
|
||||
void Tcp::connect<Tcp::IPv6>(std::string ip, int port, std::function<void(UVWError, Tcp &)> cb) noexcept {
|
||||
void Tcp::connect<Tcp::IPv6>(std::string ip, unsigned int port, std::function<void(UVWError, Tcp &)> cb) noexcept {
|
||||
sockaddr_in6 addr;
|
||||
uv_ip6_addr(ip.c_str(), port, &addr);
|
||||
using CBF = CallbackFactory<void(uv_connect_t *, int)>;
|
||||
auto func = CBF::template once<&Tcp::connectCallback>(*this, cb);
|
||||
auto err = uv_tcp_connect(conn.get(), get<uv_tcp_t>(), reinterpret_cast<const sockaddr*>(&addr), func);
|
||||
if(err) { cb(UVWError{err}, *this); }
|
||||
if(err) { error(err); }
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -36,7 +36,7 @@ public:
|
||||
using CBF = CallbackFactory<void(uv_timer_t *)>;
|
||||
auto func = CBF::on<&Timer::startCallback>(*this, cb);
|
||||
auto err = uv_timer_start(get<uv_timer_t>(), func, timeout.count(), rep.count());
|
||||
if(err) { cb(UVWError{err}, *this); }
|
||||
if(err) { error(err); }
|
||||
}
|
||||
|
||||
UVWError stop() noexcept { return UVWError{uv_timer_stop(get<uv_timer_t>())}; }
|
||||
|
||||
@ -2,23 +2,67 @@
|
||||
#include <uvw.hpp>
|
||||
|
||||
|
||||
void f(uvw::Loop &loop) {
|
||||
void listen(uvw::Loop &loop) {
|
||||
uvw::Handle<uvw::Tcp> handle = loop.handle<uvw::Tcp>();
|
||||
|
||||
auto cb = [](uvw::UVWError err, uvw::Tcp &tcp) mutable {
|
||||
std::cout << "---" << ((bool)err) << std::endl;
|
||||
tcp.close([](uvw::UVWError err, uvw::Tcp &) mutable {
|
||||
std::cout << "---" << ((bool)err) << std::endl;
|
||||
});
|
||||
auto cb = [](uvw::UVWError err, uvw::Tcp &srv) mutable {
|
||||
std::cout << "listen: " << ((bool)err) << std::endl;
|
||||
|
||||
if(!err) {
|
||||
uvw::Handle<uvw::Tcp> handle = srv.loop().handle<uvw::Tcp>();
|
||||
uvw::Tcp &client = handle;
|
||||
|
||||
err = srv.accept(client);
|
||||
std::cout << "accept: " << ((bool)err) << std::endl;
|
||||
|
||||
if(!err) {
|
||||
client.close([handle = srv.handle()](uvw::UVWError err, uvw::Tcp &) mutable {
|
||||
std::cout << "close: " << ((bool)err) << std::endl;
|
||||
|
||||
uvw::Tcp &srv = handle;
|
||||
srv.close([](uvw::UVWError err, uvw::Tcp &) mutable {
|
||||
std::cout << "close: " << ((bool)err) << std::endl;
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
uvw::Tcp &tcp = handle;
|
||||
tcp.connect<uvw::Tcp::IPv4>(std::string{"127.0.0.1"}, 80, cb);
|
||||
uvw::UVWError err = tcp.bind<uvw::Tcp::IPv4>("127.0.0.1", 4242);
|
||||
std::cout << "bind: " << ((bool)err) << std::endl;
|
||||
|
||||
if(err) {
|
||||
tcp.close([](uvw::UVWError err, uvw::Tcp &) mutable {
|
||||
std::cout << "close: " << ((bool)err) << std::endl;
|
||||
});
|
||||
} else {
|
||||
tcp.listen(0, cb);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void conn(uvw::Loop &loop) {
|
||||
uvw::Handle<uvw::Tcp> handle = loop.handle<uvw::Tcp>();
|
||||
|
||||
auto cb = [](uvw::UVWError err, uvw::Tcp &tcp) mutable {
|
||||
std::cout << "connect: " << ((bool)err) << std::endl;
|
||||
|
||||
auto cb = [](uvw::UVWError err, uvw::Tcp &tcp) mutable {
|
||||
std::cout << "close: " << ((bool)err) << std::endl;
|
||||
};
|
||||
|
||||
tcp.close(cb);
|
||||
};
|
||||
|
||||
uvw::Tcp &tcp = handle;
|
||||
tcp.connect<uvw::Tcp::IPv4>(std::string{"127.0.0.1"}, 4242, cb);
|
||||
}
|
||||
|
||||
void g() {
|
||||
auto loop = uvw::Loop::getDefault();
|
||||
f(*loop);
|
||||
listen(*loop);
|
||||
conn(*loop);
|
||||
loop->run();
|
||||
loop = nullptr;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user