Use the refactored endpoint/client classes in the actual client/server.

This commit is contained in:
Andrzej Kapolka 2014-06-26 19:11:54 -07:00
parent 4b2d122f3d
commit f16098daef
9 changed files with 101 additions and 319 deletions

View file

@ -69,7 +69,7 @@ void MetavoxelServer::readPendingDatagrams() {
void MetavoxelServer::maybeAttachSession(const SharedNodePointer& node) { void MetavoxelServer::maybeAttachSession(const SharedNodePointer& node) {
if (node->getType() == NodeType::Agent) { if (node->getType() == NodeType::Agent) {
QMutexLocker locker(&node->getMutex()); QMutexLocker locker(&node->getMutex());
node->setLinkedData(new MetavoxelSession(this, NodeList::getInstance()->nodeWithUUID(node->getUUID()))); node->setLinkedData(new MetavoxelSession(node, this));
} }
} }
@ -77,7 +77,7 @@ void MetavoxelServer::sendDeltas() {
// send deltas for all sessions // send deltas for all sessions
foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) { foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) {
if (node->getType() == NodeType::Agent) { if (node->getType() == NodeType::Agent) {
static_cast<MetavoxelSession*>(node->getLinkedData())->sendDelta(); static_cast<MetavoxelSession*>(node->getLinkedData())->update();
} }
} }
@ -89,59 +89,34 @@ void MetavoxelServer::sendDeltas() {
_sendTimer.start(qMax(0, 2 * SEND_INTERVAL - elapsed)); _sendTimer.start(qMax(0, 2 * SEND_INTERVAL - elapsed));
} }
MetavoxelSession::MetavoxelSession(MetavoxelServer* server, const SharedNodePointer& node) : MetavoxelSession::MetavoxelSession(const SharedNodePointer& node, MetavoxelServer* server) :
_server(server), Endpoint(node, new PacketRecord(), NULL),
_sequencer(byteArrayWithPopulatedHeader(PacketTypeMetavoxelData)), _server(server) {
_node(node) {
connect(&_sequencer, SIGNAL(readyToWrite(const QByteArray&)), SLOT(sendData(const QByteArray&)));
connect(&_sequencer, SIGNAL(readyToRead(Bitstream&)), SLOT(readPacket(Bitstream&)));
connect(&_sequencer, SIGNAL(sendAcknowledged(int)), SLOT(clearSendRecordsBefore(int)));
connect(&_sequencer, SIGNAL(receivedHighPriorityMessage(const QVariant&)), SLOT(handleMessage(const QVariant&))); connect(&_sequencer, SIGNAL(receivedHighPriorityMessage(const QVariant&)), SLOT(handleMessage(const QVariant&)));
connect(_sequencer.getReliableInputChannel(), SIGNAL(receivedMessage(const QVariant&)), connect(_sequencer.getReliableInputChannel(), SIGNAL(receivedMessage(const QVariant&)),
SLOT(handleMessage(const QVariant&))); SLOT(handleMessage(const QVariant&)));
// insert the baseline send record
SendRecord record = { 0 };
_sendRecords.append(record);
} }
MetavoxelSession::~MetavoxelSession() { void MetavoxelSession::update() {
}
int MetavoxelSession::parseData(const QByteArray& packet) {
// process through sequencer
_sequencer.receivedDatagram(packet);
return packet.size();
}
void MetavoxelSession::sendDelta() {
// wait until we have a valid lod // wait until we have a valid lod
if (!_lod.isValid()) { if (_lod.isValid()) {
return; Endpoint::update();
} }
Bitstream& out = _sequencer.startPacket(); }
void MetavoxelSession::writeUpdateMessage(Bitstream& out) {
out << QVariant::fromValue(MetavoxelDeltaMessage()); out << QVariant::fromValue(MetavoxelDeltaMessage());
_server->getData().writeDelta(_sendRecords.first().data, _sendRecords.first().lod, out, _lod); PacketRecord* sendRecord = getLastAcknowledgedSendRecord();
_sequencer.endPacket(); _server->getData().writeDelta(sendRecord->getData(), sendRecord->getLOD(), out, _lod);
// record the send
SendRecord record = { _sequencer.getOutgoingPacketNumber(), _server->getData(), _lod };
_sendRecords.append(record);
} }
void MetavoxelSession::sendData(const QByteArray& data) { void MetavoxelSession::handleMessage(const QVariant& message, Bitstream& in) {
NodeList::getInstance()->writeDatagram(data, _node);
}
void MetavoxelSession::readPacket(Bitstream& in) {
QVariant message;
in >> message;
handleMessage(message); handleMessage(message);
} }
void MetavoxelSession::clearSendRecordsBefore(int index) { PacketRecord* MetavoxelSession::maybeCreateSendRecord() const {
_sendRecords.erase(_sendRecords.begin(), _sendRecords.begin() + index + 1); return new PacketRecord(_lod, _server->getData());
} }
void MetavoxelSession::handleMessage(const QVariant& message) { void MetavoxelSession::handleMessage(const QVariant& message) {

View file

@ -17,8 +17,7 @@
#include <ThreadedAssignment.h> #include <ThreadedAssignment.h>
#include <DatagramSequencer.h> #include <Endpoint.h>
#include <MetavoxelData.h>
class MetavoxelEditMessage; class MetavoxelEditMessage;
class MetavoxelSession; class MetavoxelSession;
@ -53,46 +52,31 @@ private:
}; };
/// Contains the state of a single client session. /// Contains the state of a single client session.
class MetavoxelSession : public NodeData { class MetavoxelSession : public Endpoint {
Q_OBJECT Q_OBJECT
public: public:
MetavoxelSession(MetavoxelServer* server, const SharedNodePointer& node); MetavoxelSession(const SharedNodePointer& node, MetavoxelServer* server);
virtual ~MetavoxelSession();
virtual int parseData(const QByteArray& packet); virtual void update();
void sendDelta(); protected:
virtual void writeUpdateMessage(Bitstream& out);
virtual void handleMessage(const QVariant& message, Bitstream& in);
virtual PacketRecord* maybeCreateSendRecord() const;
private slots: private slots:
void sendData(const QByteArray& data);
void readPacket(Bitstream& in);
void clearSendRecordsBefore(int index);
void handleMessage(const QVariant& message); void handleMessage(const QVariant& message);
private: private:
class SendRecord {
public:
int packetNumber;
MetavoxelData data;
MetavoxelLOD lod;
};
MetavoxelServer* _server; MetavoxelServer* _server;
DatagramSequencer _sequencer;
SharedNodePointer _node;
MetavoxelLOD _lod; MetavoxelLOD _lod;
QList<SendRecord> _sendRecords;
}; };
#endif // hifi_MetavoxelServer_h #endif // hifi_MetavoxelServer_h

View file

@ -35,6 +35,8 @@ MetavoxelSystem::MetavoxelSystem() :
} }
void MetavoxelSystem::init() { void MetavoxelSystem::init() {
MetavoxelClientManager::init();
if (!_program.isLinked()) { if (!_program.isLinked()) {
_program.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath() + "shaders/metavoxel_point.vert"); _program.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath() + "shaders/metavoxel_point.vert");
_program.link(); _program.link();
@ -43,62 +45,19 @@ void MetavoxelSystem::init() {
} }
_buffer.setUsagePattern(QOpenGLBuffer::DynamicDraw); _buffer.setUsagePattern(QOpenGLBuffer::DynamicDraw);
_buffer.create(); _buffer.create();
connect(NodeList::getInstance(), SIGNAL(nodeAdded(SharedNodePointer)), SLOT(maybeAttachClient(const SharedNodePointer&)));
} }
SharedObjectPointer MetavoxelSystem::findFirstRaySpannerIntersection( MetavoxelLOD MetavoxelSystem::getLOD() const {
const glm::vec3& origin, const glm::vec3& direction, const AttributePointer& attribute, float& distance) { const float FIXED_LOD_THRESHOLD = 0.01f;
SharedObjectPointer closestSpanner; return MetavoxelLOD(Application::getInstance()->getCamera()->getPosition(), FIXED_LOD_THRESHOLD);
float closestDistance = FLT_MAX;
foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) {
if (node->getType() == NodeType::MetavoxelServer) {
QMutexLocker locker(&node->getMutex());
MetavoxelSystemClient* client = static_cast<MetavoxelSystemClient*>(node->getLinkedData());
if (client) {
float clientDistance;
SharedObjectPointer clientSpanner = client->getData().findFirstRaySpannerIntersection(
origin, direction, attribute, clientDistance);
if (clientSpanner && clientDistance < closestDistance) {
closestSpanner = clientSpanner;
closestDistance = clientDistance;
}
}
}
}
if (closestSpanner) {
distance = closestDistance;
}
return closestSpanner;
}
void MetavoxelSystem::applyEdit(const MetavoxelEditMessage& edit, bool reliable) {
foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) {
if (node->getType() == NodeType::MetavoxelServer) {
QMutexLocker locker(&node->getMutex());
MetavoxelSystemClient* client = static_cast<MetavoxelSystemClient*>(node->getLinkedData());
if (client) {
client->applyEdit(edit, reliable);
}
}
}
} }
void MetavoxelSystem::simulate(float deltaTime) { void MetavoxelSystem::simulate(float deltaTime) {
// simulate the clients // update the clients
_points.clear(); _points.clear();
_simulateVisitor.setDeltaTime(deltaTime); _simulateVisitor.setDeltaTime(deltaTime);
_simulateVisitor.setOrder(-Application::getInstance()->getViewFrustum()->getDirection()); _simulateVisitor.setOrder(-Application::getInstance()->getViewFrustum()->getDirection());
foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) { update();
if (node->getType() == NodeType::MetavoxelServer) {
QMutexLocker locker(&node->getMutex());
MetavoxelSystemClient* client = static_cast<MetavoxelSystemClient*>(node->getLinkedData());
if (client) {
client->simulate(deltaTime);
client->guide(_simulateVisitor);
}
}
}
_buffer.bind(); _buffer.bind();
int bytes = _points.size() * sizeof(Point); int bytes = _points.size() * sizeof(Point);
@ -161,11 +120,13 @@ void MetavoxelSystem::render() {
} }
} }
void MetavoxelSystem::maybeAttachClient(const SharedNodePointer& node) { MetavoxelClient* MetavoxelSystem::createClient(const SharedNodePointer& node) {
if (node->getType() == NodeType::MetavoxelServer) { return new MetavoxelSystemClient(node, this);
QMutexLocker locker(&node->getMutex());
node->setLinkedData(new MetavoxelSystemClient(NodeList::getInstance()->nodeWithUUID(node->getUUID())));
} }
void MetavoxelSystem::updateClient(MetavoxelClient* client) {
MetavoxelClientManager::updateClient(client);
client->guide(_simulateVisitor);
} }
MetavoxelSystem::SimulateVisitor::SimulateVisitor(QVector<Point>& points) : MetavoxelSystem::SimulateVisitor::SimulateVisitor(QVector<Point>& points) :
@ -235,64 +196,8 @@ bool MetavoxelSystem::RenderVisitor::visit(Spanner* spanner, const glm::vec3& cl
return true; return true;
} }
MetavoxelSystemClient::MetavoxelSystemClient(const SharedNodePointer& node) : MetavoxelSystemClient::MetavoxelSystemClient(const SharedNodePointer& node, MetavoxelSystem* system) :
_node(node), MetavoxelClient(node, system) {
_sequencer(byteArrayWithPopulatedHeader(PacketTypeMetavoxelData)) {
connect(&_sequencer, SIGNAL(readyToWrite(const QByteArray&)), SLOT(sendData(const QByteArray&)));
connect(&_sequencer, SIGNAL(readyToRead(Bitstream&)), SLOT(readPacket(Bitstream&)));
connect(&_sequencer, SIGNAL(sendAcknowledged(int)), SLOT(clearSendRecordsBefore(int)));
connect(&_sequencer, SIGNAL(receiveAcknowledged(int)), SLOT(clearReceiveRecordsBefore(int)));
// insert the baseline send record
SendRecord sendRecord = { 0 };
_sendRecords.append(sendRecord);
// insert the baseline receive record
ReceiveRecord receiveRecord = { 0, _data };
_receiveRecords.append(receiveRecord);
}
MetavoxelSystemClient::~MetavoxelSystemClient() {
// close the session
Bitstream& out = _sequencer.startPacket();
out << QVariant::fromValue(CloseSessionMessage());
_sequencer.endPacket();
}
static MetavoxelLOD getLOD() {
const float FIXED_LOD_THRESHOLD = 0.01f;
return MetavoxelLOD(Application::getInstance()->getCamera()->getPosition(), FIXED_LOD_THRESHOLD);
}
void MetavoxelSystemClient::guide(MetavoxelVisitor& visitor) {
visitor.setLOD(getLOD());
_data.guide(visitor);
}
void MetavoxelSystemClient::applyEdit(const MetavoxelEditMessage& edit, bool reliable) {
if (reliable) {
_sequencer.getReliableOutputChannel()->sendMessage(QVariant::fromValue(edit));
} else {
// apply immediately to local tree
edit.apply(_data, _sequencer.getWeakSharedObjectHash());
// start sending it out
_sequencer.sendHighPriorityMessage(QVariant::fromValue(edit));
}
}
void MetavoxelSystemClient::simulate(float deltaTime) {
Bitstream& out = _sequencer.startPacket();
ClientStateMessage state = { getLOD() };
out << QVariant::fromValue(state);
_sequencer.endPacket();
// record the send
SendRecord record = { _sequencer.getOutgoingPacketNumber(), state.lod };
_sendRecords.append(record);
} }
int MetavoxelSystemClient::parseData(const QByteArray& packet) { int MetavoxelSystemClient::parseData(const QByteArray& packet) {
@ -302,48 +207,11 @@ int MetavoxelSystemClient::parseData(const QByteArray& packet) {
return packet.size(); return packet.size();
} }
void MetavoxelSystemClient::sendData(const QByteArray& data) { void MetavoxelSystemClient::sendDatagram(const QByteArray& data) {
NodeList::getInstance()->writeDatagram(data, _node); NodeList::getInstance()->writeDatagram(data, _node);
Application::getInstance()->getBandwidthMeter()->outputStream(BandwidthMeter::METAVOXELS).updateValue(data.size()); Application::getInstance()->getBandwidthMeter()->outputStream(BandwidthMeter::METAVOXELS).updateValue(data.size());
} }
void MetavoxelSystemClient::readPacket(Bitstream& in) {
QVariant message;
in >> message;
handleMessage(message, in);
// record the receipt
ReceiveRecord record = { _sequencer.getIncomingPacketNumber(), _data, _sendRecords.first().lod };
_receiveRecords.append(record);
// reapply local edits
foreach (const DatagramSequencer::HighPriorityMessage& message, _sequencer.getHighPriorityMessages()) {
if (message.data.userType() == MetavoxelEditMessage::Type) {
message.data.value<MetavoxelEditMessage>().apply(_data, _sequencer.getWeakSharedObjectHash());
}
}
}
void MetavoxelSystemClient::clearSendRecordsBefore(int index) {
_sendRecords.erase(_sendRecords.begin(), _sendRecords.begin() + index + 1);
}
void MetavoxelSystemClient::clearReceiveRecordsBefore(int index) {
_receiveRecords.erase(_receiveRecords.begin(), _receiveRecords.begin() + index + 1);
}
void MetavoxelSystemClient::handleMessage(const QVariant& message, Bitstream& in) {
int userType = message.userType();
if (userType == MetavoxelDeltaMessage::Type) {
_data.readDelta(_receiveRecords.first().data, _receiveRecords.first().lod, in, _sendRecords.first().lod);
} else if (userType == QMetaType::QVariantList) {
foreach (const QVariant& element, message.toList()) {
handleMessage(element, in);
}
}
}
static void enableClipPlane(GLenum plane, float x, float y, float z, float w) { static void enableClipPlane(GLenum plane, float x, float y, float z, float w) {
GLdouble coefficients[] = { x, y, z, w }; GLdouble coefficients[] = { x, y, z, w };
glClipPlane(plane, coefficients); glClipPlane(plane, coefficients);

View file

@ -18,37 +18,31 @@
#include <glm/glm.hpp> #include <glm/glm.hpp>
#include <NodeList.h> #include <MetavoxelClientManager.h>
#include <DatagramSequencer.h>
#include <MetavoxelData.h>
#include <MetavoxelMessages.h>
#include "renderer/ProgramObject.h" #include "renderer/ProgramObject.h"
class Model; class Model;
/// Renders a metavoxel tree. /// Renders a metavoxel tree.
class MetavoxelSystem : public QObject { class MetavoxelSystem : public MetavoxelClientManager {
Q_OBJECT Q_OBJECT
public: public:
MetavoxelSystem(); MetavoxelSystem();
void init(); virtual void init();
SharedObjectPointer findFirstRaySpannerIntersection(const glm::vec3& origin, const glm::vec3& direction, virtual MetavoxelLOD getLOD() const;
const AttributePointer& attribute, float& distance);
Q_INVOKABLE void applyEdit(const MetavoxelEditMessage& edit, bool reliable = false);
void simulate(float deltaTime); void simulate(float deltaTime);
void render(); void render();
private slots: protected:
void maybeAttachClient(const SharedNodePointer& node); virtual MetavoxelClient* createClient(const SharedNodePointer& node);
virtual void updateClient(MetavoxelClient* client);
private: private:
@ -89,59 +83,18 @@ private:
}; };
/// A client session associated with a single server. /// A client session associated with a single server.
class MetavoxelSystemClient : public NodeData { class MetavoxelSystemClient : public MetavoxelClient {
Q_OBJECT Q_OBJECT
public: public:
MetavoxelSystemClient(const SharedNodePointer& node); MetavoxelSystemClient(const SharedNodePointer& node, MetavoxelSystem* system);
virtual ~MetavoxelSystemClient();
MetavoxelData& getData() { return _data; }
void guide(MetavoxelVisitor& visitor);
void applyEdit(const MetavoxelEditMessage& edit, bool reliable = false);
void simulate(float deltaTime);
virtual int parseData(const QByteArray& packet); virtual int parseData(const QByteArray& packet);
private slots: protected:
void sendData(const QByteArray& data); virtual void sendDatagram(const QByteArray& data);
void readPacket(Bitstream& in);
void clearSendRecordsBefore(int index);
void clearReceiveRecordsBefore(int index);
private:
void handleMessage(const QVariant& message, Bitstream& in);
class SendRecord {
public:
int packetNumber;
MetavoxelLOD lod;
};
class ReceiveRecord {
public:
int packetNumber;
MetavoxelData data;
MetavoxelLOD lod;
};
SharedNodePointer _node;
DatagramSequencer _sequencer;
MetavoxelData _data;
QList<SendRecord> _sendRecords;
QList<ReceiveRecord> _receiveRecords;
}; };
/// Base class for spanner renderers; provides clipping. /// Base class for spanner renderers; provides clipping.

View file

@ -29,6 +29,7 @@
#include <QVBoxLayout> #include <QVBoxLayout>
#include <AttributeRegistry.h> #include <AttributeRegistry.h>
#include <MetavoxelMessages.h>
#include "Application.h" #include "Application.h"
#include "MetavoxelEditor.h" #include "MetavoxelEditor.h"

View file

@ -13,7 +13,7 @@
#include "Endpoint.h" #include "Endpoint.h"
Endpoint::Endpoint(const SharedNodePointer& node) : Endpoint::Endpoint(const SharedNodePointer& node, PacketRecord* baselineSendRecord, PacketRecord* baselineReceiveRecord) :
_node(node), _node(node),
_sequencer(byteArrayWithPopulatedHeader(PacketTypeMetavoxelData)) { _sequencer(byteArrayWithPopulatedHeader(PacketTypeMetavoxelData)) {
@ -23,8 +23,8 @@ Endpoint::Endpoint(const SharedNodePointer& node) :
connect(&_sequencer, SIGNAL(receiveAcknowledged(int)), SLOT(clearReceiveRecordsBefore(int))); connect(&_sequencer, SIGNAL(receiveAcknowledged(int)), SLOT(clearReceiveRecordsBefore(int)));
// insert the baseline send and receive records // insert the baseline send and receive records
_sendRecords.append(maybeCreateSendRecord(true)); _sendRecords.append(baselineSendRecord);
_receiveRecords.append(maybeCreateReceiveRecord(true)); _receiveRecords.append(baselineReceiveRecord);
} }
Endpoint::~Endpoint() { Endpoint::~Endpoint() {
@ -38,7 +38,7 @@ Endpoint::~Endpoint() {
void Endpoint::update() { void Endpoint::update() {
Bitstream& out = _sequencer.startPacket(); Bitstream& out = _sequencer.startPacket();
out << QVariant(); writeUpdateMessage(out);
_sequencer.endPacket(); _sequencer.endPacket();
// record the send // record the send
@ -92,16 +92,17 @@ void Endpoint::handleMessage(const QVariant& message, Bitstream& in) {
} }
} }
PacketRecord* Endpoint::maybeCreateSendRecord(bool baseline) const { PacketRecord* Endpoint::maybeCreateSendRecord() const {
return NULL; return NULL;
} }
PacketRecord* Endpoint::maybeCreateReceiveRecord(bool baseline) const { PacketRecord* Endpoint::maybeCreateReceiveRecord() const {
return NULL; return NULL;
} }
PacketRecord::PacketRecord(const MetavoxelLOD& lod) : PacketRecord::PacketRecord(const MetavoxelLOD& lod, const MetavoxelData& data) :
_lod(lod) { _lod(lod),
_data(data) {
} }
PacketRecord::~PacketRecord() { PacketRecord::~PacketRecord() {

View file

@ -19,16 +19,17 @@
class PacketRecord; class PacketRecord;
/// Base class for communication endpoints: clients or servers. /// Base class for communication endpoints: clients and server sessions.
class Endpoint : public NodeData { class Endpoint : public NodeData {
Q_OBJECT Q_OBJECT
public: public:
Endpoint(const SharedNodePointer& node); Endpoint(const SharedNodePointer& node, PacketRecord* baselineSendRecord = NULL,
PacketRecord* baselineReceiveRecord = NULL);
virtual ~Endpoint(); virtual ~Endpoint();
void update(); virtual void update();
virtual int parseData(const QByteArray& packet); virtual int parseData(const QByteArray& packet);
@ -45,8 +46,8 @@ protected:
virtual void writeUpdateMessage(Bitstream& out); virtual void writeUpdateMessage(Bitstream& out);
virtual void handleMessage(const QVariant& message, Bitstream& in); virtual void handleMessage(const QVariant& message, Bitstream& in);
virtual PacketRecord* maybeCreateSendRecord(bool baseline = false) const; virtual PacketRecord* maybeCreateSendRecord() const;
virtual PacketRecord* maybeCreateReceiveRecord(bool baseline = false) const; virtual PacketRecord* maybeCreateReceiveRecord() const;
PacketRecord* getLastAcknowledgedSendRecord() const { return _sendRecords.first(); } PacketRecord* getLastAcknowledgedSendRecord() const { return _sendRecords.first(); }
PacketRecord* getLastAcknowledgedReceiveRecord() const { return _receiveRecords.first(); } PacketRecord* getLastAcknowledgedReceiveRecord() const { return _receiveRecords.first(); }
@ -62,14 +63,16 @@ protected:
class PacketRecord { class PacketRecord {
public: public:
PacketRecord(const MetavoxelLOD& lod = MetavoxelLOD()); PacketRecord(const MetavoxelLOD& lod = MetavoxelLOD(), const MetavoxelData& data = MetavoxelData());
virtual ~PacketRecord(); virtual ~PacketRecord();
const MetavoxelLOD& getLOD() const { return _lod; } const MetavoxelLOD& getLOD() const { return _lod; }
const MetavoxelData& getData() const { return _data; }
private: private:
MetavoxelLOD _lod; MetavoxelLOD _lod;
MetavoxelData _data;
}; };
#endif // hifi_Endpoint_h #endif // hifi_Endpoint_h

View file

@ -22,7 +22,7 @@ void MetavoxelClientManager::update() {
QMutexLocker locker(&node->getMutex()); QMutexLocker locker(&node->getMutex());
MetavoxelClient* client = static_cast<MetavoxelClient*>(node->getLinkedData()); MetavoxelClient* client = static_cast<MetavoxelClient*>(node->getLinkedData());
if (client) { if (client) {
client->update(); updateClient(client);
} }
} }
} }
@ -72,12 +72,20 @@ MetavoxelLOD MetavoxelClientManager::getLOD() const {
void MetavoxelClientManager::maybeAttachClient(const SharedNodePointer& node) { void MetavoxelClientManager::maybeAttachClient(const SharedNodePointer& node) {
if (node->getType() == NodeType::MetavoxelServer) { if (node->getType() == NodeType::MetavoxelServer) {
QMutexLocker locker(&node->getMutex()); QMutexLocker locker(&node->getMutex());
node->setLinkedData(new MetavoxelClient(node, this)); node->setLinkedData(createClient(node));
} }
} }
MetavoxelClient* MetavoxelClientManager::createClient(const SharedNodePointer& node) {
return new MetavoxelClient(node, this);
}
void MetavoxelClientManager::updateClient(MetavoxelClient* client) {
client->update();
}
MetavoxelClient::MetavoxelClient(const SharedNodePointer& node, MetavoxelClientManager* manager) : MetavoxelClient::MetavoxelClient(const SharedNodePointer& node, MetavoxelClientManager* manager) :
Endpoint(node), Endpoint(node, new PacketRecord(), new PacketRecord()),
_manager(manager) { _manager(manager) {
} }
@ -115,26 +123,9 @@ void MetavoxelClient::readMessage(Bitstream& in) {
} }
} }
class ReceiveRecord : public PacketRecord {
public:
ReceiveRecord(const MetavoxelLOD& lod = MetavoxelLOD(), const MetavoxelData& data = MetavoxelData());
const MetavoxelData& getData() const { return _data; }
private:
MetavoxelData _data;
};
ReceiveRecord::ReceiveRecord(const MetavoxelLOD& lod, const MetavoxelData& data) :
PacketRecord(lod),
_data(data) {
}
void MetavoxelClient::handleMessage(const QVariant& message, Bitstream& in) { void MetavoxelClient::handleMessage(const QVariant& message, Bitstream& in) {
if (message.userType() == MetavoxelDeltaMessage::Type) { if (message.userType() == MetavoxelDeltaMessage::Type) {
ReceiveRecord* receiveRecord = static_cast<ReceiveRecord*>(getLastAcknowledgedReceiveRecord()); PacketRecord* receiveRecord = getLastAcknowledgedReceiveRecord();
_data.readDelta(receiveRecord->getData(), receiveRecord->getLOD(), in, getLastAcknowledgedSendRecord()->getLOD()); _data.readDelta(receiveRecord->getData(), receiveRecord->getLOD(), in, getLastAcknowledgedSendRecord()->getLOD());
} else { } else {
@ -142,10 +133,10 @@ void MetavoxelClient::handleMessage(const QVariant& message, Bitstream& in) {
} }
} }
PacketRecord* MetavoxelClient::maybeCreateSendRecord(bool baseline) const { PacketRecord* MetavoxelClient::maybeCreateSendRecord() const {
return baseline ? new PacketRecord() : new PacketRecord(_manager->getLOD()); return new PacketRecord(_manager->getLOD());
} }
PacketRecord* MetavoxelClient::maybeCreateReceiveRecord(bool baseline) const { PacketRecord* MetavoxelClient::maybeCreateReceiveRecord() const {
return baseline ? new ReceiveRecord() : new ReceiveRecord(getLastAcknowledgedSendRecord()->getLOD(), _data); return new PacketRecord(getLastAcknowledgedSendRecord()->getLOD(), _data);
} }

View file

@ -14,6 +14,7 @@
#include "Endpoint.h" #include "Endpoint.h"
class MetavoxelClient;
class MetavoxelEditMessage; class MetavoxelEditMessage;
/// Manages the set of connected metavoxel clients. /// Manages the set of connected metavoxel clients.
@ -23,7 +24,7 @@ class MetavoxelClientManager : public QObject {
public: public:
virtual void init(); virtual void init();
virtual void update(); void update();
SharedObjectPointer findFirstRaySpannerIntersection(const glm::vec3& origin, const glm::vec3& direction, SharedObjectPointer findFirstRaySpannerIntersection(const glm::vec3& origin, const glm::vec3& direction,
const AttributePointer& attribute, float& distance); const AttributePointer& attribute, float& distance);
@ -35,6 +36,11 @@ public:
private slots: private slots:
void maybeAttachClient(const SharedNodePointer& node); void maybeAttachClient(const SharedNodePointer& node);
protected:
virtual MetavoxelClient* createClient(const SharedNodePointer& node);
virtual void updateClient(MetavoxelClient* client);
}; };
/// Base class for metavoxel clients. /// Base class for metavoxel clients.
@ -57,8 +63,8 @@ protected:
virtual void readMessage(Bitstream& in); virtual void readMessage(Bitstream& in);
virtual void handleMessage(const QVariant& message, Bitstream& in); virtual void handleMessage(const QVariant& message, Bitstream& in);
virtual PacketRecord* maybeCreateSendRecord(bool baseline) const; virtual PacketRecord* maybeCreateSendRecord() const;
virtual PacketRecord* maybeCreateReceiveRecord(bool baseline) const; virtual PacketRecord* maybeCreateReceiveRecord() const;
private: private: