#pragma once #include "event.hpp" #include "settings.hpp" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include struct ConnectEvent : Event { }; struct DisconnectEvent : Event { }; struct LineEvent : Event { explicit LineEvent(char * line) : line{line} {} char * line; }; class Connection : public std::enable_shared_from_this { using EventDispatcher = eventpp::EventDispatcher; public: template class Handle { EventDispatcher::Handle handle; Handle(EventDispatcher::Handle handle) : handle{handle} {} public: Handle() : handle{} {} friend Connection; }; private: boost::asio::ip::tcp::socket stream_; boost::asio::steady_timer write_timer_; std::list write_strings_; EventDispatcher dispatcher_; auto writer() -> void; auto writer_immediate() -> void; public: Connection(boost::asio::io_context & io); template auto add_listener(F f) -> Handle { return Handle{dispatcher_.appendListener( typeid(T), eventpp::argumentAdapter(f) )}; } template auto remove_listener(Handle handle) -> void { dispatcher_.removeListener(typeid(T), handle.handle); } template auto dispatch(T& event) -> void { dispatcher_.dispatch(typeid(T), event); } auto get_executor() -> boost::asio::any_io_executor { return stream_.get_executor(); } template auto make_event(Args&& ... args) { auto event = T{std::forward(args)...}; dispatch(event); } /// Write bytes into the socket. Messages should be properly newline terminated. auto write_line(std::string message) -> void; auto connect( boost::asio::io_context & io, std::string host, std::string port ) -> boost::asio::awaitable; auto close() -> void; };