commit
966e2a0acc
@ -1,6 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
|
||||
#include <utility>
|
||||
#include <memory>
|
||||
#include <uv.h>
|
||||
#include "resource.hpp"
|
||||
#include "error.hpp"
|
||||
@ -10,31 +12,43 @@ namespace uvw {
|
||||
|
||||
|
||||
class Check final: public Resource<Check> {
|
||||
static void proto(uv_check_t* h) {
|
||||
static_cast<Check*>(h->data)->callback(UVWError{});
|
||||
static Check* startCallback(uv_check_t* h) {
|
||||
Check *check = static_cast<Check*>(h->data);
|
||||
check->startCb(UVWError{});
|
||||
return check;
|
||||
}
|
||||
|
||||
explicit Check(std::shared_ptr<Loop> ref)
|
||||
: Resource{HandleType<uv_check_t>{}, std::move(ref)}
|
||||
{
|
||||
initialized = (uv_check_init(parent(), get<uv_check_t>()) == 0);
|
||||
}
|
||||
|
||||
public:
|
||||
using Callback = std::function<void(UVWError)>;
|
||||
|
||||
explicit Check(uv_loop_t *loop): Resource{&handle} {
|
||||
uv_check_init(loop, &handle);
|
||||
template<typename... Args>
|
||||
static std::shared_ptr<Check> create(Args&&... args) {
|
||||
return std::shared_ptr<Check>{new Check{std::forward<Args>(args)...}};
|
||||
}
|
||||
|
||||
void start(Callback cb) noexcept {
|
||||
callback = cb;
|
||||
auto err = uv_check_start(&handle, &proto);
|
||||
void start(std::function<void(UVWError)> cb) noexcept {
|
||||
using UVCB = UVCallback<uv_check_t*>;
|
||||
auto func = UVCB::get<Check, &startCallback>(this);
|
||||
startCb = std::move(cb);
|
||||
auto err = uv_check_start(get<uv_check_t>(), func);
|
||||
|
||||
if(err) {
|
||||
callback(UVWError{err});
|
||||
startCb(UVWError{err});
|
||||
reset();
|
||||
}
|
||||
}
|
||||
|
||||
bool stop() noexcept { return (uv_check_stop(&handle) == 0); }
|
||||
UVWError stop() noexcept { return UVWError{uv_check_stop(get<uv_check_t>())}; }
|
||||
|
||||
explicit operator bool() { return initialized; }
|
||||
|
||||
private:
|
||||
uv_check_t handle;
|
||||
Callback callback;
|
||||
std::function<void(UVWError)> startCb;
|
||||
bool initialized;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -33,7 +33,8 @@ public:
|
||||
|
||||
public:
|
||||
explicit operator bool() const noexcept { return !(ec == 0); }
|
||||
const char* str() const noexcept { return uv_strerror(ec); }
|
||||
operator const char *() const noexcept { return uv_strerror(ec); }
|
||||
operator int() const noexcept { return ec; }
|
||||
|
||||
private:
|
||||
int ec;
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
#include <new>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
#include <type_traits>
|
||||
#include <uv.h>
|
||||
#include "error.hpp"
|
||||
|
||||
@ -11,47 +12,90 @@
|
||||
namespace uvw {
|
||||
|
||||
|
||||
class BaseResource;
|
||||
class Loop;
|
||||
|
||||
|
||||
template<typename R>
|
||||
class Handle {
|
||||
template<typename>
|
||||
friend class Handle;
|
||||
|
||||
friend class Loop;
|
||||
|
||||
template<typename... Args>
|
||||
explicit constexpr Handle(Args&&... args)
|
||||
: res{std::make_shared<R>(std::forward<Args>(args)...)}
|
||||
explicit constexpr Handle(std::shared_ptr<Loop>&& l, Args&&... args)
|
||||
: res{R::create(std::move(l), std::forward<Args>(args)...)}
|
||||
{ }
|
||||
|
||||
public:
|
||||
constexpr Handle(const Handle &other): res{other.res} { }
|
||||
constexpr Handle(Handle &&other): res{std::move(other.res)} { }
|
||||
explicit constexpr Handle(std::shared_ptr<R> ptr): res{std::move(ptr)} { }
|
||||
|
||||
constexpr void operator=(const Handle &other) { res = other.res; }
|
||||
constexpr void operator=(Handle &&other) { res = std::move(other.res); }
|
||||
public:
|
||||
explicit constexpr Handle(): res{} { }
|
||||
|
||||
template<typename T, std::enable_if_t<std::is_base_of<R, T>::value>* = nullptr>
|
||||
constexpr Handle(const Handle<T> &other): res{other.res} { }
|
||||
|
||||
template<typename T, std::enable_if_t<std::is_base_of<R, T>::value>* = nullptr>
|
||||
constexpr Handle(Handle<T> &&other): res{std::move(other.res)} { }
|
||||
|
||||
template<typename T, std::enable_if_t<std::is_base_of<R, T>::value>* = nullptr>
|
||||
constexpr void operator=(const Handle<T> &other) { res = other.res; }
|
||||
|
||||
template<typename T, std::enable_if_t<std::is_base_of<R, T>::value>* = nullptr>
|
||||
constexpr void operator=(Handle<T> &&other) { res = std::move(other.res); }
|
||||
|
||||
constexpr explicit operator bool() const { return static_cast<bool>(res); }
|
||||
|
||||
constexpr operator R&() noexcept { return *res; }
|
||||
operator const R&() const 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;
|
||||
};
|
||||
|
||||
|
||||
class Loop final {
|
||||
public:
|
||||
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());
|
||||
class Loop final: public std::enable_shared_from_this<Loop> {
|
||||
template<typename>
|
||||
friend class Resource;
|
||||
|
||||
if(err) {
|
||||
throw UVWException{err};
|
||||
}
|
||||
} else if(!loop) {
|
||||
throw std::bad_alloc{};
|
||||
using Deleter = std::function<void(uv_loop_t *)>;
|
||||
|
||||
Loop(std::unique_ptr<uv_loop_t, Deleter> ptr): loop{std::move(ptr)} { }
|
||||
|
||||
public:
|
||||
static std::shared_ptr<Loop> create() {
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
@ -67,11 +111,11 @@ public:
|
||||
|
||||
template<typename R, typename... 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 {
|
||||
return (uv_loop_close(loop.get()) == 0);
|
||||
UVWError close() noexcept {
|
||||
return UVWError{uv_loop_close(loop.get())};
|
||||
}
|
||||
|
||||
bool run() noexcept {
|
||||
@ -95,7 +139,6 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
using Deleter = std::function<void(uv_loop_t *)>;
|
||||
std::unique_ptr<uv_loop_t, Deleter> loop;
|
||||
};
|
||||
|
||||
|
||||
@ -11,49 +11,98 @@
|
||||
namespace uvw {
|
||||
|
||||
|
||||
template<typename>
|
||||
struct HandleType { };
|
||||
|
||||
|
||||
template<typename>
|
||||
class Resource;
|
||||
|
||||
|
||||
template<typename>
|
||||
struct UVCallback;
|
||||
|
||||
|
||||
template<typename... Args>
|
||||
struct UVCallback<Args...> {
|
||||
template<typename T, T*(*F)(Args...)>
|
||||
static auto get(T *res);
|
||||
|
||||
private:
|
||||
template<typename T, T*(*F)(Args...)>
|
||||
static void proto(Args... args);
|
||||
};
|
||||
|
||||
|
||||
template<typename T>
|
||||
class Resource {
|
||||
class Resource: public std::enable_shared_from_this<T> {
|
||||
template<typename>
|
||||
friend struct UVCallback;
|
||||
|
||||
static Resource<T>* closeCallback(uv_handle_t* h) {
|
||||
auto ptr = static_cast<Resource<T>*>(h->data);
|
||||
ptr->closeCb(UVWError{});
|
||||
return ptr;
|
||||
}
|
||||
|
||||
protected:
|
||||
template<typename U>
|
||||
explicit Resource(U *u): handle{reinterpret_cast<uv_handle_t*>(u)} {
|
||||
handle->data = this;
|
||||
}
|
||||
explicit Resource(HandleType<U>, std::shared_ptr<Loop> r)
|
||||
: pLoop{std::move(r)}, handle{std::make_shared<U>()}
|
||||
{ }
|
||||
|
||||
static void proto(uv_handle_t* h) {
|
||||
static_cast<Resource*>(h->data)->callback(UVWError{});
|
||||
}
|
||||
template<typename U>
|
||||
U* get() const noexcept { return reinterpret_cast<U*>(handle.get()); }
|
||||
|
||||
uv_loop_t* parent() const noexcept { return pLoop->loop.get(); }
|
||||
void reset() noexcept { ref = nullptr; }
|
||||
|
||||
public:
|
||||
using Callback = std::function<void(UVWError)>;
|
||||
explicit Resource(const Resource &) = delete;
|
||||
explicit Resource(Resource &&) = delete;
|
||||
|
||||
virtual ~Resource() = 0;
|
||||
|
||||
Resource(const Resource &) = delete;
|
||||
Resource(Resource &&) = delete;
|
||||
~Resource() { static_assert(std::is_base_of<Resource<T>, T>::value, "!"); }
|
||||
|
||||
void operator=(const Resource &) = delete;
|
||||
void operator=(Resource &&) = delete;
|
||||
|
||||
bool active() const noexcept { return !(uv_is_active(handle) == 0); }
|
||||
bool closing() const noexcept { return !(uv_is_closing(handle) == 0); }
|
||||
std::shared_ptr<Loop> loop() const noexcept { return pLoop; }
|
||||
|
||||
void close(Callback cb) noexcept {
|
||||
callback = cb;
|
||||
uv_close(handle, &proto);
|
||||
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 reference() noexcept { uv_ref(get<uv_handle_t>()); }
|
||||
void unreference() noexcept { uv_ref(get<uv_handle_t>()); }
|
||||
bool referenced() const noexcept { return !(uv_has_ref(get<uv_handle_t>()) == 0); }
|
||||
|
||||
void close(std::function<void(UVWError)> cb) noexcept {
|
||||
using UVCB = UVCallback<uv_handle_t*>;
|
||||
auto func = UVCB::get<Resource<T>, &closeCallback>(this);
|
||||
closeCb = std::move(cb);
|
||||
uv_close(get<uv_handle_t>(), func);
|
||||
}
|
||||
|
||||
void reference() noexcept { uv_ref(handle); }
|
||||
void unreference() noexcept { uv_ref(handle); }
|
||||
bool referenced() const noexcept { return !(uv_has_ref(handle) == 0); }
|
||||
|
||||
private:
|
||||
uv_handle_t *handle;
|
||||
Callback callback;
|
||||
std::function<void(UVWError)> closeCb;
|
||||
std::shared_ptr<Loop> pLoop;
|
||||
std::shared_ptr<void> handle;
|
||||
std::shared_ptr<void> ref;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
Resource<T>::~Resource() {
|
||||
static_assert(std::is_base_of<Resource<T>, T>::value, "!");
|
||||
|
||||
template<typename... Args>
|
||||
template<typename T, T*(*F)(Args...)>
|
||||
void UVCallback<Args...>::proto(Args... args) {
|
||||
T *res = F(std::forward<Args>(args)...);
|
||||
res->ref = nullptr;
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
template<typename T, T*(*F)(Args...)>
|
||||
auto UVCallback<Args...>::get(T *res) {
|
||||
res->template get<uv_handle_t>()->data = res;
|
||||
res->ref = res->shared_from_this();
|
||||
return &proto<T, F>;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -1,18 +1,71 @@
|
||||
#pragma once
|
||||
|
||||
|
||||
#include <uv.h>
|
||||
#include "resource.hpp"
|
||||
#include "loop.hpp"
|
||||
|
||||
|
||||
namespace uvw {
|
||||
|
||||
|
||||
template<class T>
|
||||
class Connection: public Resource<T> {
|
||||
template<typename T>
|
||||
class Stream: public Resource<T> {
|
||||
static void protoListen(uv_stream_t* srv, int status) {
|
||||
Stream &stream = *(static_cast<Stream*>(srv->data));
|
||||
|
||||
if(status) {
|
||||
stream.listenCallback(UVWError{status});
|
||||
} else {
|
||||
stream.tryAccept();
|
||||
}
|
||||
}
|
||||
|
||||
void tryAccept() const noexcept {
|
||||
Handle<Stream> handle = accept();
|
||||
|
||||
if(handle) {
|
||||
// TODO invoke cb with handle
|
||||
} else {
|
||||
// TODO invoke cb with error
|
||||
}
|
||||
}
|
||||
|
||||
virtual Handle<Stream> accept() const noexcept = 0;
|
||||
|
||||
protected:
|
||||
using Resource<T>::Resource;
|
||||
};
|
||||
|
||||
public:
|
||||
using CallbackListen = std::function<void(UVWError)>;
|
||||
|
||||
template<class T>
|
||||
class Stream: public Connection<T> {
|
||||
using Connection<T>::Connection;
|
||||
// TODO shutdown
|
||||
|
||||
void listen(int backlog, CallbackListen cb) noexcept {
|
||||
listenCallback = std::move(cb);
|
||||
this->template get<uv_stream_t>()->data = this;
|
||||
auto err = uv_listen(this->template get<uv_stream_t>(), backlog, &protoListen);
|
||||
|
||||
if(err) {
|
||||
listenCallback(UVWError{err});
|
||||
}
|
||||
}
|
||||
|
||||
// TODO read
|
||||
// TODO stop
|
||||
// TODO write
|
||||
// TODO tryWrite
|
||||
|
||||
bool readable() const noexcept {
|
||||
return (uv_is_readable(this->template get<uv_stream_t>()) == 1);
|
||||
}
|
||||
|
||||
bool writable() const noexcept {
|
||||
return (uv_is_writable(this->template get<uv_stream_t>()) == 1);
|
||||
}
|
||||
|
||||
private:
|
||||
CallbackListen listenCallback;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -1,7 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
|
||||
#include <utility>
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <chrono>
|
||||
#include <ratio>
|
||||
#include <uv.h>
|
||||
@ -14,9 +17,30 @@ namespace uvw {
|
||||
|
||||
class Tcp final: public Stream<Tcp> {
|
||||
static void protoConnect(uv_connect_t* req, int status) {
|
||||
auto handle = req->handle;
|
||||
delete req;
|
||||
static_cast<Tcp*>(handle->data)->connCb(UVWError{status});
|
||||
Tcp *tcp = static_cast<Tcp*>(req->handle->data);
|
||||
tcp->connCb(UVWError{status});
|
||||
tcp->connCb = nullptr;
|
||||
}
|
||||
|
||||
Handle<Stream> accept() const noexcept override {
|
||||
auto handle = loop()->handle<Tcp>(get<uv_stream_t>());
|
||||
|
||||
if(!handle || !static_cast<Tcp&>(handle)) {
|
||||
handle = Handle<Tcp>{};
|
||||
}
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
explicit Tcp(std::shared_ptr<Loop> ref)
|
||||
: Stream{HandleType<uv_tcp_t>{}, std::move(ref)},
|
||||
conn{std::make_unique<uv_connect_t>()}
|
||||
{
|
||||
initialized = (uv_tcp_init(parent(), get<uv_tcp_t>()) == 0);
|
||||
}
|
||||
|
||||
explicit Tcp(std::shared_ptr<Loop> ref, uv_stream_t *srv): Tcp{ref} {
|
||||
initialized = initialized || (uv_accept(srv, get<uv_stream_t>()) == 0);
|
||||
}
|
||||
|
||||
public:
|
||||
@ -25,51 +49,52 @@ public:
|
||||
|
||||
enum { IPv4, IPv6 };
|
||||
|
||||
explicit Tcp(uv_loop_t *loop): Stream<Tcp>{&handle} {
|
||||
uv_tcp_init(loop, &handle);
|
||||
template<typename... Args>
|
||||
static std::shared_ptr<Tcp> create(Args&&... args) {
|
||||
return std::shared_ptr<Tcp>{new Tcp{std::forward<Args>(args)...}};
|
||||
}
|
||||
|
||||
~Tcp() {
|
||||
close([](UVWError){});
|
||||
UVWError noDelay(bool value = false) noexcept {
|
||||
return UVWError{uv_tcp_nodelay(get<uv_tcp_t>(), value ? 1 : 0)};
|
||||
}
|
||||
|
||||
bool noDelay(bool value = false) {
|
||||
return (uv_tcp_nodelay(&handle, value ? 1 : 0) == 0);
|
||||
}
|
||||
|
||||
bool keepAlive(bool enable = false, Time time = Time{0}) {
|
||||
return (uv_tcp_keepalive(&handle, enable ? 1 : 0, time.count()) == 0);
|
||||
UVWError keepAlive(bool enable = false, Time time = Time{0}) noexcept {
|
||||
return UVWError{uv_tcp_keepalive(get<uv_tcp_t>(), enable ? 1 : 0, time.count())};
|
||||
}
|
||||
|
||||
template<int>
|
||||
void connect(std::string, int, CallbackConnect) noexcept;
|
||||
|
||||
explicit operator bool() { return initialized; }
|
||||
|
||||
private:
|
||||
std::unique_ptr<uv_connect_t> conn;
|
||||
CallbackConnect connCb;
|
||||
uv_tcp_t handle;
|
||||
bool initialized;
|
||||
};
|
||||
|
||||
|
||||
template<>
|
||||
void Tcp::connect<Tcp::IPv4>(std::string ip, int port, CallbackConnect cb) noexcept {
|
||||
uv_connect_t *conn = new uv_connect_t;
|
||||
sockaddr_in addr;
|
||||
uv_ip4_addr(ip.c_str(), port, &addr);
|
||||
connCb = cb;
|
||||
auto err = uv_tcp_connect(conn, &handle, reinterpret_cast<const sockaddr*>(&addr), &protoConnect);
|
||||
connCb = std::move(cb);
|
||||
get<uv_tcp_t>()->data = this;
|
||||
auto err = uv_tcp_connect(conn.get(), get<uv_tcp_t>(), reinterpret_cast<const sockaddr*>(&addr), &protoConnect);
|
||||
|
||||
if(err) {
|
||||
connCb(UVWError{err});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<>
|
||||
void Tcp::connect<Tcp::IPv6>(std::string ip, int port, CallbackConnect cb) noexcept {
|
||||
uv_connect_t *conn = new uv_connect_t;
|
||||
sockaddr_in6 addr;
|
||||
uv_ip6_addr(ip.c_str(), port, &addr);
|
||||
connCb = cb;
|
||||
auto err = uv_tcp_connect(conn, &handle, reinterpret_cast<const sockaddr*>(&addr), &protoConnect);
|
||||
connCb = std::move(cb);
|
||||
get<uv_tcp_t>()->data = this;
|
||||
auto err = uv_tcp_connect(conn.get(), get<uv_tcp_t>(), reinterpret_cast<const sockaddr*>(&addr), &protoConnect);
|
||||
|
||||
if(err) {
|
||||
connCb(UVWError{err});
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
|
||||
|
||||
#include <cstdint>
|
||||
#include <utility>
|
||||
#include <chrono>
|
||||
#include <ratio>
|
||||
#include <uv.h>
|
||||
@ -13,35 +14,48 @@ namespace uvw {
|
||||
|
||||
|
||||
class Timer final: public Resource<Timer> {
|
||||
static void proto(uv_timer_t* h) {
|
||||
static_cast<Timer*>(h->data)->callback(UVWError{});
|
||||
static Timer* startCallback(uv_timer_t* h) {
|
||||
Timer *timer = static_cast<Timer*>(h->data);
|
||||
timer->startCb(UVWError{});
|
||||
return timer;
|
||||
}
|
||||
|
||||
explicit Timer(std::shared_ptr<Loop> ref)
|
||||
: Resource{HandleType<uv_timer_t>{}, std::move(ref)}
|
||||
{
|
||||
initialized = (uv_timer_init(parent(), get<uv_timer_t>()) == 0);
|
||||
}
|
||||
|
||||
public:
|
||||
using Time = std::chrono::duration<uint64_t, std::milli>;
|
||||
using Callback = std::function<void(UVWError)>;
|
||||
|
||||
explicit Timer(uv_loop_t *loop): Resource{&handle} {
|
||||
uv_timer_init(loop, &handle);
|
||||
template<typename... Args>
|
||||
static std::shared_ptr<Timer> create(Args&&... args) {
|
||||
return std::shared_ptr<Timer>{new Timer{std::forward<Args>(args)...}};
|
||||
}
|
||||
|
||||
void start(const Time &timeout, const Time &rep, Callback cb) noexcept {
|
||||
callback = cb;
|
||||
auto err = uv_timer_start(&handle, &proto, timeout.count(), rep.count());
|
||||
void start(const Time &timeout, const Time &rep, std::function<void(UVWError)> cb) noexcept {
|
||||
using UVCB = UVCallback<uv_timer_t*>;
|
||||
auto func = UVCB::get<Timer, &startCallback>(this);
|
||||
startCb = std::move(cb);
|
||||
auto err = uv_timer_start(get<uv_timer_t>(), func, timeout.count(), rep.count());
|
||||
|
||||
if(err) {
|
||||
callback(UVWError{err});
|
||||
startCb(UVWError{err});
|
||||
reset();
|
||||
}
|
||||
}
|
||||
|
||||
void stop() noexcept { uv_timer_stop(&handle); }
|
||||
void again() noexcept { uv_timer_again(&handle); }
|
||||
void repeat(const Time &rep) noexcept { uv_timer_set_repeat(&handle, rep.count()); }
|
||||
Time repeat() const noexcept { return Time{uv_timer_get_repeat(&handle)}; }
|
||||
UVWError stop() noexcept { return UVWError{uv_timer_stop(get<uv_timer_t>())}; }
|
||||
UVWError again() noexcept { return UVWError{uv_timer_again(get<uv_timer_t>())}; }
|
||||
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(get<uv_timer_t>())}; }
|
||||
|
||||
explicit operator bool() { return initialized; }
|
||||
|
||||
private:
|
||||
uv_timer_t handle;
|
||||
Callback callback;
|
||||
std::function<void(UVWError)> startCb;
|
||||
bool initialized;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -4,14 +4,26 @@
|
||||
|
||||
void f(uvw::Loop &loop) {
|
||||
uvw::Handle<uvw::Tcp> handle = loop.handle<uvw::Tcp>();
|
||||
auto cb = [h{handle}](uvw::UVWError err){ std::cout << "---" << ((bool)err) << std::endl; };
|
||||
|
||||
auto cb = [handle](uvw::UVWError err) mutable {
|
||||
std::cout << "---" << ((bool)err) << std::endl;
|
||||
uvw::Tcp &tcp = handle;
|
||||
tcp.close([](uvw::UVWError err) mutable {
|
||||
std::cout << "---" << ((bool)err) << std::endl;
|
||||
});
|
||||
};
|
||||
|
||||
uvw::Tcp &tcp = handle;
|
||||
tcp.connect<uvw::Tcp::IPv4>(std::string{"127.0.0.1"}, 80, cb);
|
||||
}
|
||||
|
||||
void g() {
|
||||
auto loop = uvw::Loop::getDefault();
|
||||
f(*loop);
|
||||
loop->run();
|
||||
loop = nullptr;
|
||||
}
|
||||
|
||||
int main() {
|
||||
uvw::Loop loop;
|
||||
f(loop);
|
||||
loop.runWait();
|
||||
g();
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user