diff options
| author | Felix Morgner <felix.morgner@gmail.com> | 2023-08-17 12:32:50 +0200 |
|---|---|---|
| committer | Felix Morgner <felix.morgner@gmail.com> | 2023-08-17 12:32:50 +0200 |
| commit | 375799fa79d1af76f33299acc20a11a167a021f8 (patch) | |
| tree | 8f91b982ec96225c33a2f4871730ababffe5cab0 /source/lib/control/src/connection.cpp | |
| parent | af471b9b780869915d3217b228e24d025892de47 (diff) | |
| download | wanda-375799fa79d1af76f33299acc20a11a167a021f8.tar.xz wanda-375799fa79d1af76f33299acc20a11a167a021f8.zip | |
project: restructure libraries and build env
Diffstat (limited to 'source/lib/control/src/connection.cpp')
| -rw-r--r-- | source/lib/control/src/connection.cpp | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/source/lib/control/src/connection.cpp b/source/lib/control/src/connection.cpp new file mode 100644 index 0000000..30fc8af --- /dev/null +++ b/source/lib/control/src/connection.cpp @@ -0,0 +1,124 @@ +#include "wanda/control/connection.hpp" + +#include "wanda/proto/message.hpp" + +#include <asio.hpp> + +#include <limits> + +namespace wanda::control +{ + connection::pointer make_connection(connection::protocol::socket && socket) + { + return std::make_shared<connection>(connection::key{}, std::move(socket)); + } + + connection::connection(connection::key key, connection::protocol::socket socket) + : keyed{key} + , m_socket{std::move(socket)} + { + } + + bool connection::add(listener * listener) + { + auto [_, inserted] = m_listeners.insert(listener); + return inserted; + } + + bool connection::remove(listener * listener) + { + return m_listeners.erase(listener); + } + + void connection::start() + { + if (m_state == state::unknown) + { + m_state = state::fresh; + perform_read(); + } + } + + void connection::send(proto::message message) + { + m_output << message << '\n'; + asio::async_write(m_socket, m_out, asio::transfer_exactly(message.size() + 1), [that = shared_from_this(), this](auto const & error, auto const length) { + if (error) + { + // TODO: Handle error + } + else + { + m_out.consume(length); + } + }); + } + + void connection::close() + { + if (auto error = std::error_code{}; m_socket.cancel(error)) + { + for (auto & listener : m_listeners) + { + listener->on_error(shared_from_this(), error); + } + } + + if (auto error = std::error_code{}; m_socket.close(error)) + { + for (auto & listener : m_listeners) + { + listener->on_error(shared_from_this(), error); + } + } + + for (auto & listener : m_listeners) + { + listener->on_close(shared_from_this()); + } + m_listeners.clear(); + } + + void connection::update(state state) + { + m_state = state; + } + + connection::state connection::current_state() const + { + return m_state; + } + + void connection::perform_read() + { + asio::async_read_until(m_socket, m_in, '\n', [that = shared_from_this(), this](auto const & error, auto const length) { + if (error) + { + for (auto & listener : m_listeners) + { + listener->on_error(shared_from_this(), error); + } + close(); + } + else + { + auto msg = proto::message{}; + m_input >> msg; + if (!m_input) + { + m_input.ignore(std::numeric_limits<std::streamsize>::max()); + m_input.clear(); + } + else + { + for (auto & listener : m_listeners) + { + listener->on_received(shared_from_this(), msg); + } + } + perform_read(); + } + }); + } + +} // namespace wanda::control
\ No newline at end of file |
