mirror of
https://thingvellir.net/git/overte
synced 2025-03-27 23:52:03 +01:00
138 lines
5.1 KiB
C++
138 lines
5.1 KiB
C++
//
|
|
// ModelServer.cpp
|
|
// assignment-client/src/models
|
|
//
|
|
// Created by Brad Hefta-Gaub on 4/29/14
|
|
// Copyright 2014 High Fidelity, Inc.
|
|
//
|
|
// Distributed under the Apache License, Version 2.0.
|
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
|
//
|
|
|
|
#include <QTimer>
|
|
#include <ModelTree.h>
|
|
|
|
#include "ModelServer.h"
|
|
#include "ModelServerConsts.h"
|
|
#include "ModelNodeData.h"
|
|
|
|
const char* MODEL_SERVER_NAME = "Model";
|
|
const char* MODEL_SERVER_LOGGING_TARGET_NAME = "model-server";
|
|
const char* LOCAL_MODELS_PERSIST_FILE = "resources/models.svo";
|
|
|
|
ModelServer::ModelServer(const QByteArray& packet) : OctreeServer(packet) {
|
|
// nothing special to do here...
|
|
}
|
|
|
|
ModelServer::~ModelServer() {
|
|
ModelTree* tree = (ModelTree*)_tree;
|
|
tree->removeNewlyCreatedHook(this);
|
|
}
|
|
|
|
OctreeQueryNode* ModelServer::createOctreeQueryNode() {
|
|
return new ModelNodeData();
|
|
}
|
|
|
|
Octree* ModelServer::createTree() {
|
|
ModelTree* tree = new ModelTree(true);
|
|
tree->addNewlyCreatedHook(this);
|
|
return tree;
|
|
}
|
|
|
|
void ModelServer::beforeRun() {
|
|
QTimer* pruneDeletedModelsTimer = new QTimer(this);
|
|
connect(pruneDeletedModelsTimer, SIGNAL(timeout()), this, SLOT(pruneDeletedModels()));
|
|
const int PRUNE_DELETED_MODELS_INTERVAL_MSECS = 1 * 1000; // once every second
|
|
pruneDeletedModelsTimer->start(PRUNE_DELETED_MODELS_INTERVAL_MSECS);
|
|
}
|
|
|
|
void ModelServer::modelCreated(const ModelItem& newModel, const SharedNodePointer& senderNode) {
|
|
unsigned char outputBuffer[MAX_PACKET_SIZE];
|
|
unsigned char* copyAt = outputBuffer;
|
|
|
|
int numBytesPacketHeader = populatePacketHeader(reinterpret_cast<char*>(outputBuffer), PacketTypeModelAddResponse);
|
|
int packetLength = numBytesPacketHeader;
|
|
copyAt += numBytesPacketHeader;
|
|
|
|
// encode the creatorTokenID
|
|
uint32_t creatorTokenID = newModel.getCreatorTokenID();
|
|
memcpy(copyAt, &creatorTokenID, sizeof(creatorTokenID));
|
|
copyAt += sizeof(creatorTokenID);
|
|
packetLength += sizeof(creatorTokenID);
|
|
|
|
// encode the model ID
|
|
uint32_t modelID = newModel.getID();
|
|
memcpy(copyAt, &modelID, sizeof(modelID));
|
|
copyAt += sizeof(modelID);
|
|
packetLength += sizeof(modelID);
|
|
|
|
NodeList::getInstance()->writeDatagram((char*) outputBuffer, packetLength, senderNode);
|
|
}
|
|
|
|
|
|
// ModelServer will use the "special packets" to send list of recently deleted models
|
|
bool ModelServer::hasSpecialPacketToSend(const SharedNodePointer& node) {
|
|
bool shouldSendDeletedModels = false;
|
|
|
|
// check to see if any new models have been added since we last sent to this node...
|
|
ModelNodeData* nodeData = static_cast<ModelNodeData*>(node->getLinkedData());
|
|
if (nodeData) {
|
|
quint64 deletedModelsSentAt = nodeData->getLastDeletedModelsSentAt();
|
|
|
|
ModelTree* tree = static_cast<ModelTree*>(_tree);
|
|
shouldSendDeletedModels = tree->hasModelsDeletedSince(deletedModelsSentAt);
|
|
}
|
|
|
|
return shouldSendDeletedModels;
|
|
}
|
|
|
|
int ModelServer::sendSpecialPacket(OctreeQueryNode* queryNode, const SharedNodePointer& node) {
|
|
unsigned char outputBuffer[MAX_PACKET_SIZE];
|
|
size_t packetLength = 0;
|
|
|
|
ModelNodeData* nodeData = static_cast<ModelNodeData*>(node->getLinkedData());
|
|
if (nodeData) {
|
|
quint64 deletedModelsSentAt = nodeData->getLastDeletedModelsSentAt();
|
|
quint64 deletePacketSentAt = usecTimestampNow();
|
|
|
|
ModelTree* tree = static_cast<ModelTree*>(_tree);
|
|
bool hasMoreToSend = true;
|
|
|
|
// TODO: is it possible to send too many of these packets? what if you deleted 1,000,000 models?
|
|
while (hasMoreToSend) {
|
|
hasMoreToSend = tree->encodeModelsDeletedSince(queryNode->getSequenceNumber(), deletedModelsSentAt,
|
|
outputBuffer, MAX_PACKET_SIZE, packetLength);
|
|
|
|
//qDebug() << "sending PacketType_MODEL_ERASE packetLength:" << packetLength;
|
|
|
|
NodeList::getInstance()->writeDatagram((char*) outputBuffer, packetLength, SharedNodePointer(node));
|
|
queryNode->incrementSequenceNumber();
|
|
}
|
|
|
|
nodeData->setLastDeletedModelsSentAt(deletePacketSentAt);
|
|
}
|
|
|
|
// TODO: caller is expecting a packetLength, what if we send more than one packet??
|
|
return packetLength;
|
|
}
|
|
|
|
void ModelServer::pruneDeletedModels() {
|
|
ModelTree* tree = static_cast<ModelTree*>(_tree);
|
|
if (tree->hasAnyDeletedModels()) {
|
|
|
|
//qDebug() << "there are some deleted models to consider...";
|
|
quint64 earliestLastDeletedModelsSent = usecTimestampNow() + 1; // in the future
|
|
foreach (const SharedNodePointer& otherNode, NodeList::getInstance()->getNodeHash()) {
|
|
if (otherNode->getLinkedData()) {
|
|
ModelNodeData* nodeData = static_cast<ModelNodeData*>(otherNode->getLinkedData());
|
|
quint64 nodeLastDeletedModelsSentAt = nodeData->getLastDeletedModelsSentAt();
|
|
if (nodeLastDeletedModelsSentAt < earliestLastDeletedModelsSent) {
|
|
earliestLastDeletedModelsSent = nodeLastDeletedModelsSentAt;
|
|
}
|
|
}
|
|
}
|
|
//qDebug() << "earliestLastDeletedModelsSent=" << earliestLastDeletedModelsSent;
|
|
tree->forgetModelsDeletedBefore(earliestLastDeletedModelsSent);
|
|
}
|
|
}
|
|
|