diff --git a/assignment-client/src/metavoxels/MetavoxelServer.cpp b/assignment-client/src/metavoxels/MetavoxelServer.cpp index fa934142d3..3f9f5114dd 100644 --- a/assignment-client/src/metavoxels/MetavoxelServer.cpp +++ b/assignment-client/src/metavoxels/MetavoxelServer.cpp @@ -28,15 +28,16 @@ void MetavoxelServer::applyEdit(const MetavoxelEditMessage& edit) { edit.apply(_data); } -void MetavoxelServer::removeSession(const QUuid& sessionId) { - _sessions.take(sessionId)->deleteLater(); -} - const char METAVOXEL_SERVER_LOGGING_NAME[] = "metavoxel-server"; void MetavoxelServer::run() { commonInit(METAVOXEL_SERVER_LOGGING_NAME, NodeType::MetavoxelServer); + NodeList* nodeList = NodeList::getInstance(); + nodeList->addNodeTypeToInterestSet(NodeType::Agent); + + connect(nodeList, SIGNAL(nodeAdded(SharedNodePointer)), SLOT(maybeAttachSession(const SharedNodePointer&))); + _lastSend = QDateTime::currentMSecsSinceEpoch(); _sendTimer.start(SEND_INTERVAL); } @@ -50,25 +51,31 @@ void MetavoxelServer::readPendingDatagrams() { while (readAvailableDatagram(receivedPacket, senderSockAddr)) { if (nodeList->packetVersionAndHashMatch(receivedPacket)) { switch (packetTypeForPacket(receivedPacket)) { - case PacketTypeMetavoxelData: { - SharedNodePointer matchingNode = nodeList->sendingNodeForPacket(receivedPacket); - if (matchingNode) { - processData(receivedPacket, matchingNode); - } + case PacketTypeMetavoxelData: + nodeList->findNodeAndUpdateWithDataFromPacket(receivedPacket); break; - } + default: - NodeList::getInstance()->processNodeData(senderSockAddr, receivedPacket); + nodeList->processNodeData(senderSockAddr, receivedPacket); break; } } } } +void MetavoxelServer::maybeAttachSession(const SharedNodePointer& node) { + if (node->getType() == NodeType::Agent) { + QMutexLocker locker(&node->getMutex()); + node->setLinkedData(new MetavoxelSession(this, NodeList::getInstance()->nodeWithUUID(node->getUUID()))); + } +} + void MetavoxelServer::sendDeltas() { // send deltas for all sessions - foreach (MetavoxelSession* session, _sessions) { - session->sendDelta(); + foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) { + if (node->getType() == NodeType::Agent) { + static_cast(node->getLinkedData())->sendDelta(); + } } // restart the send timer @@ -79,35 +86,10 @@ void MetavoxelServer::sendDeltas() { _sendTimer.start(qMax(0, 2 * SEND_INTERVAL - elapsed)); } -void MetavoxelServer::processData(const QByteArray& data, const SharedNodePointer& sendingNode) { - // read the session id - int headerPlusIDSize; - QUuid sessionID = readSessionID(data, sendingNode, headerPlusIDSize); - if (sessionID.isNull()) { - return; - } - - // forward to session, creating if necessary - MetavoxelSession*& session = _sessions[sessionID]; - if (!session) { - session = new MetavoxelSession(this, sessionID, QByteArray::fromRawData(data.constData(), headerPlusIDSize), - sendingNode); - } - session->receivedData(data, sendingNode); -} - -MetavoxelSession::MetavoxelSession(MetavoxelServer* server, const QUuid& sessionId, - const QByteArray& datagramHeader, const SharedNodePointer& sendingNode) : - QObject(server), +MetavoxelSession::MetavoxelSession(MetavoxelServer* server, const SharedNodePointer& node) : _server(server), - _sessionId(sessionId), - _sequencer(datagramHeader), - _sendingNode(sendingNode) { - - const int TIMEOUT_INTERVAL = 30 * 1000; - _timeoutTimer.setInterval(TIMEOUT_INTERVAL); - _timeoutTimer.setSingleShot(true); - connect(&_timeoutTimer, SIGNAL(timeout()), SLOT(timedOut())); + _sequencer(byteArrayWithPopluatedHeader(PacketTypeMetavoxelData)), + _node(node) { connect(&_sequencer, SIGNAL(readyToWrite(const QByteArray&)), SLOT(sendData(const QByteArray&))); connect(&_sequencer, SIGNAL(readyToRead(Bitstream&)), SLOT(readPacket(Bitstream&))); @@ -117,19 +99,15 @@ MetavoxelSession::MetavoxelSession(MetavoxelServer* server, const QUuid& session // insert the baseline send record SendRecord record = { 0 }; _sendRecords.append(record); - - qDebug() << "Opened session [sessionId=" << _sessionId << ", sendingNode=" << sendingNode << "]"; } -void MetavoxelSession::receivedData(const QByteArray& data, const SharedNodePointer& sendingNode) { - // reset the timeout timer - _timeoutTimer.start(); +MetavoxelSession::~MetavoxelSession() { +} - // save the most recent sender - _sendingNode = sendingNode; - +int MetavoxelSession::parseData(const QByteArray& packet) { // process through sequencer - _sequencer.receivedDatagram(data); + _sequencer.receivedDatagram(packet); + return packet.size(); } void MetavoxelSession::sendDelta() { @@ -143,13 +121,8 @@ void MetavoxelSession::sendDelta() { _sendRecords.append(record); } -void MetavoxelSession::timedOut() { - qDebug() << "Session timed out [sessionId=" << _sessionId << ", sendingNode=" << _sendingNode << "]"; - _server->removeSession(_sessionId); -} - void MetavoxelSession::sendData(const QByteArray& data) { - NodeList::getInstance()->writeDatagram(data, _sendingNode); + NodeList::getInstance()->writeDatagram(data, _node); } void MetavoxelSession::readPacket(Bitstream& in) { @@ -164,11 +137,7 @@ void MetavoxelSession::clearSendRecordsBefore(int index) { void MetavoxelSession::handleMessage(const QVariant& message) { int userType = message.userType(); - if (userType == CloseSessionMessage::Type) { - qDebug() << "Session closed [sessionId=" << _sessionId << ", sendingNode=" << _sendingNode << "]"; - _server->removeSession(_sessionId); - - } else if (userType == ClientStateMessage::Type) { + if (userType == ClientStateMessage::Type) { ClientStateMessage state = message.value(); _position = state.position; diff --git a/assignment-client/src/metavoxels/MetavoxelServer.h b/assignment-client/src/metavoxels/MetavoxelServer.h index 60fdeca5a5..a7939ee115 100644 --- a/assignment-client/src/metavoxels/MetavoxelServer.h +++ b/assignment-client/src/metavoxels/MetavoxelServer.h @@ -9,12 +9,9 @@ #ifndef __hifi__MetavoxelServer__ #define __hifi__MetavoxelServer__ -#include #include #include -#include -#include #include #include @@ -35,45 +32,38 @@ public: const MetavoxelData& getData() const { return _data; } - void removeSession(const QUuid& sessionId); - virtual void run(); virtual void readPendingDatagrams(); private slots: - + + void maybeAttachSession(const SharedNodePointer& node); void sendDeltas(); private: - void processData(const QByteArray& data, const SharedNodePointer& sendingNode); - QTimer _sendTimer; qint64 _lastSend; - QHash _sessions; - MetavoxelData _data; }; /// Contains the state of a single client session. -class MetavoxelSession : public QObject { +class MetavoxelSession : public NodeData { Q_OBJECT public: - MetavoxelSession(MetavoxelServer* server, const QUuid& sessionId, - const QByteArray& datagramHeader, const SharedNodePointer& sendingNode); + MetavoxelSession(MetavoxelServer* server, const SharedNodePointer& node); + virtual ~MetavoxelSession(); - void receivedData(const QByteArray& data, const SharedNodePointer& sendingNode); + virtual int parseData(const QByteArray& packet); void sendDelta(); private slots: - void timedOut(); - void sendData(const QByteArray& data); void readPacket(Bitstream& in); @@ -91,12 +81,10 @@ private: }; MetavoxelServer* _server; - QUuid _sessionId; - QTimer _timeoutTimer; DatagramSequencer _sequencer; - SharedNodePointer _sendingNode; + SharedNodePointer _node; glm::vec3 _position; diff --git a/interface/src/DatagramProcessor.cpp b/interface/src/DatagramProcessor.cpp index d8447168cd..18e3742bd7 100644 --- a/interface/src/DatagramProcessor.cpp +++ b/interface/src/DatagramProcessor.cpp @@ -94,7 +94,7 @@ void DatagramProcessor::processDatagrams() { break; } case PacketTypeMetavoxelData: - application->_metavoxels.processData(incomingPacket, senderSockAddr); + nodeList->findNodeAndUpdateWithDataFromPacket(incomingPacket); break; case PacketTypeBulkAvatarData: case PacketTypeKillAvatar: diff --git a/interface/src/MetavoxelSystem.cpp b/interface/src/MetavoxelSystem.cpp index 34c3be5308..3c3683f0dc 100644 --- a/interface/src/MetavoxelSystem.cpp +++ b/interface/src/MetavoxelSystem.cpp @@ -25,12 +25,6 @@ MetavoxelSystem::MetavoxelSystem() : _buffer(QOpenGLBuffer::VertexBuffer) { } -MetavoxelSystem::~MetavoxelSystem() { - for (QHash::const_iterator it = _clients.begin(); it != _clients.end(); it++) { - delete it.value(); - } -} - void MetavoxelSystem::init() { if (!_program.isLinked()) { switchToResourcesParentIfRequired(); @@ -42,33 +36,35 @@ void MetavoxelSystem::init() { // let the script cache know to use our common access manager ScriptCache::getInstance()->setNetworkAccessManager(Application::getInstance()->getNetworkAccessManager()); } - - NodeList* nodeList = NodeList::getInstance(); - - connect(nodeList, SIGNAL(nodeAdded(SharedNodePointer)), SLOT(nodeAdded(SharedNodePointer))); - connect(nodeList, SIGNAL(nodeKilled(SharedNodePointer)), SLOT(nodeKilled(SharedNodePointer))); - _buffer.setUsagePattern(QOpenGLBuffer::DynamicDraw); _buffer.create(); + + connect(NodeList::getInstance(), SIGNAL(nodeAdded(SharedNodePointer)), SLOT(maybeAttachClient(const SharedNodePointer&))); } void MetavoxelSystem::applyEdit(const MetavoxelEditMessage& edit) { - foreach (MetavoxelClient* client, _clients) { - client->applyEdit(edit); + foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) { + if (node->getType() == NodeType::MetavoxelServer) { + MetavoxelClient* client = static_cast(node->getLinkedData()); + if (client) { + client->applyEdit(edit); + } + } } } -void MetavoxelSystem::processData(const QByteArray& data, const HifiSockAddr& sender) { - QMetaObject::invokeMethod(this, "receivedData", Q_ARG(const QByteArray&, data), Q_ARG(const HifiSockAddr&, sender)); -} - void MetavoxelSystem::simulate(float deltaTime) { // simulate the clients _points.clear(); - foreach (MetavoxelClient* client, _clients) { - client->simulate(deltaTime, _pointVisitor); + foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) { + if (node->getType() == NodeType::MetavoxelServer) { + MetavoxelClient* client = static_cast(node->getLinkedData()); + if (client) { + client->simulate(deltaTime, _pointVisitor); + } + } } - + _buffer.bind(); int bytes = _points.size() * sizeof(Point); if (_buffer.size() < bytes) { @@ -120,39 +116,10 @@ void MetavoxelSystem::render() { _program.release(); } -void MetavoxelSystem::nodeAdded(SharedNodePointer node) { +void MetavoxelSystem::maybeAttachClient(const SharedNodePointer& node) { if (node->getType() == NodeType::MetavoxelServer) { - QMetaObject::invokeMethod(this, "addClient", Q_ARG(const SharedNodePointer&, node)); - } -} - -void MetavoxelSystem::nodeKilled(SharedNodePointer node) { - if (node->getType() == NodeType::MetavoxelServer) { - QMetaObject::invokeMethod(this, "removeClient", Q_ARG(const QUuid&, node->getUUID())); - } -} - -void MetavoxelSystem::addClient(const SharedNodePointer& node) { - MetavoxelClient* client = new MetavoxelClient(node); - _clients.insert(node->getUUID(), client); - _clientsBySessionID.insert(client->getSessionID(), client); -} - -void MetavoxelSystem::removeClient(const QUuid& uuid) { - MetavoxelClient* client = _clients.take(uuid); - _clientsBySessionID.remove(client->getSessionID()); - delete client; -} - -void MetavoxelSystem::receivedData(const QByteArray& data, const SharedNodePointer& sendingNode) { - int headerPlusIDSize; - QUuid sessionID = readSessionID(data, sendingNode, headerPlusIDSize); - if (sessionID.isNull()) { - return; - } - MetavoxelClient* client = _clientsBySessionID.value(sessionID); - if (client) { - client->receivedData(data); + QMutexLocker locker(&node->getMutex()); + node->setLinkedData(new MetavoxelClient(NodeList::getInstance()->nodeWithUUID(node->getUUID()))); } } @@ -179,16 +146,9 @@ bool MetavoxelSystem::PointVisitor::visit(MetavoxelInfo& info) { return false; } -static QByteArray createDatagramHeader(const QUuid& sessionID) { - QByteArray header = byteArrayWithPopluatedHeader(PacketTypeMetavoxelData); - header += sessionID.toRfc4122(); - return header; -} - MetavoxelClient::MetavoxelClient(const SharedNodePointer& node) : _node(node), - _sessionID(QUuid::createUuid()), - _sequencer(createDatagramHeader(_sessionID)) { + _sequencer(byteArrayWithPopluatedHeader(PacketTypeMetavoxelData)) { connect(&_sequencer, SIGNAL(readyToWrite(const QByteArray&)), SLOT(sendData(const QByteArray&))); connect(&_sequencer, SIGNAL(readyToRead(Bitstream&)), SLOT(readPacket(Bitstream&))); @@ -223,9 +183,10 @@ void MetavoxelClient::simulate(float deltaTime, MetavoxelVisitor& visitor) { _data.guide(visitor); } -void MetavoxelClient::receivedData(const QByteArray& data) { +int MetavoxelClient::parseData(const QByteArray& packet) { // process through sequencer - _sequencer.receivedDatagram(data); + QMetaObject::invokeMethod(&_sequencer, "receivedDatagram", Q_ARG(const QByteArray&, packet)); + return packet.size(); } void MetavoxelClient::sendData(const QByteArray& data) { diff --git a/interface/src/MetavoxelSystem.h b/interface/src/MetavoxelSystem.h index 7bb7935e4d..40765723fd 100644 --- a/interface/src/MetavoxelSystem.h +++ b/interface/src/MetavoxelSystem.h @@ -23,8 +23,6 @@ #include "renderer/ProgramObject.h" -class MetavoxelClient; - /// Renders a metavoxel tree. class MetavoxelSystem : public QObject { Q_OBJECT @@ -32,28 +30,20 @@ class MetavoxelSystem : public QObject { public: MetavoxelSystem(); - ~MetavoxelSystem(); void init(); void applyEdit(const MetavoxelEditMessage& edit); - void processData(const QByteArray& data, const HifiSockAddr& sender); - void simulate(float deltaTime); void render(); -public slots: +private slots: + + void maybeAttachClient(const SharedNodePointer& node); - void nodeAdded(SharedNodePointer node); - void nodeKilled(SharedNodePointer node); - private: - - Q_INVOKABLE void addClient(const SharedNodePointer& node); - Q_INVOKABLE void removeClient(const QUuid& uuid); - Q_INVOKABLE void receivedData(const QByteArray& data, const SharedNodePointer& sendingNode); - + class Point { public: glm::vec4 vertex; @@ -76,13 +66,10 @@ private: QVector _points; PointVisitor _pointVisitor; QOpenGLBuffer _buffer; - - QHash _clients; - QHash _clientsBySessionID; }; /// A client session associated with a single server. -class MetavoxelClient : public QObject { +class MetavoxelClient : public NodeData { Q_OBJECT public: @@ -90,13 +77,11 @@ public: MetavoxelClient(const SharedNodePointer& node); virtual ~MetavoxelClient(); - const QUuid& getSessionID() const { return _sessionID; } - void applyEdit(const MetavoxelEditMessage& edit); void simulate(float deltaTime, MetavoxelVisitor& visitor); - void receivedData(const QByteArray& data); + virtual int parseData(const QByteArray& packet); private slots: @@ -117,7 +102,6 @@ private: }; SharedNodePointer _node; - QUuid _sessionID; DatagramSequencer _sequencer; diff --git a/libraries/metavoxels/src/DatagramSequencer.h b/libraries/metavoxels/src/DatagramSequencer.h index 7156175f51..13bdf4c7bf 100644 --- a/libraries/metavoxels/src/DatagramSequencer.h +++ b/libraries/metavoxels/src/DatagramSequencer.h @@ -70,7 +70,7 @@ public: /// Processes a datagram received from the other party, emitting readyToRead when the entire packet /// has been successfully assembled. - void receivedDatagram(const QByteArray& datagram); + Q_INVOKABLE void receivedDatagram(const QByteArray& datagram); signals: