/* * This file is part of the Flowee project * Copyright (C) 2016, 2019-2020 Tom Zander * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "NetworkConnection.h" #include "NetworkManager.h" #include "NetworkManager_p.h" #include #include NetworkConnection::NetworkConnection() : m_id(-1), m_callbacksId(-1) { } NetworkConnection::NetworkConnection(NetworkManager *parent, int id) : m_id(id), m_callbacksId(-1) { auto priv = parent->priv().lock(); if (priv) m_parent = priv->connections.at(id); } NetworkConnection::NetworkConnection(std::shared_ptr &parent, int id) : m_parent(parent), m_id(id), m_callbacksId(-1) { } NetworkConnection::NetworkConnection(NetworkConnection &&other) : m_parent(std::move(other.m_parent)), m_id(other.m_id), m_callbacksId(other.m_callbacksId) { other.m_id = -1; other.m_parent.reset(); } NetworkConnection& NetworkConnection::operator=(NetworkConnection && other) { if (other.m_id != m_id && m_callbacksId != -1) clear(); m_parent = std::move(other.m_parent); other.m_parent.reset(); m_id = other.m_id; other.m_id = -1; m_callbacksId = other.m_callbacksId; return *this; } void NetworkConnection::dummy() const { // intentionally empty } void NetworkConnection::clear() { auto d = m_parent.lock(); if (d) { if (m_callbacksId >= 0) d->m_strand.post(std::bind(&NetworkManagerConnection::removeAllCallbacksFor, d, m_callbacksId)); m_callbacksId = -1; m_parent.reset(); } } NetworkConnection::~NetworkConnection() { clear(); } bool NetworkConnection::isValid() const { if (m_id <= 0) // default constructor called return false; auto d = m_parent.lock(); return d != nullptr; } bool NetworkConnection::isConnected() const { auto d = m_parent.lock(); if (d) return d->isConnected(); return false; } EndPoint NetworkConnection::endPoint() const { auto d = m_parent.lock(); if (d) return d->endPoint(); return EndPoint(); } void NetworkConnection::accept() { auto d = m_parent.lock(); if (d && d->isConnected()) d->accept(); } void NetworkConnection::connect() { auto d = m_parent.lock(); if (d.get()) d->connect(); } void NetworkConnection::disconnect() { auto d = m_parent.lock(); if (d) { if (d->m_strand.running_in_this_thread()) d->disconnect(); else d->m_strand.post(std::bind(&NetworkManagerConnection::disconnect, d)); } } void NetworkConnection::shutdown() { auto d = m_parent.lock(); if (d) d->m_strand.post(std::bind(&NetworkManagerConnection::recycleConnection, d)); } void NetworkConnection::send(const Message &message, MessagePriority priority) { auto d = m_parent.lock(); if (d) d->queueMessage(message, priority); } void NetworkConnection::setOnConnected(const std::function &callback) { auto d = m_parent.lock(); if (d) { if (m_callbacksId < 0) m_callbacksId = d->nextCallbackId(); if (d->m_strand.running_in_this_thread()) d->addOnConnectedCallback(m_callbacksId, callback); else d->m_strand.post(std::bind(&NetworkManagerConnection::addOnConnectedCallback, d, m_callbacksId, callback)); } } void NetworkConnection::setOnDisconnected(const std::function &callback) { auto d = m_parent.lock(); if (d) { if (m_callbacksId < 0) m_callbacksId = d->nextCallbackId(); if (d->m_strand.running_in_this_thread()) d->addOnDisconnectedCallback(m_callbacksId, callback); else d->m_strand.post(std::bind(&NetworkManagerConnection::addOnDisconnectedCallback, d, m_callbacksId, callback)); } } void NetworkConnection::setOnIncomingMessage(const std::function &callback) { auto d = m_parent.lock(); if (d) { if (m_callbacksId < 0) m_callbacksId = d->nextCallbackId(); if (d->m_strand.running_in_this_thread()) d->addOnIncomingMessageCallback(m_callbacksId, callback); else d->m_strand.post(std::bind(&NetworkManagerConnection::addOnIncomingMessageCallback, d, m_callbacksId, callback)); } } void NetworkConnection::setOnError(const std::function &callback) { auto d = m_parent.lock(); if (d) { if (m_callbacksId < 0) m_callbacksId = d->nextCallbackId(); if (d->m_strand.running_in_this_thread()) d->addOnError(m_callbacksId, callback); else d->m_strand.post(std::bind(&NetworkManagerConnection::addOnError, d, m_callbacksId, callback)); } } void NetworkConnection::punishPeer(int punishment) { auto d = m_parent.lock(); if (d.get()) { d->punish(punishment); } } void NetworkConnection::postOnStrand(const std::function &task) { auto d = m_parent.lock(); if (d) d->runOnStrand(task); } void NetworkConnection::setMessageHeaderLegacy(bool on) { auto d = m_parent.lock(); if (d) d->setMessageHeaderType(on ? NetworkManagerConnection::LegacyP2P : NetworkManagerConnection::FloweeNative); } void NetworkConnection::setMessageQueueSizes(int main, int priority) { assert(main >= 1); assert(main <= 0xeFFF); assert(priority >= 1); assert(priority <= 0xeFFF); auto d = m_parent.lock(); if (d) d->setMessageQueueSizes(static_cast(main), static_cast(priority)); }