WIP: Stream/Connection
This commit is contained in:
parent
10dacd46f6
commit
e177cc23bb
@ -1,6 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
|
#include <memory>
|
||||||
#include <uv.h>
|
#include <uv.h>
|
||||||
#include "resource.hpp"
|
#include "resource.hpp"
|
||||||
#include "error.hpp"
|
#include "error.hpp"
|
||||||
@ -9,7 +11,7 @@
|
|||||||
namespace uvw {
|
namespace uvw {
|
||||||
|
|
||||||
|
|
||||||
class Check final: public Resource<Check> {
|
class Check final: public Resource {
|
||||||
static void proto(uv_check_t* h) {
|
static void proto(uv_check_t* h) {
|
||||||
static_cast<Check*>(h->data)->callback(UVWError{});
|
static_cast<Check*>(h->data)->callback(UVWError{});
|
||||||
}
|
}
|
||||||
@ -17,23 +19,24 @@ class Check final: public Resource<Check> {
|
|||||||
public:
|
public:
|
||||||
using Callback = std::function<void(UVWError)>;
|
using Callback = std::function<void(UVWError)>;
|
||||||
|
|
||||||
explicit Check(uv_loop_t *loop): Resource{&handle} {
|
explicit Check(std::shared_ptr<Loop> ref)
|
||||||
uv_check_init(loop, &handle);
|
: Resource{HandleType<uv_check_t>{}, ref}
|
||||||
|
{
|
||||||
|
uv_check_init(parent(), get<uv_check_t>());
|
||||||
}
|
}
|
||||||
|
|
||||||
void start(Callback cb) noexcept {
|
void start(Callback cb) noexcept {
|
||||||
callback = cb;
|
callback = cb;
|
||||||
auto err = uv_check_start(&handle, &proto);
|
auto err = uv_check_start(get<uv_check_t>(), &proto);
|
||||||
|
|
||||||
if(err) {
|
if(err) {
|
||||||
callback(UVWError{err});
|
callback(UVWError{err});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool stop() noexcept { return (uv_check_stop(&handle) == 0); }
|
bool stop() noexcept { return (uv_check_stop(get<uv_check_t>()) == 0); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uv_check_t handle;
|
|
||||||
Callback callback;
|
Callback callback;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -11,6 +11,7 @@
|
|||||||
namespace uvw {
|
namespace uvw {
|
||||||
|
|
||||||
|
|
||||||
|
class Resource;
|
||||||
class Loop;
|
class Loop;
|
||||||
|
|
||||||
|
|
||||||
@ -19,17 +20,21 @@ class Handle {
|
|||||||
friend class Loop;
|
friend class Loop;
|
||||||
|
|
||||||
template<typename... Args>
|
template<typename... Args>
|
||||||
explicit constexpr Handle(uv_loop_t *loop, Args&&... args)
|
explicit constexpr Handle(std::shared_ptr<Loop>&& l, Args&&... args)
|
||||||
: res{std::make_shared<R>(loop, std::forward<Args>(args)...)}
|
: res{std::make_shared<R>(std::move(l), std::forward<Args>(args)...)}
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
explicit constexpr Handle(): res{} { }
|
||||||
|
|
||||||
constexpr Handle(const Handle &other): res{other.res} { }
|
constexpr Handle(const Handle &other): res{other.res} { }
|
||||||
constexpr Handle(Handle &&other): res{std::move(other.res)} { }
|
constexpr Handle(Handle &&other): res{std::move(other.res)} { }
|
||||||
|
|
||||||
constexpr void operator=(const Handle &other) { res = other.res; }
|
constexpr void operator=(const Handle &other) { res = other.res; }
|
||||||
constexpr void operator=(Handle &&other) { res = std::move(other.res); }
|
constexpr void operator=(Handle &&other) { res = std::move(other.res); }
|
||||||
|
|
||||||
|
constexpr explicit operator bool() { return static_cast<bool>(res); }
|
||||||
|
|
||||||
constexpr operator R&() noexcept { return *res; }
|
constexpr operator R&() noexcept { return *res; }
|
||||||
operator const R&() const noexcept { return *res; }
|
operator const R&() const noexcept { return *res; }
|
||||||
|
|
||||||
@ -38,20 +43,43 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class Loop final {
|
class Loop final: public std::enable_shared_from_this<Loop> {
|
||||||
public:
|
friend class Resource;
|
||||||
Loop(bool def = true)
|
|
||||||
: loop{def ? uv_default_loop() : new uv_loop_t, [def](uv_loop_t *l){ if(!def) delete l; }}
|
|
||||||
{
|
|
||||||
if(!def) {
|
|
||||||
auto err = uv_loop_init(loop.get());
|
|
||||||
|
|
||||||
if(err) {
|
using Deleter = std::function<void(uv_loop_t *)>;
|
||||||
throw UVWException{err};
|
|
||||||
|
Loop(std::unique_ptr<uv_loop_t, Deleter> ptr): loop{std::move(ptr)} { }
|
||||||
|
|
||||||
|
public:
|
||||||
|
static std::shared_ptr<Loop> create(bool def = true) {
|
||||||
|
auto ptr = std::unique_ptr<uv_loop_t, Deleter>{new uv_loop_t, [](uv_loop_t *l){ delete l; }};
|
||||||
|
auto loop = std::shared_ptr<Loop>(new Loop{std::move(ptr)});
|
||||||
|
|
||||||
|
if(!uv_loop_init(loop->loop.get())) {
|
||||||
|
loop = nullptr;
|
||||||
}
|
}
|
||||||
} else if(!loop) {
|
|
||||||
throw std::bad_alloc{};
|
return loop;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::shared_ptr<Loop> getDefault() {
|
||||||
|
static std::weak_ptr<Loop> ref;
|
||||||
|
std::shared_ptr<Loop> loop;
|
||||||
|
|
||||||
|
if(ref.expired()) {
|
||||||
|
auto def = uv_default_loop();
|
||||||
|
|
||||||
|
if(def) {
|
||||||
|
auto ptr = std::unique_ptr<uv_loop_t, Deleter>(def, [](uv_loop_t *){ });
|
||||||
|
loop = std::shared_ptr<Loop>(new Loop{std::move(ptr)});
|
||||||
|
}
|
||||||
|
|
||||||
|
ref = loop;
|
||||||
|
} else {
|
||||||
|
loop = ref.lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
return loop;
|
||||||
}
|
}
|
||||||
|
|
||||||
Loop(const Loop &) = delete;
|
Loop(const Loop &) = delete;
|
||||||
@ -67,7 +95,7 @@ public:
|
|||||||
|
|
||||||
template<typename R, typename... Args>
|
template<typename R, typename... Args>
|
||||||
Handle<R> handle(Args&&... args) {
|
Handle<R> handle(Args&&... args) {
|
||||||
return Handle<R>{loop.get(), std::forward<Args>(args)...};
|
return Handle<R>{shared_from_this(), std::forward<Args>(args)...};
|
||||||
}
|
}
|
||||||
|
|
||||||
bool close() noexcept {
|
bool close() noexcept {
|
||||||
@ -95,7 +123,6 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
using Deleter = std::function<void(uv_loop_t *)>;
|
|
||||||
std::unique_ptr<uv_loop_t, Deleter> loop;
|
std::unique_ptr<uv_loop_t, Deleter> loop;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -11,43 +11,67 @@
|
|||||||
namespace uvw {
|
namespace uvw {
|
||||||
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename>
|
||||||
class Resource {
|
struct HandleType { };
|
||||||
protected:
|
|
||||||
template<typename U>
|
|
||||||
explicit Resource(U *u): handle{reinterpret_cast<uv_handle_t*>(u)} {
|
|
||||||
handle->data = this;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
class Resource {
|
||||||
static void proto(uv_handle_t* h) {
|
static void proto(uv_handle_t* h) {
|
||||||
static_cast<Resource*>(h->data)->callback(UVWError{});
|
static_cast<Resource*>(h->data)->callback(UVWError{});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
template<typename T>
|
||||||
|
explicit Resource(HandleType<T>, std::shared_ptr<Loop> r)
|
||||||
|
: ref{std::move(r)}, res{std::make_shared<T>()}
|
||||||
|
{
|
||||||
|
get<uv_handle_t>()->data = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
T* get() const noexcept { return reinterpret_cast<T*>(res.get()); }
|
||||||
|
|
||||||
|
uv_loop_t* parent() const noexcept { return ref->loop.get(); }
|
||||||
|
|
||||||
|
template<typename T, typename... Args>
|
||||||
|
Handle<T> spawn(Args&&... args) {
|
||||||
|
auto h = ref->handle<T>(std::forward<Args>(args)...);
|
||||||
|
static_cast<T&>(h).res = res;
|
||||||
|
return h;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void reset() {
|
||||||
|
res = std::make_shared<T>();
|
||||||
|
get<uv_handle_t>()->data = this;
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using Callback = std::function<void(UVWError)>;
|
using Callback = std::function<void(UVWError)>;
|
||||||
|
|
||||||
virtual ~Resource() { static_assert(std::is_base_of<Resource<T>, T>::value, "!"); }
|
explicit Resource(const Resource &) = delete;
|
||||||
|
explicit Resource(Resource &&) = delete;
|
||||||
Resource(const Resource &) = delete;
|
|
||||||
Resource(Resource &&) = delete;
|
|
||||||
|
|
||||||
void operator=(const Resource &) = delete;
|
void operator=(const Resource &) = delete;
|
||||||
void operator=(Resource &&) = delete;
|
void operator=(Resource &&) = delete;
|
||||||
|
|
||||||
bool active() const noexcept { return !(uv_is_active(handle) == 0); }
|
std::shared_ptr<Loop> loop() const noexcept { return ref; }
|
||||||
bool closing() const noexcept { return !(uv_is_closing(handle) == 0); }
|
|
||||||
|
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); }
|
||||||
|
|
||||||
void close(Callback cb) noexcept {
|
void close(Callback cb) noexcept {
|
||||||
callback = cb;
|
callback = cb;
|
||||||
uv_close(handle, &proto);
|
uv_close(get<uv_handle_t>(), &proto);
|
||||||
}
|
}
|
||||||
|
|
||||||
void reference() noexcept { uv_ref(handle); }
|
void reference() noexcept { uv_ref(get<uv_handle_t>()); }
|
||||||
void unreference() noexcept { uv_ref(handle); }
|
void unreference() noexcept { uv_ref(get<uv_handle_t>()); }
|
||||||
bool referenced() const noexcept { return !(uv_has_ref(handle) == 0); }
|
bool referenced() const noexcept { return !(uv_has_ref(get<uv_handle_t>()) == 0); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uv_handle_t *handle;
|
std::shared_ptr<Loop> ref;
|
||||||
|
std::shared_ptr<void> res;
|
||||||
Callback callback;
|
Callback callback;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -1,50 +1,73 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
|
||||||
|
#include <uv.h>
|
||||||
|
#include "resource.hpp"
|
||||||
|
#include "loop.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace uvw {
|
namespace uvw {
|
||||||
|
|
||||||
|
|
||||||
template<class T>
|
class Connection final: public Resource {
|
||||||
class Connection: public Resource<T> {
|
// TODO proxy on a stream client
|
||||||
using Resource<T>::Resource;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
explicit Connection(std::shared_ptr<Loop> ref, uv_stream_t *srv)
|
||||||
|
: Resource{HandleType<uv_stream_t>{}, ref}
|
||||||
|
{
|
||||||
|
// TODO initialized... HOW????
|
||||||
|
uv_tcp_init(parent(), get<uv_tcp_t>());get<uv_stream_t>()
|
||||||
|
auto err = uv_accept(srv, get<uv_stream_t>());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class Stream: public Resource {
|
||||||
|
static void protoListen(uv_stream_t* srv, int status) {
|
||||||
|
// TODO invoke accept
|
||||||
|
|
||||||
|
Stream &stream = *(static_cast<Stream*>(srv->data));
|
||||||
|
|
||||||
|
if(status) {
|
||||||
|
stream.listenCallback(UVWError{status}, Handle<Connection>{});
|
||||||
|
} else {
|
||||||
|
stream.listenCallback(UVWError{}, loop()->handle(get<uv_stream_t>()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
using Resource::Resource;
|
||||||
|
|
||||||
|
public:
|
||||||
|
using CallbackListen = std::function<void(UVWError, Handle<Connection>)>;
|
||||||
|
|
||||||
|
// TODO shutdown
|
||||||
|
|
||||||
|
void listen(int backlog, CallbackListen cb) noexcept {
|
||||||
|
listenCallback = cb;
|
||||||
|
auto err = uv_listen(get<uv_stream_t>(), backlog, &protoListen);
|
||||||
|
|
||||||
|
if(err) {
|
||||||
|
listenCallback(UVWError{err}, Handle<Connection>{});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO read
|
// TODO read
|
||||||
// TODO stop
|
// TODO stop
|
||||||
// TODO write
|
// TODO write
|
||||||
// TODO tryWrite
|
// TODO tryWrite
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
class Stream: public Connection<T> {
|
|
||||||
using Connection<T>::Connection;
|
|
||||||
|
|
||||||
static void protoListen(uv_stream_t* srv, int status) {
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
template<typename U>
|
|
||||||
explicit Stream(U *u)
|
|
||||||
: Connection<T>{u},
|
|
||||||
handle{reinterpret_cast<uv_stream_t*>(u)}
|
|
||||||
{ }
|
|
||||||
|
|
||||||
public:
|
|
||||||
// TODO shutdown
|
|
||||||
// TODO listen
|
|
||||||
|
|
||||||
bool readable() const noexcept {
|
bool readable() const noexcept {
|
||||||
return (uv_is_readable(handle) == 1);
|
return (uv_is_readable(get<uv_stream_t>()) == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool writable() const noexcept {
|
bool writable() const noexcept {
|
||||||
return (uv_is_writable(handle) == 1);
|
return (uv_is_writable(get<uv_stream_t>()) == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uv_stream_t *handle;
|
CallbackListen listenCallback;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
#include <memory>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <ratio>
|
#include <ratio>
|
||||||
#include <uv.h>
|
#include <uv.h>
|
||||||
@ -12,67 +13,72 @@
|
|||||||
namespace uvw {
|
namespace uvw {
|
||||||
|
|
||||||
|
|
||||||
class Tcp final: public Stream<Tcp> {
|
class Tcp final: public Stream {
|
||||||
static void protoConnect(uv_connect_t* req, int status) {
|
static void protoConnect(uv_connect_t* req, int status) {
|
||||||
auto handle = req->handle;
|
Tcp &tcp = *(static_cast<Tcp*>(req->handle->data));
|
||||||
delete req;
|
|
||||||
static_cast<Tcp*>(handle->data)->connCb(UVWError{status});
|
if(status) {
|
||||||
|
tcp.connCb(UVWError{status}, Handle<Connection>{});
|
||||||
|
} else {
|
||||||
|
auto h = tcp.spawn<Connection>();
|
||||||
|
tcp.reset<uv_tcp_t>();
|
||||||
|
uv_tcp_init(tcp.parent(), tcp.get<uv_tcp_t>());
|
||||||
|
tcp.connCb(UVWError{}, h);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using Time = std::chrono::duration<uint64_t>;
|
using Time = std::chrono::duration<uint64_t>;
|
||||||
using CallbackConnect = std::function<void(UVWError)>;
|
using CallbackConnect = std::function<void(UVWError, Handle<Connection>)>;
|
||||||
|
|
||||||
enum { IPv4, IPv6 };
|
enum { IPv4, IPv6 };
|
||||||
|
|
||||||
explicit Tcp(uv_loop_t *loop): Stream<Tcp>{&handle} {
|
explicit Tcp(std::shared_ptr<Loop> ref)
|
||||||
uv_tcp_init(loop, &handle);
|
: Stream{HandleType<uv_tcp_t>{}, ref},
|
||||||
}
|
conn{std::make_unique<uv_connect_t>()}
|
||||||
|
{
|
||||||
~Tcp() {
|
uv_tcp_init(parent(), get<uv_tcp_t>());
|
||||||
close([](UVWError){});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool noDelay(bool value = false) noexcept {
|
bool noDelay(bool value = false) noexcept {
|
||||||
return (uv_tcp_nodelay(&handle, value ? 1 : 0) == 0);
|
return (uv_tcp_nodelay(get<uv_tcp_t>(), value ? 1 : 0) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool keepAlive(bool enable = false, Time time = Time{0}) noexcept {
|
bool keepAlive(bool enable = false, Time time = Time{0}) noexcept {
|
||||||
return (uv_tcp_keepalive(&handle, enable ? 1 : 0, time.count()) == 0);
|
return (uv_tcp_keepalive(get<uv_tcp_t>(), enable ? 1 : 0, time.count()) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int>
|
template<int>
|
||||||
void connect(std::string, int, CallbackConnect) noexcept;
|
void connect(std::string, int, CallbackConnect) noexcept;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
std::unique_ptr<uv_connect_t> conn;
|
||||||
CallbackConnect connCb;
|
CallbackConnect connCb;
|
||||||
uv_tcp_t handle;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void Tcp::connect<Tcp::IPv4>(std::string ip, int port, CallbackConnect cb) noexcept {
|
void Tcp::connect<Tcp::IPv4>(std::string ip, int port, CallbackConnect cb) noexcept {
|
||||||
uv_connect_t *conn = new uv_connect_t;
|
|
||||||
sockaddr_in addr;
|
sockaddr_in addr;
|
||||||
uv_ip4_addr(ip.c_str(), port, &addr);
|
uv_ip4_addr(ip.c_str(), port, &addr);
|
||||||
connCb = cb;
|
connCb = cb;
|
||||||
auto err = uv_tcp_connect(conn, &handle, reinterpret_cast<const sockaddr*>(&addr), &protoConnect);
|
auto err = uv_tcp_connect(conn.get(), get<uv_tcp_t>(), reinterpret_cast<const sockaddr*>(&addr), &protoConnect);
|
||||||
|
|
||||||
if(err) {
|
if(err) {
|
||||||
connCb(UVWError{err});
|
connCb(UVWError{err}, Handle<Connection>{});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void Tcp::connect<Tcp::IPv6>(std::string ip, int port, CallbackConnect cb) noexcept {
|
void Tcp::connect<Tcp::IPv6>(std::string ip, int port, CallbackConnect cb) noexcept {
|
||||||
uv_connect_t *conn = new uv_connect_t;
|
|
||||||
sockaddr_in6 addr;
|
sockaddr_in6 addr;
|
||||||
uv_ip6_addr(ip.c_str(), port, &addr);
|
uv_ip6_addr(ip.c_str(), port, &addr);
|
||||||
connCb = cb;
|
connCb = cb;
|
||||||
auto err = uv_tcp_connect(conn, &handle, reinterpret_cast<const sockaddr*>(&addr), &protoConnect);
|
auto err = uv_tcp_connect(conn.get(), get<uv_tcp_t>(), reinterpret_cast<const sockaddr*>(&addr), &protoConnect);
|
||||||
|
|
||||||
if(err) {
|
if(err) {
|
||||||
connCb(UVWError{err});
|
connCb(UVWError{err}, Handle<Connection>{});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -12,7 +12,7 @@
|
|||||||
namespace uvw {
|
namespace uvw {
|
||||||
|
|
||||||
|
|
||||||
class Timer final: public Resource<Timer> {
|
class Timer final: public Resource {
|
||||||
static void proto(uv_timer_t* h) {
|
static void proto(uv_timer_t* h) {
|
||||||
static_cast<Timer*>(h->data)->callback(UVWError{});
|
static_cast<Timer*>(h->data)->callback(UVWError{});
|
||||||
}
|
}
|
||||||
@ -21,26 +21,27 @@ public:
|
|||||||
using Time = std::chrono::duration<uint64_t, std::milli>;
|
using Time = std::chrono::duration<uint64_t, std::milli>;
|
||||||
using Callback = std::function<void(UVWError)>;
|
using Callback = std::function<void(UVWError)>;
|
||||||
|
|
||||||
explicit Timer(uv_loop_t *loop): Resource{&handle} {
|
explicit Timer(std::shared_ptr<Loop> ref)
|
||||||
uv_timer_init(loop, &handle);
|
: Resource{HandleType<uv_timer_t>{}, ref}
|
||||||
|
{
|
||||||
|
uv_timer_init(parent(), get<uv_timer_t>());
|
||||||
}
|
}
|
||||||
|
|
||||||
void start(const Time &timeout, const Time &rep, Callback cb) noexcept {
|
void start(const Time &timeout, const Time &rep, Callback cb) noexcept {
|
||||||
callback = cb;
|
callback = cb;
|
||||||
auto err = uv_timer_start(&handle, &proto, timeout.count(), rep.count());
|
auto err = uv_timer_start(get<uv_timer_t>(), &proto, timeout.count(), rep.count());
|
||||||
|
|
||||||
if(err) {
|
if(err) {
|
||||||
callback(UVWError{err});
|
callback(UVWError{err});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void stop() noexcept { uv_timer_stop(&handle); }
|
void stop() noexcept { uv_timer_stop(get<uv_timer_t>()); }
|
||||||
void again() noexcept { uv_timer_again(&handle); }
|
void again() noexcept { uv_timer_again(get<uv_timer_t>()); }
|
||||||
void repeat(const Time &rep) noexcept { uv_timer_set_repeat(&handle, rep.count()); }
|
void repeat(const Time &rep) noexcept { uv_timer_set_repeat(get<uv_timer_t>(), rep.count()); }
|
||||||
Time repeat() const noexcept { return Time{uv_timer_get_repeat(&handle)}; }
|
Time repeat() const noexcept { return Time{uv_timer_get_repeat(get<uv_timer_t>())}; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uv_timer_t handle;
|
|
||||||
Callback callback;
|
Callback callback;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -4,14 +4,14 @@
|
|||||||
|
|
||||||
void f(uvw::Loop &loop) {
|
void f(uvw::Loop &loop) {
|
||||||
uvw::Handle<uvw::Tcp> handle = loop.handle<uvw::Tcp>();
|
uvw::Handle<uvw::Tcp> handle = loop.handle<uvw::Tcp>();
|
||||||
auto cb = [h = handle](uvw::UVWError err){ std::cout << "---" << ((bool)err) << std::endl; };
|
auto cb = [h = handle](uvw::UVWError err, uvw::Handle<uvw::Connection> conn){ std::cout << "---" << ((bool)err) << std::endl; };
|
||||||
uvw::Tcp &tcp = handle;
|
uvw::Tcp &tcp = handle;
|
||||||
tcp.connect<uvw::Tcp::IPv4>(std::string{"127.0.0.1"}, 80, cb);
|
tcp.connect<uvw::Tcp::IPv4>(std::string{"127.0.0.1"}, 80, cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
uvw::Loop loop;
|
auto loop = uvw::Loop::getDefault();
|
||||||
f(loop);
|
f(*loop);
|
||||||
loop.runWait();
|
loop->runWait();
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user