mirror of
https://github.com/overte-org/overte.git
synced 2025-04-07 21:33:48 +02:00
Remove legacy jurisdiction code
This commit is contained in:
parent
4bbce011a4
commit
28f164d7e5
31 changed files with 113 additions and 1519 deletions
|
@ -94,7 +94,6 @@ Agent::Agent(ReceivedMessage& message) :
|
|||
packetReceiver.registerListenerForTypes(
|
||||
{ PacketType::OctreeStats, PacketType::EntityData, PacketType::EntityErase },
|
||||
this, "handleOctreePacket");
|
||||
packetReceiver.registerListener(PacketType::Jurisdiction, this, "handleJurisdictionPacket");
|
||||
packetReceiver.registerListener(PacketType::SelectedAudioFormat, this, "handleSelectedAudioFormat");
|
||||
|
||||
|
||||
|
@ -149,17 +148,6 @@ void Agent::handleOctreePacket(QSharedPointer<ReceivedMessage> message, SharedNo
|
|||
}
|
||||
}
|
||||
|
||||
void Agent::handleJurisdictionPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer senderNode) {
|
||||
NodeType_t nodeType;
|
||||
message->peekPrimitive(&nodeType);
|
||||
|
||||
// PacketType_JURISDICTION, first byte is the node type...
|
||||
if (nodeType == NodeType::EntityServer) {
|
||||
DependencyManager::get<EntityScriptingInterface>()->getJurisdictionListener()->
|
||||
queueReceivedPacket(message, senderNode);
|
||||
}
|
||||
}
|
||||
|
||||
void Agent::handleAudioPacket(QSharedPointer<ReceivedMessage> message) {
|
||||
_receivedAudioStream.parseData(*message);
|
||||
_lastReceivedAudioLoudness = _receivedAudioStream.getNextOutputFrameLoudness();
|
||||
|
@ -483,10 +471,7 @@ void Agent::executeScript() {
|
|||
auto recordingInterface = DependencyManager::get<RecordingScriptingInterface>();
|
||||
_scriptEngine->registerGlobalObject("Recording", recordingInterface.data());
|
||||
|
||||
// we need to make sure that init has been called for our EntityScriptingInterface
|
||||
// so that it actually has a jurisdiction listener when we ask it for it next
|
||||
entityScriptingInterface->init();
|
||||
_entityViewer.setJurisdictionListener(entityScriptingInterface->getJurisdictionListener());
|
||||
|
||||
_entityViewer.init();
|
||||
|
||||
|
|
|
@ -73,7 +73,6 @@ private slots:
|
|||
|
||||
void handleAudioPacket(QSharedPointer<ReceivedMessage> message);
|
||||
void handleOctreePacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer senderNode);
|
||||
void handleJurisdictionPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer senderNode);
|
||||
void handleSelectedAudioFormat(QSharedPointer<ReceivedMessage> message);
|
||||
|
||||
void nodeActivated(SharedNodePointer activatedNode);
|
||||
|
|
|
@ -23,23 +23,6 @@ void OctreeHeadlessViewer::queryOctree() {
|
|||
char serverType = getMyNodeType();
|
||||
PacketType packetType = getMyQueryMessageType();
|
||||
|
||||
NodeToJurisdictionMap& jurisdictions = *_jurisdictionListener->getJurisdictions();
|
||||
|
||||
bool wantExtraDebugging = false;
|
||||
|
||||
if (wantExtraDebugging) {
|
||||
qCDebug(octree) << "OctreeHeadlessViewer::queryOctree() _jurisdictionListener=" << _jurisdictionListener;
|
||||
qCDebug(octree) << "---------------";
|
||||
qCDebug(octree) << "_jurisdictionListener=" << _jurisdictionListener;
|
||||
qCDebug(octree) << "Jurisdictions...";
|
||||
jurisdictions.withReadLock([&] {
|
||||
for (NodeToJurisdictionMapIterator i = jurisdictions.begin(); i != jurisdictions.end(); ++i) {
|
||||
qCDebug(octree) << i.key() << ": " << &i.value();
|
||||
}
|
||||
});
|
||||
qCDebug(octree) << "---------------";
|
||||
}
|
||||
|
||||
_octreeQuery.setCameraPosition(_viewFrustum.getPosition());
|
||||
_octreeQuery.setCameraOrientation(_viewFrustum.getOrientation());
|
||||
_octreeQuery.setCameraFov(_viewFrustum.getFieldOfView());
|
||||
|
@ -51,159 +34,22 @@ void OctreeHeadlessViewer::queryOctree() {
|
|||
_octreeQuery.setOctreeSizeScale(_voxelSizeScale);
|
||||
_octreeQuery.setBoundaryLevelAdjust(_boundaryLevelAdjust);
|
||||
|
||||
// Iterate all of the nodes, and get a count of how many voxel servers we have...
|
||||
int totalServers = 0;
|
||||
int inViewServers = 0;
|
||||
int unknownJurisdictionServers = 0;
|
||||
|
||||
DependencyManager::get<NodeList>()->eachNode([&](const SharedNodePointer& node){
|
||||
// only send to the NodeTypes that are serverType
|
||||
if (node->getActiveSocket() && node->getType() == serverType) {
|
||||
totalServers++;
|
||||
|
||||
// get the server bounds for this server
|
||||
QUuid nodeUUID = node->getUUID();
|
||||
|
||||
// if we haven't heard from this voxel server, go ahead and send it a query, so we
|
||||
// can get the jurisdiction...
|
||||
VoxelPositionSize rootDetails;
|
||||
bool foundRootDetails = false;
|
||||
jurisdictions.withReadLock([&] {
|
||||
if (jurisdictions.find(nodeUUID) == jurisdictions.end()) {
|
||||
unknownJurisdictionServers++;
|
||||
return;
|
||||
}
|
||||
const JurisdictionMap& map = (jurisdictions)[nodeUUID];
|
||||
|
||||
auto rootCode = map.getRootOctalCode();
|
||||
if (!rootCode) {
|
||||
return;
|
||||
}
|
||||
|
||||
voxelDetailsForCode(rootCode.get(), rootDetails);
|
||||
foundRootDetails = true;
|
||||
});
|
||||
|
||||
if (foundRootDetails) {
|
||||
AACube serverBounds(glm::vec3(rootDetails.x, rootDetails.y, rootDetails.z), rootDetails.s);
|
||||
if ((bool)(_viewFrustum.calculateCubeKeyholeIntersection(serverBounds))) {
|
||||
inViewServers++;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (wantExtraDebugging) {
|
||||
qCDebug(octree, "Servers: total %d, in view %d, unknown jurisdiction %d",
|
||||
totalServers, inViewServers, unknownJurisdictionServers);
|
||||
}
|
||||
|
||||
int perServerPPS = 0;
|
||||
const int SMALL_BUDGET = 10;
|
||||
int perUnknownServer = SMALL_BUDGET;
|
||||
int totalPPS = getMaxPacketsPerSecond();
|
||||
|
||||
// determine PPS based on number of servers
|
||||
if (inViewServers >= 1) {
|
||||
// set our preferred PPS to be exactly evenly divided among all of the voxel servers... and allocate 1 PPS
|
||||
// for each unknown jurisdiction server
|
||||
perServerPPS = (totalPPS / inViewServers) - (unknownJurisdictionServers * perUnknownServer);
|
||||
} else {
|
||||
if (unknownJurisdictionServers > 0) {
|
||||
perUnknownServer = (totalPPS / unknownJurisdictionServers);
|
||||
}
|
||||
}
|
||||
|
||||
if (wantExtraDebugging) {
|
||||
qCDebug(octree, "perServerPPS: %d perUnknownServer: %d", perServerPPS, perUnknownServer);
|
||||
}
|
||||
|
||||
auto nodeList = DependencyManager::get<NodeList>();
|
||||
nodeList->eachNode([&](const SharedNodePointer& node){
|
||||
// only send to the NodeTypes that are serverType
|
||||
if (node->getActiveSocket() && node->getType() == serverType) {
|
||||
|
||||
// get the server bounds for this server
|
||||
QUuid nodeUUID = node->getUUID();
|
||||
auto node = nodeList->soloNodeOfType(serverType);
|
||||
if (node && node->getActiveSocket()) {
|
||||
_octreeQuery.setMaxQueryPacketsPerSecond(getMaxPacketsPerSecond());
|
||||
|
||||
bool inView = false;
|
||||
bool unknownView = false;
|
||||
auto queryPacket = NLPacket::create(packetType);
|
||||
|
||||
// if we haven't heard from this voxel server, go ahead and send it a query, so we
|
||||
// can get the jurisdiction...
|
||||
VoxelPositionSize rootDetails;
|
||||
bool foundRootDetails = false;
|
||||
jurisdictions.withReadLock([&] {
|
||||
if (jurisdictions.find(nodeUUID) == jurisdictions.end()) {
|
||||
unknownView = true; // assume it's in view
|
||||
if (wantExtraDebugging) {
|
||||
qCDebug(octree) << "no known jurisdiction for node " << *node << ", assume it's visible.";
|
||||
}
|
||||
return;
|
||||
}
|
||||
// encode the query data
|
||||
auto packetData = reinterpret_cast<unsigned char*>(queryPacket->getPayload());
|
||||
int packetSize = _octreeQuery.getBroadcastData(packetData);
|
||||
queryPacket->setPayloadSize(packetSize);
|
||||
|
||||
const JurisdictionMap& map = (jurisdictions)[nodeUUID];
|
||||
auto rootCode = map.getRootOctalCode();
|
||||
|
||||
if (!rootCode) {
|
||||
if (wantExtraDebugging) {
|
||||
qCDebug(octree) << "Jurisdiction without RootCode for node " << *node << ". That's unusual!";
|
||||
}
|
||||
return;
|
||||
}
|
||||
voxelDetailsForCode(rootCode.get(), rootDetails);
|
||||
foundRootDetails = true;
|
||||
});
|
||||
|
||||
if (foundRootDetails) {
|
||||
AACube serverBounds(glm::vec3(rootDetails.x, rootDetails.y, rootDetails.z), rootDetails.s);
|
||||
inView = (bool)(_viewFrustum.calculateCubeKeyholeIntersection(serverBounds));
|
||||
}
|
||||
|
||||
if (inView) {
|
||||
_octreeQuery.setMaxQueryPacketsPerSecond(perServerPPS);
|
||||
if (wantExtraDebugging) {
|
||||
qCDebug(octree) << "inView for node " << *node << ", give it budget of " << perServerPPS;
|
||||
}
|
||||
} else if (unknownView) {
|
||||
if (wantExtraDebugging) {
|
||||
qCDebug(octree) << "no known jurisdiction for node " << *node << ", give it budget of "
|
||||
<< perUnknownServer << " to send us jurisdiction.";
|
||||
}
|
||||
|
||||
// set the query's position/orientation to be degenerate in a manner that will get the scene quickly
|
||||
// If there's only one server, then don't do this, and just let the normal voxel query pass through
|
||||
// as expected... this way, we will actually get a valid scene if there is one to be seen
|
||||
if (totalServers > 1) {
|
||||
_octreeQuery.setCameraPosition(glm::vec3(-0.1,-0.1,-0.1));
|
||||
const glm::quat OFF_IN_NEGATIVE_SPACE = glm::quat(-0.5, 0, -0.5, 1.0);
|
||||
_octreeQuery.setCameraOrientation(OFF_IN_NEGATIVE_SPACE);
|
||||
_octreeQuery.setCameraNearClip(0.1f);
|
||||
_octreeQuery.setCameraFarClip(0.1f);
|
||||
if (wantExtraDebugging) {
|
||||
qCDebug(octree) << "Using 'minimal' camera position for node" << *node;
|
||||
}
|
||||
} else {
|
||||
if (wantExtraDebugging) {
|
||||
qCDebug(octree) << "Using regular camera position for node" << *node;
|
||||
}
|
||||
}
|
||||
_octreeQuery.setMaxQueryPacketsPerSecond(perUnknownServer);
|
||||
} else {
|
||||
_octreeQuery.setMaxQueryPacketsPerSecond(0);
|
||||
}
|
||||
|
||||
// setup the query packet
|
||||
auto queryPacket = NLPacket::create(packetType);
|
||||
|
||||
// read the data to our packet and set the payload size to fit the query
|
||||
int querySize = _octreeQuery.getBroadcastData(reinterpret_cast<unsigned char*>(queryPacket->getPayload()));
|
||||
queryPacket->setPayloadSize(querySize);
|
||||
|
||||
// ask the NodeList to send it
|
||||
nodeList->sendPacket(std::move(queryPacket), *node);
|
||||
}
|
||||
});
|
||||
// make sure we still have an active socket
|
||||
nodeList->sendUnreliablePacket(*queryPacket, *node);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
#define hifi_OctreeHeadlessViewer_h
|
||||
|
||||
#include <OctreeProcessor.h>
|
||||
#include <JurisdictionListener.h>
|
||||
#include <OctreeQuery.h>
|
||||
|
||||
|
||||
|
@ -23,8 +22,6 @@ class OctreeHeadlessViewer : public OctreeProcessor {
|
|||
public:
|
||||
OctreeHeadlessViewer();
|
||||
virtual ~OctreeHeadlessViewer() {};
|
||||
|
||||
void setJurisdictionListener(JurisdictionListener* jurisdictionListener) { _jurisdictionListener = jurisdictionListener; }
|
||||
|
||||
OctreeQuery& getOctreeQuery() { return _octreeQuery; }
|
||||
|
||||
|
@ -57,7 +54,6 @@ public slots:
|
|||
unsigned getOctreeElementsCount() const { return _tree->getOctreeElementsCount(); }
|
||||
|
||||
private:
|
||||
JurisdictionListener* _jurisdictionListener = nullptr;
|
||||
OctreeQuery _octreeQuery;
|
||||
|
||||
ViewFrustum _viewFrustum;
|
||||
|
|
|
@ -391,8 +391,7 @@ int OctreeSendThread::packetDistributor(SharedNodePointer node, OctreeQueryNode*
|
|||
|
||||
nodeData->sceneStart(usecTimestampNow() - CHANGE_FUDGE);
|
||||
// start tracking our stats
|
||||
nodeData->stats.sceneStarted(isFullScene, viewFrustumChanged,
|
||||
_myServer->getOctree()->getRoot(), _myServer->getJurisdiction());
|
||||
nodeData->stats.sceneStarted(isFullScene, viewFrustumChanged, _myServer->getOctree()->getRoot());
|
||||
|
||||
preStartNewScene(nodeData, isFullScene);
|
||||
}
|
||||
|
@ -507,7 +506,7 @@ void OctreeSendThread::traverseTreeAndSendContents(SharedNodePointer node, Octre
|
|||
float octreeSizeScale = nodeData->getOctreeSizeScale();
|
||||
EncodeBitstreamParams params(INT_MAX, WANT_EXISTS_BITS, DONT_CHOP,
|
||||
viewFrustumChanged, boundaryLevelAdjust, octreeSizeScale,
|
||||
isFullScene, _myServer->getJurisdiction(), nodeData);
|
||||
isFullScene, nodeData);
|
||||
// Our trackSend() function is implemented by the server subclass, and will be called back as new entities/data elements are sent
|
||||
params.trackSend = [this](const QUuid& dataID, quint64 dataEdited) {
|
||||
_myServer->trackSend(dataID, dataEdited, _nodeUuid);
|
||||
|
|
|
@ -237,8 +237,6 @@ OctreeServer::OctreeServer(ReceivedMessage& message) :
|
|||
_debugSending(false),
|
||||
_debugReceiving(false),
|
||||
_verboseDebug(false),
|
||||
_jurisdiction(NULL),
|
||||
_jurisdictionSender(NULL),
|
||||
_octreeInboundPacketProcessor(NULL),
|
||||
_persistThread(NULL),
|
||||
_started(time(0)),
|
||||
|
@ -257,12 +255,6 @@ OctreeServer::~OctreeServer() {
|
|||
delete[] _parsedArgV;
|
||||
}
|
||||
|
||||
if (_jurisdictionSender) {
|
||||
_jurisdictionSender->terminating();
|
||||
_jurisdictionSender->terminate();
|
||||
_jurisdictionSender->deleteLater();
|
||||
}
|
||||
|
||||
if (_octreeInboundPacketProcessor) {
|
||||
_octreeInboundPacketProcessor->terminating();
|
||||
_octreeInboundPacketProcessor->terminate();
|
||||
|
@ -275,9 +267,6 @@ OctreeServer::~OctreeServer() {
|
|||
_persistThread->deleteLater();
|
||||
}
|
||||
|
||||
delete _jurisdiction;
|
||||
_jurisdiction = NULL;
|
||||
|
||||
// cleanup our tree here...
|
||||
qDebug() << qPrintable(_safeServerName) << "server START cleaning up octree... [" << this << "]";
|
||||
_tree.reset();
|
||||
|
@ -933,10 +922,6 @@ void OctreeServer::handleOctreeDataNackPacket(QSharedPointer<ReceivedMessage> me
|
|||
}
|
||||
}
|
||||
|
||||
void OctreeServer::handleJurisdictionRequestPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer senderNode) {
|
||||
_jurisdictionSender->queueReceivedPacket(message, senderNode);
|
||||
}
|
||||
|
||||
void OctreeServer::handleOctreeFileReplacement(QSharedPointer<ReceivedMessage> message) {
|
||||
if (!_isFinished && !_isShuttingDown) {
|
||||
// these messages are only allowed to come from the domain server, so make sure that is the case
|
||||
|
@ -1111,23 +1096,6 @@ void OctreeServer::readConfiguration() {
|
|||
qDebug() << "statusPort= DISABLED";
|
||||
}
|
||||
|
||||
QString jurisdictionFile;
|
||||
if (readOptionString(QString("jurisdictionFile"), settingsSectionObject, jurisdictionFile)) {
|
||||
qDebug("jurisdictionFile=%s", qPrintable(jurisdictionFile));
|
||||
qDebug("about to readFromFile().... jurisdictionFile=%s", qPrintable(jurisdictionFile));
|
||||
_jurisdiction = new JurisdictionMap(qPrintable(jurisdictionFile));
|
||||
qDebug("after readFromFile().... jurisdictionFile=%s", qPrintable(jurisdictionFile));
|
||||
} else {
|
||||
QString jurisdictionRoot;
|
||||
bool hasRoot = readOptionString(QString("jurisdictionRoot"), settingsSectionObject, jurisdictionRoot);
|
||||
QString jurisdictionEndNodes;
|
||||
bool hasEndNodes = readOptionString(QString("jurisdictionEndNodes"), settingsSectionObject, jurisdictionEndNodes);
|
||||
|
||||
if (hasRoot || hasEndNodes) {
|
||||
_jurisdiction = new JurisdictionMap(qPrintable(jurisdictionRoot), qPrintable(jurisdictionEndNodes));
|
||||
}
|
||||
}
|
||||
|
||||
readOptionBool(QString("verboseDebug"), settingsSectionObject, _verboseDebug);
|
||||
qDebug("verboseDebug=%s", debug::valueOf(_verboseDebug));
|
||||
|
||||
|
@ -1241,7 +1209,6 @@ void OctreeServer::domainSettingsRequestComplete() {
|
|||
auto& packetReceiver = DependencyManager::get<NodeList>()->getPacketReceiver();
|
||||
packetReceiver.registerListener(getMyQueryMessageType(), this, "handleOctreeQueryPacket");
|
||||
packetReceiver.registerListener(PacketType::OctreeDataNack, this, "handleOctreeDataNackPacket");
|
||||
packetReceiver.registerListener(PacketType::JurisdictionRequest, this, "handleJurisdictionRequestPacket");
|
||||
packetReceiver.registerListener(PacketType::OctreeFileReplacement, this, "handleOctreeFileReplacement");
|
||||
packetReceiver.registerListener(PacketType::OctreeFileReplacementFromUrl, this, "handleOctreeFileReplacementFromURL");
|
||||
|
||||
|
@ -1365,13 +1332,6 @@ void OctreeServer::domainSettingsRequestComplete() {
|
|||
_persistThread->initialize(true);
|
||||
}
|
||||
|
||||
// set up our jurisdiction broadcaster...
|
||||
if (_jurisdiction) {
|
||||
_jurisdiction->setNodeType(getMyNodeType());
|
||||
}
|
||||
_jurisdictionSender = new JurisdictionSender(_jurisdiction, getMyNodeType());
|
||||
_jurisdictionSender->initialize(true);
|
||||
|
||||
// set up our OctreeServerPacketProcessor
|
||||
_octreeInboundPacketProcessor = new OctreeInboundPacketProcessor(this);
|
||||
_octreeInboundPacketProcessor->initialize(true);
|
||||
|
@ -1441,10 +1401,6 @@ void OctreeServer::aboutToFinish() {
|
|||
_octreeInboundPacketProcessor->terminating();
|
||||
}
|
||||
|
||||
if (_jurisdictionSender) {
|
||||
_jurisdictionSender->terminating();
|
||||
}
|
||||
|
||||
// Shut down all the send threads
|
||||
for (auto& it : _sendThreads) {
|
||||
auto& sendThread = *it.second;
|
||||
|
|
|
@ -44,7 +44,6 @@ public:
|
|||
bool wantsVerboseDebug() const { return _verboseDebug; }
|
||||
|
||||
OctreePointer getOctree() { return _tree; }
|
||||
JurisdictionMap* getJurisdiction() { return _jurisdiction; }
|
||||
|
||||
int getPacketsPerClientPerInterval() const { return std::min(_packetsPerClientPerInterval,
|
||||
std::max(1, getPacketsTotalPerInterval() / std::max(1, getCurrentClientCount()))); }
|
||||
|
@ -138,7 +137,6 @@ private slots:
|
|||
void domainSettingsRequestComplete();
|
||||
void handleOctreeQueryPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer senderNode);
|
||||
void handleOctreeDataNackPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer senderNode);
|
||||
void handleJurisdictionRequestPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer senderNode);
|
||||
void handleOctreeFileReplacement(QSharedPointer<ReceivedMessage> message);
|
||||
void handleOctreeFileReplacementFromURL(QSharedPointer<ReceivedMessage> message);
|
||||
void removeSendThread();
|
||||
|
@ -190,8 +188,6 @@ protected:
|
|||
bool _debugReceiving;
|
||||
bool _debugTimestampNow;
|
||||
bool _verboseDebug;
|
||||
JurisdictionMap* _jurisdiction;
|
||||
JurisdictionSender* _jurisdictionSender;
|
||||
OctreeInboundPacketProcessor* _octreeInboundPacketProcessor;
|
||||
OctreePersistThread* _persistThread;
|
||||
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
|
||||
#include <SharedUtil.h>
|
||||
#include <NodeList.h> // for MAX_PACKET_SIZE
|
||||
#include <JurisdictionSender.h>
|
||||
|
||||
const int MAX_FILENAME_LENGTH = 1024;
|
||||
|
||||
|
|
|
@ -79,7 +79,6 @@ EntityScriptServer::EntityScriptServer(ReceivedMessage& message) : ThreadedAssig
|
|||
auto& packetReceiver = DependencyManager::get<NodeList>()->getPacketReceiver();
|
||||
packetReceiver.registerListenerForTypes({ PacketType::OctreeStats, PacketType::EntityData, PacketType::EntityErase },
|
||||
this, "handleOctreePacket");
|
||||
packetReceiver.registerListener(PacketType::Jurisdiction, this, "handleJurisdictionPacket");
|
||||
packetReceiver.registerListener(PacketType::SelectedAudioFormat, this, "handleSelectedAudioFormat");
|
||||
|
||||
auto avatarHashMap = DependencyManager::set<AvatarHashMap>();
|
||||
|
@ -283,11 +282,8 @@ void EntityScriptServer::run() {
|
|||
// Setup Script Engine
|
||||
resetEntitiesScriptEngine();
|
||||
|
||||
// we need to make sure that init has been called for our EntityScriptingInterface
|
||||
// so that it actually has a jurisdiction listener when we ask it for it next
|
||||
auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>();
|
||||
entityScriptingInterface->init();
|
||||
_entityViewer.setJurisdictionListener(entityScriptingInterface->getJurisdictionListener());
|
||||
|
||||
_entityViewer.init();
|
||||
|
||||
|
@ -566,17 +562,6 @@ void EntityScriptServer::handleOctreePacket(QSharedPointer<ReceivedMessage> mess
|
|||
}
|
||||
}
|
||||
|
||||
void EntityScriptServer::handleJurisdictionPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer senderNode) {
|
||||
NodeType_t nodeType;
|
||||
message->peekPrimitive(&nodeType);
|
||||
|
||||
// PacketType_JURISDICTION, first byte is the node type...
|
||||
if (nodeType == NodeType::EntityServer) {
|
||||
DependencyManager::get<EntityScriptingInterface>()->getJurisdictionListener()->
|
||||
queueReceivedPacket(message, senderNode);
|
||||
}
|
||||
}
|
||||
|
||||
void EntityScriptServer::aboutToFinish() {
|
||||
shutdownScriptEngine();
|
||||
|
||||
|
|
|
@ -41,7 +41,6 @@ public slots:
|
|||
|
||||
private slots:
|
||||
void handleOctreePacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer senderNode);
|
||||
void handleJurisdictionPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer senderNode);
|
||||
void handleSelectedAudioFormat(QSharedPointer<ReceivedMessage> message);
|
||||
|
||||
void handleReloadEntityServerScriptPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer senderNode);
|
||||
|
|
|
@ -1189,8 +1189,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
userActivityLogger.logAction("launch", properties);
|
||||
}
|
||||
|
||||
// Tell our entity edit sender about our known jurisdictions
|
||||
_entityEditSender.setServerJurisdictions(&_entityServerJurisdictions);
|
||||
_entityEditSender.setMyAvatar(myAvatar.get());
|
||||
|
||||
// The entity octree will have to know about MyAvatar for the parentJointName import
|
||||
|
@ -4557,7 +4555,7 @@ void Application::reloadResourceCaches() {
|
|||
_lastQueriedTime = 0;
|
||||
_octreeQuery.incrementConnectionID();
|
||||
|
||||
queryOctree(NodeType::EntityServer, PacketType::EntityQuery, _entityServerJurisdictions);
|
||||
queryOctree(NodeType::EntityServer, PacketType::EntityQuery);
|
||||
|
||||
DependencyManager::get<AssetClient>()->clearCache();
|
||||
|
||||
|
@ -5050,7 +5048,7 @@ void Application::update(float deltaTime) {
|
|||
if (queryIsDue || viewIsDifferentEnough) {
|
||||
_lastQueriedTime = now;
|
||||
if (DependencyManager::get<SceneScriptingInterface>()->shouldRenderEntities()) {
|
||||
queryOctree(NodeType::EntityServer, PacketType::EntityQuery, _entityServerJurisdictions);
|
||||
queryOctree(NodeType::EntityServer, PacketType::EntityQuery);
|
||||
}
|
||||
sendAvatarViewFrustum();
|
||||
_lastQueriedViewFrustum = _viewFrustum;
|
||||
|
@ -5271,15 +5269,12 @@ int Application::sendNackPackets() {
|
|||
return packetsSent;
|
||||
}
|
||||
|
||||
void Application::queryOctree(NodeType_t serverType, PacketType packetType, NodeToJurisdictionMap& jurisdictions) {
|
||||
void Application::queryOctree(NodeType_t serverType, PacketType packetType) {
|
||||
|
||||
if (!_settingsLoaded) {
|
||||
return; // bail early if settings are not loaded
|
||||
}
|
||||
|
||||
//qCDebug(interfaceapp) << ">>> inside... queryOctree()... _viewFrustum.getFieldOfView()=" << _viewFrustum.getFieldOfView();
|
||||
bool wantExtraDebugging = getLogger()->extraDebugging();
|
||||
|
||||
ViewFrustum viewFrustum;
|
||||
copyViewFrustum(viewFrustum);
|
||||
_octreeQuery.setCameraPosition(viewFrustum.getPosition());
|
||||
|
@ -5294,147 +5289,22 @@ void Application::queryOctree(NodeType_t serverType, PacketType packetType, Node
|
|||
_octreeQuery.setOctreeSizeScale(lodManager->getOctreeSizeScale());
|
||||
_octreeQuery.setBoundaryLevelAdjust(lodManager->getBoundaryLevelAdjust());
|
||||
|
||||
// Iterate all of the nodes, and get a count of how many octree servers we have...
|
||||
int totalServers = 0;
|
||||
int inViewServers = 0;
|
||||
int unknownJurisdictionServers = 0;
|
||||
|
||||
auto nodeList = DependencyManager::get<NodeList>();
|
||||
|
||||
nodeList->eachNode([&](const SharedNodePointer& node) {
|
||||
// only send to the NodeTypes that are serverType
|
||||
if (node->getActiveSocket() && node->getType() == serverType) {
|
||||
totalServers++;
|
||||
auto node = nodeList->soloNodeOfType(serverType);
|
||||
if (node && node->getActiveSocket()) {
|
||||
_octreeQuery.setMaxQueryPacketsPerSecond(getMaxOctreePacketsPerSecond());
|
||||
|
||||
// get the server bounds for this server
|
||||
QUuid nodeUUID = node->getUUID();
|
||||
auto queryPacket = NLPacket::create(packetType);
|
||||
|
||||
// if we haven't heard from this voxel server, go ahead and send it a query, so we
|
||||
// can get the jurisdiction...
|
||||
if (jurisdictions.find(nodeUUID) == jurisdictions.end()) {
|
||||
unknownJurisdictionServers++;
|
||||
} else {
|
||||
const JurisdictionMap& map = (jurisdictions)[nodeUUID];
|
||||
// encode the query data
|
||||
auto packetData = reinterpret_cast<unsigned char*>(queryPacket->getPayload());
|
||||
int packetSize = _octreeQuery.getBroadcastData(packetData);
|
||||
queryPacket->setPayloadSize(packetSize);
|
||||
|
||||
auto rootCode = map.getRootOctalCode();
|
||||
|
||||
if (rootCode) {
|
||||
VoxelPositionSize rootDetails;
|
||||
voxelDetailsForCode(rootCode.get(), rootDetails);
|
||||
AACube serverBounds(glm::vec3(rootDetails.x * TREE_SCALE,
|
||||
rootDetails.y * TREE_SCALE,
|
||||
rootDetails.z * TREE_SCALE) - glm::vec3(HALF_TREE_SCALE),
|
||||
rootDetails.s * TREE_SCALE);
|
||||
if (viewFrustum.cubeIntersectsKeyhole(serverBounds)) {
|
||||
inViewServers++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (wantExtraDebugging) {
|
||||
qCDebug(interfaceapp, "Servers: total %d, in view %d, unknown jurisdiction %d",
|
||||
totalServers, inViewServers, unknownJurisdictionServers);
|
||||
// make sure we still have an active socket
|
||||
nodeList->sendUnreliablePacket(*queryPacket, *node);
|
||||
}
|
||||
|
||||
int perServerPPS = 0;
|
||||
const int SMALL_BUDGET = 10;
|
||||
int perUnknownServer = SMALL_BUDGET;
|
||||
int totalPPS = getMaxOctreePacketsPerSecond();
|
||||
|
||||
// determine PPS based on number of servers
|
||||
if (inViewServers >= 1) {
|
||||
// set our preferred PPS to be exactly evenly divided among all of the voxel servers... and allocate 1 PPS
|
||||
// for each unknown jurisdiction server
|
||||
perServerPPS = (totalPPS / inViewServers) - (unknownJurisdictionServers * perUnknownServer);
|
||||
} else {
|
||||
if (unknownJurisdictionServers > 0) {
|
||||
perUnknownServer = (totalPPS / unknownJurisdictionServers);
|
||||
}
|
||||
}
|
||||
|
||||
if (wantExtraDebugging) {
|
||||
qCDebug(interfaceapp, "perServerPPS: %d perUnknownServer: %d", perServerPPS, perUnknownServer);
|
||||
}
|
||||
|
||||
auto queryPacket = NLPacket::create(packetType);
|
||||
|
||||
nodeList->eachNode([&](const SharedNodePointer& node) {
|
||||
// only send to the NodeTypes that are serverType
|
||||
if (node->getActiveSocket() && node->getType() == serverType) {
|
||||
|
||||
// get the server bounds for this server
|
||||
QUuid nodeUUID = node->getUUID();
|
||||
|
||||
bool inView = false;
|
||||
bool unknownView = false;
|
||||
|
||||
// if we haven't heard from this voxel server, go ahead and send it a query, so we
|
||||
// can get the jurisdiction...
|
||||
if (jurisdictions.find(nodeUUID) == jurisdictions.end()) {
|
||||
unknownView = true; // assume it's in view
|
||||
if (wantExtraDebugging) {
|
||||
qCDebug(interfaceapp) << "no known jurisdiction for node " << *node << ", assume it's visible.";
|
||||
}
|
||||
} else {
|
||||
const JurisdictionMap& map = (jurisdictions)[nodeUUID];
|
||||
|
||||
auto rootCode = map.getRootOctalCode();
|
||||
|
||||
if (rootCode) {
|
||||
VoxelPositionSize rootDetails;
|
||||
voxelDetailsForCode(rootCode.get(), rootDetails);
|
||||
AACube serverBounds(glm::vec3(rootDetails.x * TREE_SCALE,
|
||||
rootDetails.y * TREE_SCALE,
|
||||
rootDetails.z * TREE_SCALE) - glm::vec3(HALF_TREE_SCALE),
|
||||
rootDetails.s * TREE_SCALE);
|
||||
|
||||
|
||||
inView = viewFrustum.cubeIntersectsKeyhole(serverBounds);
|
||||
} else if (wantExtraDebugging) {
|
||||
qCDebug(interfaceapp) << "Jurisdiction without RootCode for node " << *node << ". That's unusual!";
|
||||
}
|
||||
}
|
||||
|
||||
if (inView) {
|
||||
_octreeQuery.setMaxQueryPacketsPerSecond(perServerPPS);
|
||||
} else if (unknownView) {
|
||||
if (wantExtraDebugging) {
|
||||
qCDebug(interfaceapp) << "no known jurisdiction for node " << *node << ", give it budget of "
|
||||
<< perUnknownServer << " to send us jurisdiction.";
|
||||
}
|
||||
|
||||
// set the query's position/orientation to be degenerate in a manner that will get the scene quickly
|
||||
// If there's only one server, then don't do this, and just let the normal voxel query pass through
|
||||
// as expected... this way, we will actually get a valid scene if there is one to be seen
|
||||
if (totalServers > 1) {
|
||||
_octreeQuery.setCameraPosition(glm::vec3(-0.1,-0.1,-0.1));
|
||||
const glm::quat OFF_IN_NEGATIVE_SPACE = glm::quat(-0.5, 0, -0.5, 1.0);
|
||||
_octreeQuery.setCameraOrientation(OFF_IN_NEGATIVE_SPACE);
|
||||
_octreeQuery.setCameraNearClip(0.1f);
|
||||
_octreeQuery.setCameraFarClip(0.1f);
|
||||
if (wantExtraDebugging) {
|
||||
qCDebug(interfaceapp) << "Using 'minimal' camera position for node" << *node;
|
||||
}
|
||||
} else {
|
||||
if (wantExtraDebugging) {
|
||||
qCDebug(interfaceapp) << "Using regular camera position for node" << *node;
|
||||
}
|
||||
}
|
||||
_octreeQuery.setMaxQueryPacketsPerSecond(perUnknownServer);
|
||||
} else {
|
||||
_octreeQuery.setMaxQueryPacketsPerSecond(0);
|
||||
}
|
||||
|
||||
// encode the query data
|
||||
int packetSize = _octreeQuery.getBroadcastData(reinterpret_cast<unsigned char*>(queryPacket->getPayload()));
|
||||
queryPacket->setPayloadSize(packetSize);
|
||||
|
||||
// make sure we still have an active socket
|
||||
nodeList->sendUnreliablePacket(*queryPacket, *node);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
@ -5549,11 +5419,6 @@ void Application::clearDomainOctreeDetails() {
|
|||
|
||||
resetPhysicsReadyInformation();
|
||||
|
||||
// reset our node to stats and node to jurisdiction maps... since these must be changing...
|
||||
_entityServerJurisdictions.withWriteLock([&] {
|
||||
_entityServerJurisdictions.clear();
|
||||
});
|
||||
|
||||
_octreeServerSceneStats.withWriteLock([&] {
|
||||
_octreeServerSceneStats.clear();
|
||||
});
|
||||
|
@ -5755,8 +5620,6 @@ bool Application::nearbyEntitiesAreReadyForPhysics() {
|
|||
}
|
||||
|
||||
int Application::processOctreeStats(ReceivedMessage& message, SharedNodePointer sendingNode) {
|
||||
// But, also identify the sender, and keep track of the contained jurisdiction root for this server
|
||||
|
||||
// parse the incoming stats datas stick it in a temporary object for now, while we
|
||||
// determine which server it belongs to
|
||||
int statsMessageLength = 0;
|
||||
|
@ -5771,42 +5634,6 @@ int Application::processOctreeStats(ReceivedMessage& message, SharedNodePointer
|
|||
if (octreeStats.isFullScene()) {
|
||||
_fullSceneReceivedCounter++;
|
||||
}
|
||||
|
||||
// see if this is the first we've heard of this node...
|
||||
NodeToJurisdictionMap* jurisdiction = nullptr;
|
||||
QString serverType;
|
||||
if (sendingNode->getType() == NodeType::EntityServer) {
|
||||
jurisdiction = &_entityServerJurisdictions;
|
||||
serverType = "Entity";
|
||||
}
|
||||
|
||||
bool found = false;
|
||||
|
||||
jurisdiction->withReadLock([&] {
|
||||
if (jurisdiction->find(nodeUUID) != jurisdiction->end()) {
|
||||
found = true;
|
||||
return;
|
||||
}
|
||||
|
||||
VoxelPositionSize rootDetails;
|
||||
voxelDetailsForCode(octreeStats.getJurisdictionRoot().get(), rootDetails);
|
||||
|
||||
qCDebug(interfaceapp, "stats from new %s server... [%f, %f, %f, %f]",
|
||||
qPrintable(serverType),
|
||||
(double)rootDetails.x, (double)rootDetails.y, (double)rootDetails.z, (double)rootDetails.s);
|
||||
});
|
||||
|
||||
if (!found) {
|
||||
// store jurisdiction details for later use
|
||||
// This is bit of fiddling is because JurisdictionMap assumes it is the owner of the values used to construct it
|
||||
// but OctreeSceneStats thinks it's just returning a reference to its contents. So we need to make a copy of the
|
||||
// details from the OctreeSceneStats to construct the JurisdictionMap
|
||||
JurisdictionMap jurisdictionMap;
|
||||
jurisdictionMap.copyContents(octreeStats.getJurisdictionRoot(), octreeStats.getJurisdictionEndNodes());
|
||||
jurisdiction->withWriteLock([&] {
|
||||
(*jurisdiction)[nodeUUID] = jurisdictionMap;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return statsMessageLength;
|
||||
|
@ -5827,7 +5654,7 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEnginePointe
|
|||
return !entityServerNode || isPhysicsEnabled();
|
||||
});
|
||||
|
||||
// setup the packet senders and jurisdiction listeners of the script engine's scripting interfaces so
|
||||
// setup the packet sender of the script engine's scripting interfaces so
|
||||
// we can use the same ones from the application.
|
||||
auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>();
|
||||
entityScriptingInterface->setPacketSender(&_entityEditSender);
|
||||
|
|
|
@ -228,8 +228,6 @@ public:
|
|||
|
||||
FileLogger* getLogger() const { return _logger; }
|
||||
|
||||
NodeToJurisdictionMap& getEntityServerJurisdictions() { return _entityServerJurisdictions; }
|
||||
|
||||
float getRenderResolutionScale() const;
|
||||
|
||||
qint64 getCurrentSessionRuntime() const { return _sessionRunTimer.elapsed(); }
|
||||
|
@ -450,7 +448,7 @@ private:
|
|||
void updateThreads(float deltaTime);
|
||||
void updateDialogs(float deltaTime) const;
|
||||
|
||||
void queryOctree(NodeType_t serverType, PacketType packetType, NodeToJurisdictionMap& jurisdictions);
|
||||
void queryOctree(NodeType_t serverType, PacketType packetType);
|
||||
|
||||
int sendNackPackets();
|
||||
void sendAvatarViewFrustum();
|
||||
|
@ -571,7 +569,6 @@ private:
|
|||
StDev _idleLoopStdev;
|
||||
float _idleLoopMeasuredJitter;
|
||||
|
||||
NodeToJurisdictionMap _entityServerJurisdictions;
|
||||
NodeToOctreeSceneStats _octreeServerSceneStats;
|
||||
ControllerScriptingInterface* _controllerScriptingInterface{ nullptr };
|
||||
QPointer<LogDialog> _logDialog;
|
||||
|
|
|
@ -378,8 +378,7 @@ void OctreeStatsDialog::paintEvent(QPaintEvent* event) {
|
|||
void OctreeStatsDialog::showAllOctreeServers() {
|
||||
int serverCount = 0;
|
||||
|
||||
showOctreeServersOfType(serverCount, NodeType::EntityServer, "Entity",
|
||||
qApp->getEntityServerJurisdictions());
|
||||
showOctreeServersOfType(serverCount, NodeType::EntityServer, "Entity");
|
||||
|
||||
if (_octreeServerLabelsCount > serverCount) {
|
||||
for (int i = serverCount; i < _octreeServerLabelsCount; i++) {
|
||||
|
@ -391,8 +390,7 @@ void OctreeStatsDialog::showAllOctreeServers() {
|
|||
}
|
||||
}
|
||||
|
||||
void OctreeStatsDialog::showOctreeServersOfType(int& serverCount, NodeType_t serverType, const char* serverTypeName,
|
||||
NodeToJurisdictionMap& serverJurisdictions) {
|
||||
void OctreeStatsDialog::showOctreeServersOfType(int& serverCount, NodeType_t serverType, const char* serverTypeName) {
|
||||
|
||||
QLocale locale(QLocale::English);
|
||||
|
||||
|
@ -424,35 +422,6 @@ void OctreeStatsDialog::showOctreeServersOfType(int& serverCount, NodeType_t ser
|
|||
|
||||
QUuid nodeUUID = node->getUUID();
|
||||
|
||||
// lookup our nodeUUID in the jurisdiction map, if it's missing then we're
|
||||
// missing at least one jurisdiction
|
||||
serverJurisdictions.withReadLock([&] {
|
||||
if (serverJurisdictions.find(nodeUUID) == serverJurisdictions.end()) {
|
||||
serverDetails << " unknown jurisdiction ";
|
||||
return;
|
||||
}
|
||||
const JurisdictionMap& map = serverJurisdictions[nodeUUID];
|
||||
|
||||
auto rootCode = map.getRootOctalCode();
|
||||
|
||||
if (rootCode) {
|
||||
QString rootCodeHex = octalCodeToHexString(rootCode.get());
|
||||
|
||||
VoxelPositionSize rootDetails;
|
||||
voxelDetailsForCode(rootCode.get(), rootDetails);
|
||||
AACube serverBounds(glm::vec3(rootDetails.x, rootDetails.y, rootDetails.z), rootDetails.s);
|
||||
serverDetails << " jurisdiction: "
|
||||
<< qPrintable(rootCodeHex)
|
||||
<< " ["
|
||||
<< rootDetails.x << ", "
|
||||
<< rootDetails.y << ", "
|
||||
<< rootDetails.z << ": "
|
||||
<< rootDetails.s << "] ";
|
||||
} else {
|
||||
serverDetails << " jurisdiction has no rootCode";
|
||||
} // root code
|
||||
});
|
||||
|
||||
// now lookup stats details for this server...
|
||||
if (_extraServerDetails[serverCount-1] != LESS) {
|
||||
NodeToOctreeSceneStats* sceneStats = qApp->getOcteeSceneStats();
|
||||
|
|
|
@ -48,7 +48,7 @@ protected:
|
|||
void showAllOctreeServers();
|
||||
|
||||
void showOctreeServersOfType(int& serverNumber, NodeType_t serverType,
|
||||
const char* serverTypeName, NodeToJurisdictionMap& serverJurisdictions);
|
||||
const char* serverTypeName);
|
||||
|
||||
private:
|
||||
|
||||
|
|
|
@ -239,16 +239,14 @@ void OctreeStatsProvider::updateOctreeStatsData() {
|
|||
void OctreeStatsProvider::updateOctreeServers() {
|
||||
int serverCount = 0;
|
||||
|
||||
showOctreeServersOfType(serverCount, NodeType::EntityServer, "Entity",
|
||||
qApp->getEntityServerJurisdictions());
|
||||
showOctreeServersOfType(serverCount, NodeType::EntityServer, "Entity");
|
||||
if (m_serversNum != serverCount) {
|
||||
m_serversNum = serverCount;
|
||||
emit serversNumChanged(m_serversNum);
|
||||
}
|
||||
}
|
||||
|
||||
void OctreeStatsProvider::showOctreeServersOfType(int& serverCount, NodeType_t serverType, const char* serverTypeName,
|
||||
NodeToJurisdictionMap& serverJurisdictions) {
|
||||
void OctreeStatsProvider::showOctreeServersOfType(int& serverCount, NodeType_t serverType, const char* serverTypeName) {
|
||||
|
||||
m_servers.clear();
|
||||
|
||||
|
@ -270,35 +268,7 @@ void OctreeStatsProvider::showOctreeServersOfType(int& serverCount, NodeType_t s
|
|||
}
|
||||
|
||||
QUuid nodeUUID = node->getUUID();
|
||||
|
||||
// lookup our nodeUUID in the jurisdiction map, if it's missing then we're
|
||||
// missing at least one jurisdiction
|
||||
serverJurisdictions.withReadLock([&] {
|
||||
if (serverJurisdictions.find(nodeUUID) == serverJurisdictions.end()) {
|
||||
lesserDetails += " unknown jurisdiction ";
|
||||
return;
|
||||
}
|
||||
const JurisdictionMap& map = serverJurisdictions[nodeUUID];
|
||||
|
||||
auto rootCode = map.getRootOctalCode();
|
||||
|
||||
if (rootCode) {
|
||||
QString rootCodeHex = octalCodeToHexString(rootCode.get());
|
||||
|
||||
VoxelPositionSize rootDetails;
|
||||
voxelDetailsForCode(rootCode.get(), rootDetails);
|
||||
AACube serverBounds(glm::vec3(rootDetails.x, rootDetails.y, rootDetails.z), rootDetails.s);
|
||||
lesserDetails += QString(" jurisdiction: %1 [%2, %3, %4: %5]")
|
||||
.arg(rootCodeHex)
|
||||
.arg(rootDetails.x)
|
||||
.arg(rootDetails.y)
|
||||
.arg(rootDetails.z)
|
||||
.arg(rootDetails.s);
|
||||
} else {
|
||||
lesserDetails += " jurisdiction has no rootCode";
|
||||
} // root code
|
||||
});
|
||||
|
||||
// now lookup stats details for this server...
|
||||
NodeToOctreeSceneStats* sceneStats = qApp->getOcteeSceneStats();
|
||||
sceneStats->withReadLock([&] {
|
||||
|
|
|
@ -121,8 +121,7 @@ private slots:
|
|||
void updateOctreeStatsData();
|
||||
protected:
|
||||
void updateOctreeServers();
|
||||
void showOctreeServersOfType(int& serverNumber, NodeType_t serverType,
|
||||
const char* serverTypeName, NodeToJurisdictionMap& serverJurisdictions);
|
||||
void showOctreeServersOfType(int& serverNumber, NodeType_t serverType, const char* serverTypeName);
|
||||
|
||||
private:
|
||||
NodeToOctreeSceneStats* _model;
|
||||
|
|
|
@ -56,8 +56,6 @@ public:
|
|||
ICEServerPeerInformation,
|
||||
ICEServerQuery,
|
||||
OctreeStats,
|
||||
Jurisdiction,
|
||||
JurisdictionRequest,
|
||||
AssignmentClientStatus,
|
||||
NoisyMute,
|
||||
AvatarIdentity,
|
||||
|
|
|
@ -1,85 +0,0 @@
|
|||
//
|
||||
// JurisdictionListener.cpp
|
||||
// libraries/octree/src
|
||||
//
|
||||
// Created by Brad Hefta-Gaub on 8/12/13.
|
||||
// Copyright 2013 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 <PerfStat.h>
|
||||
|
||||
#include <OctalCode.h>
|
||||
#include <SharedUtil.h>
|
||||
#include <udt/PacketHeaders.h>
|
||||
#include "JurisdictionListener.h"
|
||||
|
||||
JurisdictionListener::JurisdictionListener(NodeType_t type) :
|
||||
_nodeType(type),
|
||||
_packetSender(JurisdictionListener::DEFAULT_PACKETS_PER_SECOND)
|
||||
{
|
||||
setObjectName("Jurisdiction Listener");
|
||||
|
||||
connect(DependencyManager::get<NodeList>().data(), &NodeList::nodeKilled, this, &JurisdictionListener::nodeKilled);
|
||||
|
||||
// tell our NodeList we want to hear about nodes with our node type
|
||||
DependencyManager::get<NodeList>()->addNodeTypeToInterestSet(type);
|
||||
}
|
||||
|
||||
void JurisdictionListener::nodeKilled(SharedNodePointer node) {
|
||||
if (_jurisdictions.find(node->getUUID()) != _jurisdictions.end()) {
|
||||
_jurisdictions.erase(_jurisdictions.find(node->getUUID()));
|
||||
}
|
||||
}
|
||||
|
||||
bool JurisdictionListener::queueJurisdictionRequest() {
|
||||
auto nodeList = DependencyManager::get<NodeList>();
|
||||
|
||||
int nodeCount = 0;
|
||||
|
||||
nodeList->eachNode([&](const SharedNodePointer& node) {
|
||||
if (node->getType() == getNodeType() && node->getActiveSocket()) {
|
||||
auto packet = NLPacket::create(PacketType::JurisdictionRequest, 0);
|
||||
_packetSender.queuePacketForSending(node, std::move(packet));
|
||||
nodeCount++;
|
||||
}
|
||||
});
|
||||
|
||||
if (nodeCount > 0){
|
||||
_packetSender.setPacketsPerSecond(nodeCount);
|
||||
} else {
|
||||
_packetSender.setPacketsPerSecond(NO_SERVER_CHECK_RATE);
|
||||
}
|
||||
|
||||
// keep going if still running
|
||||
return isStillRunning();
|
||||
}
|
||||
|
||||
void JurisdictionListener::processPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode) {
|
||||
if (message->getType() == PacketType::Jurisdiction) {
|
||||
JurisdictionMap map;
|
||||
map.unpackFromPacket(*message);
|
||||
_jurisdictions[message->getSourceID()] = map;
|
||||
}
|
||||
}
|
||||
|
||||
bool JurisdictionListener::process() {
|
||||
bool continueProcessing = isStillRunning();
|
||||
|
||||
// If we're still running, and we don't have any requests waiting to be sent, then queue our jurisdiction requests
|
||||
if (continueProcessing && !_packetSender.hasPacketsToSend()) {
|
||||
queueJurisdictionRequest();
|
||||
}
|
||||
|
||||
if (continueProcessing) {
|
||||
continueProcessing = _packetSender.process();
|
||||
}
|
||||
if (continueProcessing) {
|
||||
// NOTE: This will sleep if there are no pending packets to process
|
||||
continueProcessing = ReceivedPacketProcessor::process();
|
||||
}
|
||||
|
||||
return continueProcessing;
|
||||
}
|
|
@ -1,60 +0,0 @@
|
|||
//
|
||||
// JurisdictionListener.h
|
||||
// libraries/octree/src
|
||||
//
|
||||
// Created by Brad Hefta-Gaub on 8/12/13.
|
||||
// Copyright 2013 High Fidelity, Inc.
|
||||
//
|
||||
// Voxel Packet Sender
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#ifndef hifi_JurisdictionListener_h
|
||||
#define hifi_JurisdictionListener_h
|
||||
|
||||
#include <NodeList.h>
|
||||
#include <PacketSender.h>
|
||||
#include <ReceivedPacketProcessor.h>
|
||||
|
||||
#include "JurisdictionMap.h"
|
||||
|
||||
/// Sends out PacketType::_JURISDICTION_REQUEST packets to all voxel servers and then listens for and processes
|
||||
/// the PacketType::_JURISDICTION packets it receives in order to maintain an accurate state of all jurisidictions
|
||||
/// within the domain. As with other ReceivedPacketProcessor classes the user is responsible for reading inbound packets
|
||||
/// and adding them to the processing queue by calling queueReceivedPacket()
|
||||
class JurisdictionListener : public ReceivedPacketProcessor {
|
||||
Q_OBJECT
|
||||
public:
|
||||
static const int DEFAULT_PACKETS_PER_SECOND = 1;
|
||||
static const int NO_SERVER_CHECK_RATE = 60; // if no servers yet detected, keep checking at 60fps
|
||||
|
||||
JurisdictionListener(NodeType_t type = NodeType::EntityServer);
|
||||
|
||||
virtual bool process() override;
|
||||
|
||||
NodeToJurisdictionMap* getJurisdictions() { return &_jurisdictions; }
|
||||
|
||||
|
||||
NodeType_t getNodeType() const { return _nodeType; }
|
||||
void setNodeType(NodeType_t type) { _nodeType = type; }
|
||||
|
||||
public slots:
|
||||
/// Called by NodeList to inform us that a node has been killed.
|
||||
void nodeKilled(SharedNodePointer node);
|
||||
|
||||
protected:
|
||||
/// Callback for processing of received packets. Will process any queued PacketType::_JURISDICTION and update the
|
||||
/// jurisdiction map member variable
|
||||
virtual void processPacket(QSharedPointer<ReceivedMessage> messsage, SharedNodePointer sendingNode) override;
|
||||
|
||||
private:
|
||||
NodeToJurisdictionMap _jurisdictions;
|
||||
NodeType_t _nodeType;
|
||||
|
||||
bool queueJurisdictionRequest();
|
||||
|
||||
PacketSender _packetSender;
|
||||
};
|
||||
#endif // hifi_JurisdictionListener_h
|
|
@ -1,325 +0,0 @@
|
|||
//
|
||||
// JurisdictionMap.cpp
|
||||
// libraries/octree/src
|
||||
//
|
||||
// Created by Brad Hefta-Gaub on 8/1/13.
|
||||
// Copyright 2013 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 <QSettings>
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
#include <QDebug>
|
||||
|
||||
#include <DependencyManager.h>
|
||||
#include <NodeList.h>
|
||||
#include <udt/PacketHeaders.h>
|
||||
|
||||
#include "OctreeLogging.h"
|
||||
#include "JurisdictionMap.h"
|
||||
|
||||
void myDebugOutputBits(unsigned char byte, bool withNewLine) {
|
||||
if (isalnum(byte)) {
|
||||
printf("[ %d (%c): ", byte, byte);
|
||||
} else {
|
||||
printf("[ %d (0x%x): ", byte, byte);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 8; i++) {
|
||||
printf("%d", byte >> (7 - i) & 1);
|
||||
}
|
||||
printf(" ] ");
|
||||
|
||||
if (withNewLine) {
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
void myDebugPrintOctalCode(const unsigned char* octalCode, bool withNewLine) {
|
||||
if (!octalCode) {
|
||||
printf("nullptr");
|
||||
} else {
|
||||
for (size_t i = 0; i < bytesRequiredForCodeLength(numberOfThreeBitSectionsInCode(octalCode)); i++) {
|
||||
myDebugOutputBits(octalCode[i], false);
|
||||
}
|
||||
}
|
||||
if (withNewLine) {
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
// standard assignment
|
||||
// copy assignment
|
||||
JurisdictionMap& JurisdictionMap::operator=(const JurisdictionMap& other) {
|
||||
copyContents(other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Copy constructor
|
||||
JurisdictionMap::JurisdictionMap(const JurisdictionMap& other) : _rootOctalCode(nullptr) {
|
||||
copyContents(other);
|
||||
}
|
||||
|
||||
void JurisdictionMap::copyContents(const OctalCodePtr& rootCodeIn, const OctalCodePtrList& endNodesIn) {
|
||||
OctalCodePtr rootCode = rootCodeIn;
|
||||
if (!rootCode) {
|
||||
rootCode = createOctalCodePtr(1);
|
||||
*rootCode = 0;
|
||||
}
|
||||
|
||||
OctalCodePtrList emptyEndNodes;
|
||||
init(rootCode, endNodesIn);
|
||||
}
|
||||
|
||||
void JurisdictionMap::copyContents(const JurisdictionMap& other) {
|
||||
_nodeType = other._nodeType;
|
||||
|
||||
OctalCodePtr rootOctalCode;
|
||||
OctalCodePtrList endNodes;
|
||||
|
||||
std::tie(rootOctalCode, endNodes) = other.getRootAndEndNodeOctalCodes();
|
||||
|
||||
init(rootOctalCode, endNodes);
|
||||
}
|
||||
|
||||
JurisdictionMap::~JurisdictionMap() {
|
||||
}
|
||||
|
||||
JurisdictionMap::JurisdictionMap(NodeType_t type) : _rootOctalCode(nullptr) {
|
||||
_nodeType = type;
|
||||
OctalCodePtr rootCode = createOctalCodePtr(1);
|
||||
*rootCode = 0;
|
||||
|
||||
OctalCodePtrList emptyEndNodes;
|
||||
init(rootCode, emptyEndNodes);
|
||||
}
|
||||
|
||||
JurisdictionMap::JurisdictionMap(const char* filename) : _rootOctalCode(nullptr) {
|
||||
readFromFile(filename);
|
||||
}
|
||||
|
||||
JurisdictionMap::JurisdictionMap(const char* rootHexCode, const char* endNodesHexCodes) {
|
||||
|
||||
qCDebug(octree, "JurisdictionMap::JurisdictionMap(const char* rootHexCode=[%p] %s, const char* endNodesHexCodes=[%p] %s)",
|
||||
rootHexCode, rootHexCode, endNodesHexCodes, endNodesHexCodes);
|
||||
|
||||
_rootOctalCode = hexStringToOctalCode(QString(rootHexCode));
|
||||
|
||||
qCDebug(octree, "JurisdictionMap::JurisdictionMap() _rootOctalCode=%p octalCode=", _rootOctalCode.get());
|
||||
myDebugPrintOctalCode(_rootOctalCode.get(), true);
|
||||
|
||||
QString endNodesHexStrings(endNodesHexCodes);
|
||||
QString delimiterPattern(",");
|
||||
QStringList endNodeList = endNodesHexStrings.split(delimiterPattern);
|
||||
|
||||
for (int i = 0; i < endNodeList.size(); i++) {
|
||||
QString endNodeHexString = endNodeList.at(i);
|
||||
|
||||
auto endNodeOctcode = hexStringToOctalCode(endNodeHexString);
|
||||
|
||||
qCDebug(octree, "JurisdictionMap::JurisdictionMap() endNodeList(%d)=%s",
|
||||
i, endNodeHexString.toLocal8Bit().constData());
|
||||
|
||||
//printOctalCode(endNodeOctcode);
|
||||
_endNodes.push_back(endNodeOctcode);
|
||||
|
||||
qCDebug(octree, "JurisdictionMap::JurisdictionMap() endNodeOctcode=%p octalCode=", endNodeOctcode.get());
|
||||
myDebugPrintOctalCode(endNodeOctcode.get(), true);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
std::tuple<OctalCodePtr, OctalCodePtrList> JurisdictionMap::getRootAndEndNodeOctalCodes() const {
|
||||
std::lock_guard<std::mutex> lock(_octalCodeMutex);
|
||||
return std::tuple<OctalCodePtr, OctalCodePtrList>(_rootOctalCode, _endNodes);
|
||||
}
|
||||
|
||||
OctalCodePtr JurisdictionMap::getRootOctalCode() const {
|
||||
std::lock_guard<std::mutex> lock(_octalCodeMutex);
|
||||
return _rootOctalCode;
|
||||
}
|
||||
|
||||
OctalCodePtrList JurisdictionMap::getEndNodeOctalCodes() const {
|
||||
std::lock_guard<std::mutex> lock(_octalCodeMutex);
|
||||
return _endNodes;
|
||||
}
|
||||
|
||||
void JurisdictionMap::init(OctalCodePtr rootOctalCode, const OctalCodePtrList& endNodes) {
|
||||
std::lock_guard<std::mutex> lock(_octalCodeMutex);
|
||||
_rootOctalCode = rootOctalCode;
|
||||
_endNodes = endNodes;
|
||||
}
|
||||
|
||||
JurisdictionMap::Area JurisdictionMap::isMyJurisdiction(const unsigned char* nodeOctalCode, int childIndex) const {
|
||||
// to be in our jurisdiction, we must be under the root...
|
||||
|
||||
std::lock_guard<std::mutex> lock(_octalCodeMutex);
|
||||
|
||||
// if the node is an ancestor of my root, then we return ABOVE
|
||||
if (isAncestorOf(nodeOctalCode, _rootOctalCode.get())) {
|
||||
return ABOVE;
|
||||
}
|
||||
|
||||
// otherwise...
|
||||
bool isInJurisdiction = isAncestorOf(_rootOctalCode.get(), nodeOctalCode, childIndex);
|
||||
// if we're under the root, then we can't be under any of the endpoints
|
||||
if (isInJurisdiction) {
|
||||
for (size_t i = 0; i < _endNodes.size(); i++) {
|
||||
bool isUnderEndNode = isAncestorOf(_endNodes[i].get(), nodeOctalCode);
|
||||
if (isUnderEndNode) {
|
||||
isInJurisdiction = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return isInJurisdiction ? WITHIN : BELOW;
|
||||
}
|
||||
|
||||
|
||||
bool JurisdictionMap::readFromFile(const char* filename) {
|
||||
QString settingsFile(filename);
|
||||
QSettings settings(settingsFile, QSettings::IniFormat);
|
||||
QString rootCode = settings.value("root","00").toString();
|
||||
qCDebug(octree) << "rootCode=" << rootCode;
|
||||
|
||||
std::lock_guard<std::mutex> lock(_octalCodeMutex);
|
||||
_rootOctalCode = hexStringToOctalCode(rootCode);
|
||||
printOctalCode(_rootOctalCode.get());
|
||||
|
||||
settings.beginGroup("endNodes");
|
||||
const QStringList childKeys = settings.childKeys();
|
||||
QHash<QString, QString> values;
|
||||
foreach (const QString &childKey, childKeys) {
|
||||
QString childValue = settings.value(childKey).toString();
|
||||
values.insert(childKey, childValue);
|
||||
qCDebug(octree) << childKey << "=" << childValue;
|
||||
|
||||
auto octcode = hexStringToOctalCode(childValue);
|
||||
printOctalCode(octcode.get());
|
||||
|
||||
_endNodes.push_back(octcode);
|
||||
}
|
||||
settings.endGroup();
|
||||
return true;
|
||||
}
|
||||
|
||||
void JurisdictionMap::displayDebugDetails() const {
|
||||
std::lock_guard<std::mutex> lock(_octalCodeMutex);
|
||||
|
||||
QString rootNodeValue = octalCodeToHexString(_rootOctalCode.get());
|
||||
|
||||
qCDebug(octree) << "root:" << rootNodeValue;
|
||||
|
||||
for (size_t i = 0; i < _endNodes.size(); i++) {
|
||||
QString value = octalCodeToHexString(_endNodes[i].get());
|
||||
qCDebug(octree) << "End node[" << i << "]: " << rootNodeValue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool JurisdictionMap::writeToFile(const char* filename) {
|
||||
QString settingsFile(filename);
|
||||
QSettings settings(settingsFile, QSettings::IniFormat);
|
||||
|
||||
std::lock_guard<std::mutex> lock(_octalCodeMutex);
|
||||
|
||||
QString rootNodeValue = octalCodeToHexString(_rootOctalCode.get());
|
||||
|
||||
settings.setValue("root", rootNodeValue);
|
||||
|
||||
settings.beginGroup("endNodes");
|
||||
for (size_t i = 0; i < _endNodes.size(); i++) {
|
||||
QString key = QString("endnode%1").arg(i);
|
||||
QString value = octalCodeToHexString(_endNodes[i].get());
|
||||
settings.setValue(key, value);
|
||||
}
|
||||
settings.endGroup();
|
||||
return true;
|
||||
}
|
||||
|
||||
std::unique_ptr<NLPacket> JurisdictionMap::packEmptyJurisdictionIntoMessage(NodeType_t type) {
|
||||
int bytes = 0;
|
||||
auto packet = NLPacket::create(PacketType::Jurisdiction, sizeof(type) + sizeof(bytes));
|
||||
|
||||
// Pack the Node Type in first byte
|
||||
packet->writePrimitive(type);
|
||||
// No root or end node details to pack!
|
||||
packet->writePrimitive(bytes);
|
||||
|
||||
return packet; // includes header!
|
||||
}
|
||||
|
||||
std::unique_ptr<NLPacket> JurisdictionMap::packIntoPacket() {
|
||||
auto packet = NLPacket::create(PacketType::Jurisdiction);
|
||||
|
||||
// Pack the Node Type in first byte
|
||||
NodeType_t type = getNodeType();
|
||||
packet->writePrimitive(type);
|
||||
|
||||
// add the root jurisdiction
|
||||
std::lock_guard<std::mutex> lock(_octalCodeMutex);
|
||||
if (_rootOctalCode) {
|
||||
size_t bytes = bytesRequiredForCodeLength(numberOfThreeBitSectionsInCode(_rootOctalCode.get()));
|
||||
// No root or end node details to pack!
|
||||
packet->writePrimitive(bytes);
|
||||
packet->write(reinterpret_cast<char*>(_rootOctalCode.get()), bytes);
|
||||
|
||||
// if and only if there's a root jurisdiction, also include the end nodes
|
||||
int endNodeCount = (int)_endNodes.size();
|
||||
packet->writePrimitive(endNodeCount);
|
||||
|
||||
for (int i=0; i < endNodeCount; i++) {
|
||||
auto endNodeCode = _endNodes[i].get();
|
||||
size_t bytes = 0;
|
||||
if (endNodeCode) {
|
||||
bytes = bytesRequiredForCodeLength(numberOfThreeBitSectionsInCode(endNodeCode));
|
||||
}
|
||||
packet->writePrimitive(bytes);
|
||||
packet->write(reinterpret_cast<char*>(endNodeCode), bytes);
|
||||
}
|
||||
} else {
|
||||
int bytes = 0;
|
||||
packet->writePrimitive(bytes);
|
||||
}
|
||||
|
||||
return packet;
|
||||
}
|
||||
|
||||
int JurisdictionMap::unpackFromPacket(ReceivedMessage& message) {
|
||||
// read the root jurisdiction
|
||||
int bytes = 0;
|
||||
message.readPrimitive(&bytes);
|
||||
|
||||
std::lock_guard<std::mutex> lock(_octalCodeMutex);
|
||||
_rootOctalCode = nullptr;
|
||||
_endNodes.clear();
|
||||
|
||||
if (bytes > 0 && bytes <= message.getBytesLeftToRead()) {
|
||||
_rootOctalCode = createOctalCodePtr(bytes);
|
||||
message.read(reinterpret_cast<char*>(_rootOctalCode.get()), bytes);
|
||||
|
||||
// if and only if there's a root jurisdiction, also include the end nodes
|
||||
int endNodeCount = 0;
|
||||
message.readPrimitive(&endNodeCount);
|
||||
|
||||
for (int i = 0; i < endNodeCount; i++) {
|
||||
int bytes = 0;
|
||||
message.readPrimitive(&bytes);
|
||||
|
||||
if (bytes <= message.getBytesLeftToRead()) {
|
||||
auto endNodeCode = createOctalCodePtr(bytes);
|
||||
message.read(reinterpret_cast<char*>(endNodeCode.get()), bytes);
|
||||
|
||||
// if the endNodeCode was 0 length then don't add it
|
||||
if (bytes > 0) {
|
||||
_endNodes.push_back(endNodeCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return message.getPosition(); // excludes header
|
||||
}
|
|
@ -1,88 +0,0 @@
|
|||
//
|
||||
// JurisdictionMap.h
|
||||
// libraries/octree/src
|
||||
//
|
||||
// Created by Brad Hefta-Gaub on 8/1/13.
|
||||
// Copyright 2013 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
|
||||
//
|
||||
|
||||
#ifndef hifi_JurisdictionMap_h
|
||||
#define hifi_JurisdictionMap_h
|
||||
|
||||
#include <map>
|
||||
#include <stdint.h>
|
||||
#include <vector>
|
||||
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QUuid>
|
||||
|
||||
#include <shared/ReadWriteLockable.h>
|
||||
|
||||
#include <NLPacket.h>
|
||||
#include <Node.h>
|
||||
#include <OctalCode.h>
|
||||
|
||||
class JurisdictionMap {
|
||||
public:
|
||||
enum Area {
|
||||
ABOVE,
|
||||
WITHIN,
|
||||
BELOW
|
||||
};
|
||||
|
||||
// standard constructors
|
||||
JurisdictionMap(NodeType_t type = NodeType::EntityServer); // default constructor
|
||||
JurisdictionMap(const JurisdictionMap& other); // copy constructor
|
||||
|
||||
// standard assignment
|
||||
JurisdictionMap& operator=(const JurisdictionMap& other); // copy assignment
|
||||
|
||||
// application constructors
|
||||
JurisdictionMap(const char* filename);
|
||||
JurisdictionMap(const char* rootHextString, const char* endNodesHextString);
|
||||
|
||||
~JurisdictionMap();
|
||||
|
||||
Area isMyJurisdiction(const unsigned char* nodeOctalCode, int childIndex) const;
|
||||
|
||||
bool writeToFile(const char* filename);
|
||||
bool readFromFile(const char* filename);
|
||||
|
||||
// Provide an atomic way to get both the rootOctalCode and endNodeOctalCodes.
|
||||
std::tuple<OctalCodePtr, OctalCodePtrList> getRootAndEndNodeOctalCodes() const;
|
||||
OctalCodePtr getRootOctalCode() const;
|
||||
OctalCodePtrList getEndNodeOctalCodes() const;
|
||||
|
||||
void copyContents(const OctalCodePtr& rootCodeIn, const OctalCodePtrList& endNodesIn);
|
||||
|
||||
int unpackFromPacket(ReceivedMessage& message);
|
||||
std::unique_ptr<NLPacket> packIntoPacket();
|
||||
|
||||
/// Available to pack an empty or unknown jurisdiction into a network packet, used when no JurisdictionMap is available
|
||||
static std::unique_ptr<NLPacket> packEmptyJurisdictionIntoMessage(NodeType_t type);
|
||||
|
||||
void displayDebugDetails() const;
|
||||
|
||||
NodeType_t getNodeType() const { return _nodeType; }
|
||||
void setNodeType(NodeType_t type) { _nodeType = type; }
|
||||
|
||||
private:
|
||||
void copyContents(const JurisdictionMap& other); // use assignment instead
|
||||
void init(OctalCodePtr rootOctalCode, const OctalCodePtrList& endNodes);
|
||||
|
||||
mutable std::mutex _octalCodeMutex;
|
||||
OctalCodePtr _rootOctalCode { nullptr };
|
||||
OctalCodePtrList _endNodes;
|
||||
NodeType_t _nodeType;
|
||||
};
|
||||
|
||||
/// Map between node IDs and their reported JurisdictionMap. Typically used by classes that need to know which nodes are
|
||||
/// managing which jurisdictions.
|
||||
class NodeToJurisdictionMap : public QMap<QUuid, JurisdictionMap>, public ReadWriteLockable {};
|
||||
typedef QMap<QUuid, JurisdictionMap>::iterator NodeToJurisdictionMapIterator;
|
||||
|
||||
|
||||
#endif // hifi_JurisdictionMap_h
|
|
@ -1,68 +0,0 @@
|
|||
//
|
||||
// JurisdictionSender.cpp
|
||||
// libraries/octree/src
|
||||
//
|
||||
// Created by Brad Hefta-Gaub on 8/12/13.
|
||||
// Copyright 2013 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 <PerfStat.h>
|
||||
|
||||
#include <OctalCode.h>
|
||||
#include <SharedUtil.h>
|
||||
#include <udt/PacketHeaders.h>
|
||||
#include "JurisdictionSender.h"
|
||||
|
||||
|
||||
JurisdictionSender::JurisdictionSender(JurisdictionMap* map, NodeType_t type) :
|
||||
ReceivedPacketProcessor(),
|
||||
_jurisdictionMap(map),
|
||||
_nodeType(type),
|
||||
_packetSender(JurisdictionSender::DEFAULT_PACKETS_PER_SECOND)
|
||||
{
|
||||
}
|
||||
|
||||
JurisdictionSender::~JurisdictionSender() {
|
||||
}
|
||||
|
||||
void JurisdictionSender::processPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode) {
|
||||
if (message->getType() == PacketType::JurisdictionRequest) {
|
||||
lockRequestingNodes();
|
||||
_nodesRequestingJurisdictions.push(sendingNode->getUUID());
|
||||
unlockRequestingNodes();
|
||||
}
|
||||
}
|
||||
|
||||
bool JurisdictionSender::process() {
|
||||
bool continueProcessing = isStillRunning();
|
||||
|
||||
// call our ReceivedPacketProcessor base class process so we'll get any pending packets
|
||||
if (continueProcessing && (continueProcessing = ReceivedPacketProcessor::process())) {
|
||||
int nodeCount = 0;
|
||||
|
||||
lockRequestingNodes();
|
||||
while (!_nodesRequestingJurisdictions.empty()) {
|
||||
|
||||
QUuid nodeUUID = _nodesRequestingJurisdictions.front();
|
||||
_nodesRequestingJurisdictions.pop();
|
||||
SharedNodePointer node = DependencyManager::get<NodeList>()->nodeWithUUID(nodeUUID);
|
||||
|
||||
if (node && node->getActiveSocket()) {
|
||||
auto packet = (_jurisdictionMap) ? _jurisdictionMap->packIntoPacket()
|
||||
: JurisdictionMap::packEmptyJurisdictionIntoMessage(getNodeType());
|
||||
_packetSender.queuePacketForSending(node, std::move(packet));
|
||||
nodeCount++;
|
||||
}
|
||||
}
|
||||
unlockRequestingNodes();
|
||||
|
||||
// set our packets per second to be the number of nodes
|
||||
_packetSender.setPacketsPerSecond(nodeCount);
|
||||
|
||||
continueProcessing = _packetSender.process();
|
||||
}
|
||||
return continueProcessing;
|
||||
}
|
|
@ -1,58 +0,0 @@
|
|||
//
|
||||
// JurisdictionSender.h
|
||||
// libraries/octree/src
|
||||
//
|
||||
// Created by Brad Hefta-Gaub on 8/12/13.
|
||||
// Copyright 2013 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
|
||||
//
|
||||
|
||||
#ifndef hifi_JurisdictionSender_h
|
||||
#define hifi_JurisdictionSender_h
|
||||
|
||||
#include <queue>
|
||||
#include <QMutex>
|
||||
|
||||
#include <PacketSender.h>
|
||||
#include <ReceivedPacketProcessor.h>
|
||||
#include "JurisdictionMap.h"
|
||||
|
||||
/// Will process PacketType::_JURISDICTION_REQUEST packets and send out PacketType::_JURISDICTION packets
|
||||
/// to requesting parties. As with other ReceivedPacketProcessor classes the user is responsible for reading inbound packets
|
||||
/// and adding them to the processing queue by calling queueReceivedPacket()
|
||||
class JurisdictionSender : public ReceivedPacketProcessor {
|
||||
Q_OBJECT
|
||||
public:
|
||||
static const int DEFAULT_PACKETS_PER_SECOND = 1;
|
||||
|
||||
JurisdictionSender(JurisdictionMap* map, NodeType_t type = NodeType::EntityServer);
|
||||
~JurisdictionSender();
|
||||
|
||||
void setJurisdiction(JurisdictionMap* map) { _jurisdictionMap = map; }
|
||||
|
||||
virtual bool process() override;
|
||||
|
||||
NodeType_t getNodeType() const { return _nodeType; }
|
||||
void setNodeType(NodeType_t type) { _nodeType = type; }
|
||||
|
||||
protected:
|
||||
virtual void processPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode) override;
|
||||
|
||||
/// Locks all the resources of the thread.
|
||||
void lockRequestingNodes() { _requestingNodeMutex.lock(); }
|
||||
|
||||
/// Unlocks all the resources of the thread.
|
||||
void unlockRequestingNodes() { _requestingNodeMutex.unlock(); }
|
||||
|
||||
|
||||
private:
|
||||
QMutex _requestingNodeMutex;
|
||||
JurisdictionMap* _jurisdictionMap;
|
||||
std::queue<QUuid> _nodesRequestingJurisdictions;
|
||||
NodeType_t _nodeType;
|
||||
|
||||
PacketSender _packetSender;
|
||||
};
|
||||
#endif // hifi_JurisdictionSender_h
|
|
@ -1020,16 +1020,6 @@ int Octree::encodeTreeBitstreamRecursion(const OctreeElementPointer& element,
|
|||
return bytesAtThisLevel;
|
||||
}
|
||||
|
||||
// If we've been provided a jurisdiction map, then we need to honor it.
|
||||
if (params.jurisdictionMap) {
|
||||
// here's how it works... if we're currently above our root jurisdiction, then we proceed normally.
|
||||
// but once we're in our own jurisdiction, then we need to make sure we're not below it.
|
||||
if (JurisdictionMap::BELOW == params.jurisdictionMap->isMyJurisdiction(element->getOctalCode(), CHECK_NODE_ONLY)) {
|
||||
params.stopReason = EncodeBitstreamParams::OUT_OF_JURISDICTION;
|
||||
return bytesAtThisLevel;
|
||||
}
|
||||
}
|
||||
|
||||
ViewFrustum::intersection nodeLocationThisView = ViewFrustum::INSIDE; // assume we're inside
|
||||
if (octreeQueryNode->getUsesFrustum() && !params.recurseEverything) {
|
||||
float boundaryDistance = boundaryDistanceForRenderLevel(element->getLevel() + params.boundaryLevelAdjust,
|
||||
|
@ -1152,18 +1142,9 @@ int Octree::encodeTreeBitstreamRecursion(const OctreeElementPointer& element,
|
|||
for (int i = 0; i < NUMBER_OF_CHILDREN; i++) {
|
||||
OctreeElementPointer childElement = element->getChildAtIndex(i);
|
||||
|
||||
// if the caller wants to include childExistsBits, then include them even if not in view, if however,
|
||||
// we're in a portion of the tree that's not our responsibility, then we assume the child nodes exist
|
||||
// even if they don't in our local tree
|
||||
bool notMyJurisdiction = false;
|
||||
if (params.jurisdictionMap) {
|
||||
notMyJurisdiction = JurisdictionMap::WITHIN != params.jurisdictionMap->isMyJurisdiction(element->getOctalCode(), i);
|
||||
}
|
||||
if (params.includeExistsBits) {
|
||||
// If the child is known to exist, OR, it's not my jurisdiction, then we mark the bit as existing
|
||||
if (childElement || notMyJurisdiction) {
|
||||
childrenExistInTreeBits += (1 << (7 - i));
|
||||
}
|
||||
// if the caller wants to include childExistsBits, then include them
|
||||
if (params.includeExistsBits && childElement) {
|
||||
childrenExistInTreeBits += (1 << (7 - i));
|
||||
}
|
||||
|
||||
sortedChildren[i] = childElement;
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
#include <SimpleMovingAverage.h>
|
||||
#include <ViewFrustum.h>
|
||||
|
||||
#include "JurisdictionMap.h"
|
||||
#include "OctreeElement.h"
|
||||
#include "OctreeElementBag.h"
|
||||
#include "OctreePacketData.h"
|
||||
|
@ -62,7 +61,6 @@ const int NO_BOUNDARY_ADJUST = 0;
|
|||
const int LOW_RES_MOVING_ADJUST = 1;
|
||||
|
||||
#define IGNORE_COVERAGE_MAP NULL
|
||||
#define IGNORE_JURISDICTION_MAP NULL
|
||||
|
||||
class EncodeBitstreamParams {
|
||||
public:
|
||||
|
@ -77,7 +75,6 @@ public:
|
|||
int boundaryLevelAdjust;
|
||||
float octreeElementSizeScale;
|
||||
bool forceSendScene;
|
||||
JurisdictionMap* jurisdictionMap;
|
||||
NodeData* nodeData;
|
||||
|
||||
// output hints from the encode process
|
||||
|
@ -87,7 +84,6 @@ public:
|
|||
NULL_NODE,
|
||||
NULL_NODE_DATA,
|
||||
TOO_DEEP,
|
||||
OUT_OF_JURISDICTION,
|
||||
LOD_SKIP,
|
||||
OUT_OF_VIEW,
|
||||
WAS_IN_VIEW,
|
||||
|
@ -105,7 +101,6 @@ public:
|
|||
int boundaryLevelAdjust = NO_BOUNDARY_ADJUST,
|
||||
float octreeElementSizeScale = DEFAULT_OCTREE_SIZE_SCALE,
|
||||
bool forceSendScene = true,
|
||||
JurisdictionMap* jurisdictionMap = IGNORE_JURISDICTION_MAP,
|
||||
NodeData* nodeData = nullptr) :
|
||||
maxEncodeLevel(maxEncodeLevel),
|
||||
maxLevelReached(0),
|
||||
|
@ -115,7 +110,6 @@ public:
|
|||
boundaryLevelAdjust(boundaryLevelAdjust),
|
||||
octreeElementSizeScale(octreeElementSizeScale),
|
||||
forceSendScene(forceSendScene),
|
||||
jurisdictionMap(jurisdictionMap),
|
||||
nodeData(nodeData),
|
||||
stopReason(UNKNOWN)
|
||||
{
|
||||
|
@ -131,7 +125,6 @@ public:
|
|||
case DIDNT_FIT: qDebug("DIDNT_FIT"); break;
|
||||
case NULL_NODE: qDebug("NULL_NODE"); break;
|
||||
case TOO_DEEP: qDebug("TOO_DEEP"); break;
|
||||
case OUT_OF_JURISDICTION: qDebug("OUT_OF_JURISDICTION"); break;
|
||||
case LOD_SKIP: qDebug("LOD_SKIP"); break;
|
||||
case OUT_OF_VIEW: qDebug("OUT_OF_VIEW"); break;
|
||||
case WAS_IN_VIEW: qDebug("WAS_IN_VIEW"); break;
|
||||
|
@ -148,7 +141,6 @@ public:
|
|||
case DIDNT_FIT: return QString("DIDNT_FIT"); break;
|
||||
case NULL_NODE: return QString("NULL_NODE"); break;
|
||||
case TOO_DEEP: return QString("TOO_DEEP"); break;
|
||||
case OUT_OF_JURISDICTION: return QString("OUT_OF_JURISDICTION"); break;
|
||||
case LOD_SKIP: return QString("LOD_SKIP"); break;
|
||||
case OUT_OF_VIEW: return QString("OUT_OF_VIEW"); break;
|
||||
case WAS_IN_VIEW: return QString("WAS_IN_VIEW"); break;
|
||||
|
|
|
@ -22,13 +22,10 @@ const int OctreeEditPacketSender::DEFAULT_MAX_PENDING_MESSAGES = PacketSender::D
|
|||
|
||||
|
||||
OctreeEditPacketSender::OctreeEditPacketSender() :
|
||||
PacketSender(),
|
||||
_shouldSend(true),
|
||||
_maxPendingMessages(DEFAULT_MAX_PENDING_MESSAGES),
|
||||
_releaseQueuedMessagesPending(false),
|
||||
_serverJurisdictions(NULL)
|
||||
_releaseQueuedMessagesPending(false)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
OctreeEditPacketSender::~OctreeEditPacketSender() {
|
||||
|
@ -40,34 +37,8 @@ OctreeEditPacketSender::~OctreeEditPacketSender() {
|
|||
|
||||
|
||||
bool OctreeEditPacketSender::serversExist() const {
|
||||
bool hasServers = false;
|
||||
bool atLeastOneJurisdictionMissing = false; // assume the best
|
||||
|
||||
DependencyManager::get<NodeList>()->eachNodeBreakable([&](const SharedNodePointer& node){
|
||||
if (node->getType() == getMyNodeType() && node->getActiveSocket()) {
|
||||
|
||||
QUuid nodeUUID = node->getUUID();
|
||||
// If we've got Jurisdictions set, then check to see if we know the jurisdiction for this server
|
||||
if (_serverJurisdictions) {
|
||||
// lookup our nodeUUID in the jurisdiction map, if it's missing then we're
|
||||
// missing at least one jurisdiction
|
||||
_serverJurisdictions->withReadLock([&] {
|
||||
if ((*_serverJurisdictions).find(nodeUUID) == (*_serverJurisdictions).end()) {
|
||||
atLeastOneJurisdictionMissing = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
hasServers = true;
|
||||
}
|
||||
|
||||
if (atLeastOneJurisdictionMissing) {
|
||||
return false; // no point in looking further - return false from anonymous function
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
return (hasServers && !atLeastOneJurisdictionMissing);
|
||||
auto node = DependencyManager::get<NodeList>()->soloNodeOfType(getMyNodeType());
|
||||
return node && node->getActiveSocket();
|
||||
}
|
||||
|
||||
// This method is called when the edit packet layer has determined that it has a fully formed packet destined for
|
||||
|
@ -132,7 +103,7 @@ void OctreeEditPacketSender::queuePacketListToNode(const QUuid& nodeUUID, std::u
|
|||
}
|
||||
|
||||
void OctreeEditPacketSender::processPreServerExistsPackets() {
|
||||
assert(serversExist()); // we should only be here if we have jurisdictions
|
||||
assert(serversExist()); // we should only be here if we have servers
|
||||
|
||||
// First send out all the single message packets...
|
||||
_pendingPacketsLock.lock();
|
||||
|
@ -150,7 +121,7 @@ void OctreeEditPacketSender::processPreServerExistsPackets() {
|
|||
|
||||
_pendingPacketsLock.unlock();
|
||||
|
||||
// if while waiting for the jurisdictions the caller called releaseQueuedMessages()
|
||||
// if while waiting for the servers the caller called releaseQueuedMessages()
|
||||
// then we want to honor that request now.
|
||||
if (_releaseQueuedMessagesPending) {
|
||||
releaseQueuedMessages();
|
||||
|
@ -178,34 +149,12 @@ void OctreeEditPacketSender::queuePacketToNodes(std::unique_ptr<NLPacket> packet
|
|||
return; // bail early
|
||||
}
|
||||
|
||||
assert(serversExist()); // we must have jurisdictions to be here!!
|
||||
assert(serversExist()); // we must have servers to be here!!
|
||||
|
||||
const unsigned char* octCode = reinterpret_cast<unsigned char*>(packet->getPayload()) + sizeof(short) + sizeof(quint64);
|
||||
|
||||
// We want to filter out edit messages for servers based on the server's Jurisdiction
|
||||
// But we can't really do that with a packed message, since each edit message could be destined
|
||||
// for a different server... So we need to actually manage multiple queued packets... one
|
||||
// for each server
|
||||
|
||||
DependencyManager::get<NodeList>()->eachNode([&](const SharedNodePointer& node){
|
||||
// only send to the NodeTypes that are getMyNodeType()
|
||||
if (node->getActiveSocket() && node->getType() == getMyNodeType()) {
|
||||
QUuid nodeUUID = node->getUUID();
|
||||
bool isMyJurisdiction = true;
|
||||
// we need to get the jurisdiction for this
|
||||
// here we need to get the "pending packet" for this server
|
||||
_serverJurisdictions->withReadLock([&] {
|
||||
const JurisdictionMap& map = (*_serverJurisdictions)[nodeUUID];
|
||||
isMyJurisdiction = (map.isMyJurisdiction(octCode, CHECK_NODE_ONLY) == JurisdictionMap::WITHIN);
|
||||
});
|
||||
|
||||
if (isMyJurisdiction) {
|
||||
// make a copy of this packet for this node and queue
|
||||
auto packetCopy = NLPacket::createCopy(*packet);
|
||||
queuePacketToNode(nodeUUID, std::move(packetCopy));
|
||||
}
|
||||
}
|
||||
});
|
||||
auto node = DependencyManager::get<NodeList>()->soloNodeOfType(getMyNodeType());
|
||||
if (node && node->getActiveSocket()) {
|
||||
queuePacketToNode(node->getUUID(), std::move(packet));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -216,8 +165,8 @@ void OctreeEditPacketSender::queueOctreeEditMessage(PacketType type, QByteArray&
|
|||
return; // bail early
|
||||
}
|
||||
|
||||
// If we don't have jurisdictions, then we will simply queue up all of these packets and wait till we have
|
||||
// jurisdictions for processing
|
||||
// If we don't have servers, then we will simply queue up all of these packets and wait till we have
|
||||
// servers for processing
|
||||
if (!serversExist()) {
|
||||
if (_maxPendingMessages > 0) {
|
||||
EditMessagePair messagePair { type, QByteArray(editMessage) };
|
||||
|
@ -235,107 +184,80 @@ void OctreeEditPacketSender::queueOctreeEditMessage(PacketType type, QByteArray&
|
|||
return; // bail early
|
||||
}
|
||||
|
||||
// We want to filter out edit messages for servers based on the server's Jurisdiction
|
||||
// But we can't really do that with a packed message, since each edit message could be destined
|
||||
// for a different server... So we need to actually manage multiple queued packets... one
|
||||
// for each server
|
||||
_packetsQueueLock.lock();
|
||||
|
||||
DependencyManager::get<NodeList>()->eachNode([&](const SharedNodePointer& node){
|
||||
// only send to the NodeTypes that are getMyNodeType()
|
||||
if (node->getActiveSocket() && node->getType() == getMyNodeType()) {
|
||||
QUuid nodeUUID = node->getUUID();
|
||||
bool isMyJurisdiction = true;
|
||||
auto node = DependencyManager::get<NodeList>()->soloNodeOfType(getMyNodeType());
|
||||
if (node && node->getActiveSocket()) {
|
||||
QUuid nodeUUID = node->getUUID();
|
||||
|
||||
if (type == PacketType::EntityErase) {
|
||||
isMyJurisdiction = true; // send erase messages to all servers
|
||||
} else if (_serverJurisdictions) {
|
||||
// we need to get the jurisdiction for this
|
||||
// here we need to get the "pending packet" for this server
|
||||
_serverJurisdictions->withReadLock([&] {
|
||||
if ((*_serverJurisdictions).find(nodeUUID) != (*_serverJurisdictions).end()) {
|
||||
const JurisdictionMap& map = (*_serverJurisdictions)[nodeUUID];
|
||||
isMyJurisdiction = (map.isMyJurisdiction(reinterpret_cast<const unsigned char*>(editMessage.data()),
|
||||
CHECK_NODE_ONLY) == JurisdictionMap::WITHIN);
|
||||
} else {
|
||||
isMyJurisdiction = false;
|
||||
}
|
||||
});
|
||||
// for edit messages, we will attempt to combine multiple edit commands where possible, we
|
||||
// don't do this for add because we send those reliably
|
||||
if (type == PacketType::EntityAdd) {
|
||||
auto newPacket = NLPacketList::create(type, QByteArray(), true, true);
|
||||
auto nodeClockSkew = node->getClockSkewUsec();
|
||||
|
||||
// pack sequence number
|
||||
quint16 sequence = _outgoingSequenceNumbers[nodeUUID]++;
|
||||
newPacket->writePrimitive(sequence);
|
||||
|
||||
// pack in timestamp
|
||||
quint64 now = usecTimestampNow() + nodeClockSkew;
|
||||
newPacket->writePrimitive(now);
|
||||
|
||||
|
||||
// We call this virtual function that allows our specific type of EditPacketSender to
|
||||
// fixup the buffer for any clock skew
|
||||
if (nodeClockSkew != 0) {
|
||||
adjustEditPacketForClockSkew(type, editMessage, nodeClockSkew);
|
||||
}
|
||||
if (isMyJurisdiction) {
|
||||
|
||||
// for edit messages, we will attempt to combine multiple edit commands where possible, we
|
||||
// don't do this for add because we send those reliably
|
||||
if (type == PacketType::EntityAdd) {
|
||||
newPacket->write(editMessage);
|
||||
|
||||
auto newPacket = NLPacketList::create(type, QByteArray(), true, true);
|
||||
auto nodeClockSkew = node->getClockSkewUsec();
|
||||
// release the new packet
|
||||
releaseQueuedPacketList(nodeUUID, std::move(newPacket));
|
||||
|
||||
// pack sequence number
|
||||
quint16 sequence = _outgoingSequenceNumbers[nodeUUID]++;
|
||||
newPacket->writePrimitive(sequence);
|
||||
// tell the sent packet history that we used a sequence number for an untracked packet
|
||||
auto& sentPacketHistory = _sentPacketHistories[nodeUUID];
|
||||
sentPacketHistory.untrackedPacketSent(sequence);
|
||||
} else {
|
||||
// only a NLPacket for now
|
||||
std::unique_ptr<NLPacket>& bufferedPacket = _pendingEditPackets[nodeUUID].first;
|
||||
|
||||
// pack in timestamp
|
||||
quint64 now = usecTimestampNow() + nodeClockSkew;
|
||||
newPacket->writePrimitive(now);
|
||||
if (!bufferedPacket) {
|
||||
bufferedPacket = initializePacket(type, node->getClockSkewUsec());
|
||||
} else {
|
||||
// If we're switching type, then we send the last one and start over
|
||||
if ((type != bufferedPacket->getType() && bufferedPacket->getPayloadSize() > 0) ||
|
||||
(editMessage.size() >= bufferedPacket->bytesAvailableForWrite())) {
|
||||
|
||||
// create the new packet and swap it with the packet in _pendingEditPackets
|
||||
auto packetToRelease = initializePacket(type, node->getClockSkewUsec());
|
||||
bufferedPacket.swap(packetToRelease);
|
||||
|
||||
// We call this virtual function that allows our specific type of EditPacketSender to
|
||||
// fixup the buffer for any clock skew
|
||||
if (nodeClockSkew != 0) {
|
||||
adjustEditPacketForClockSkew(type, editMessage, nodeClockSkew);
|
||||
}
|
||||
|
||||
newPacket->write(editMessage);
|
||||
|
||||
// release the new packet
|
||||
releaseQueuedPacketList(nodeUUID, std::move(newPacket));
|
||||
|
||||
// tell the sent packet history that we used a sequence number for an untracked packet
|
||||
auto& sentPacketHistory = _sentPacketHistories[nodeUUID];
|
||||
sentPacketHistory.untrackedPacketSent(sequence);
|
||||
} else {
|
||||
|
||||
std::unique_ptr<NLPacket>& bufferedPacket = _pendingEditPackets[nodeUUID].first; //only a NLPacket for now
|
||||
|
||||
if (!bufferedPacket) {
|
||||
bufferedPacket = initializePacket(type, node->getClockSkewUsec());
|
||||
} else {
|
||||
// If we're switching type, then we send the last one and start over
|
||||
if ((type != bufferedPacket->getType() && bufferedPacket->getPayloadSize() > 0) ||
|
||||
(editMessage.size() >= bufferedPacket->bytesAvailableForWrite())) {
|
||||
|
||||
// create the new packet and swap it with the packet in _pendingEditPackets
|
||||
auto packetToRelease = initializePacket(type, node->getClockSkewUsec());
|
||||
bufferedPacket.swap(packetToRelease);
|
||||
|
||||
// release the previously buffered packet
|
||||
releaseQueuedPacket(nodeUUID, std::move(packetToRelease));
|
||||
}
|
||||
}
|
||||
|
||||
// This is really the first time we know which server/node this particular edit message
|
||||
// is going to, so we couldn't adjust for clock skew till now. But here's our chance.
|
||||
// We call this virtual function that allows our specific type of EditPacketSender to
|
||||
// fixup the buffer for any clock skew
|
||||
if (node->getClockSkewUsec() != 0) {
|
||||
adjustEditPacketForClockSkew(type, editMessage, node->getClockSkewUsec());
|
||||
}
|
||||
|
||||
bufferedPacket->write(editMessage);
|
||||
|
||||
// release the previously buffered packet
|
||||
releaseQueuedPacket(nodeUUID, std::move(packetToRelease));
|
||||
}
|
||||
}
|
||||
|
||||
// This is really the first time we know which server/node this particular edit message
|
||||
// is going to, so we couldn't adjust for clock skew till now. But here's our chance.
|
||||
// We call this virtual function that allows our specific type of EditPacketSender to
|
||||
// fixup the buffer for any clock skew
|
||||
if (node->getClockSkewUsec() != 0) {
|
||||
adjustEditPacketForClockSkew(type, editMessage, node->getClockSkewUsec());
|
||||
}
|
||||
|
||||
bufferedPacket->write(editMessage);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
_packetsQueueLock.unlock();
|
||||
|
||||
}
|
||||
|
||||
void OctreeEditPacketSender::releaseQueuedMessages() {
|
||||
// if we don't yet have jurisdictions then we can't actually release messages yet because we don't
|
||||
// know where to send them to. Instead, just remember this request and when we eventually get jurisdictions
|
||||
// if we don't yet have servers then we can't actually release messages yet because we don't
|
||||
// know where to send them to. Instead, just remember this request and when we eventually get servers
|
||||
// call release again at that time.
|
||||
if (!serversExist()) {
|
||||
_releaseQueuedMessagesPending = true;
|
||||
|
@ -397,8 +319,8 @@ std::unique_ptr<NLPacket> OctreeEditPacketSender::initializePacket(PacketType ty
|
|||
}
|
||||
|
||||
bool OctreeEditPacketSender::process() {
|
||||
// if we have server jurisdiction details, and we have pending pre-jurisdiction packets, then process those
|
||||
// before doing our normal process step. This processPreJurisdictionPackets()
|
||||
// if we have servers, and we have pending pre-servers exist packets, then process those
|
||||
// before doing our normal process step. This processPreServerExistPackets()
|
||||
if (serversExist() && (!_preServerEdits.empty() || !_preServerSingleMessagePackets.empty() )) {
|
||||
processPreServerExistsPackets();
|
||||
}
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
#include <PacketSender.h>
|
||||
#include <udt/PacketHeaders.h>
|
||||
|
||||
#include "JurisdictionMap.h"
|
||||
#include "SentPacketHistory.h"
|
||||
|
||||
/// Utility for processing, packing, queueing and sending of outbound edit messages.
|
||||
|
@ -49,14 +48,6 @@ public:
|
|||
/// in an application like interface when all octree features are disabled.
|
||||
void setShouldSend(bool shouldSend) { _shouldSend = shouldSend; }
|
||||
|
||||
/// call this to inform the OctreeEditPacketSender of the server jurisdictions. This is required for normal operation.
|
||||
/// The internal contents of the jurisdiction map may change throughout the lifetime of the OctreeEditPacketSender. This map
|
||||
/// can be set prior to servers being present, so long as the contents of the map accurately reflect the current
|
||||
/// known jurisdictions.
|
||||
void setServerJurisdictions(NodeToJurisdictionMap* serverJurisdictions) {
|
||||
_serverJurisdictions = serverJurisdictions;
|
||||
}
|
||||
|
||||
/// if you're running in non-threaded mode, you must call this method regularly
|
||||
virtual bool process() override;
|
||||
|
||||
|
@ -108,8 +99,6 @@ protected:
|
|||
std::list<EditMessagePair> _preServerEdits; // these will get packed into other larger packets
|
||||
std::list<std::unique_ptr<NLPacket>> _preServerSingleMessagePackets; // these will go out as is
|
||||
|
||||
NodeToJurisdictionMap* _serverJurisdictions;
|
||||
|
||||
QMutex _releaseQueuedPacketMutex;
|
||||
|
||||
// TODO: add locks for this and _pendingEditPackets
|
||||
|
|
|
@ -37,15 +37,13 @@ OctreeSceneStats::OctreeSceneStats() :
|
|||
_incomingBytes(0),
|
||||
_incomingWastedBytes(0),
|
||||
_incomingOctreeSequenceNumberStats(),
|
||||
_incomingFlightTimeAverage(samples),
|
||||
_jurisdictionRoot(NULL)
|
||||
_incomingFlightTimeAverage(samples)
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
// copy constructor
|
||||
OctreeSceneStats::OctreeSceneStats(const OctreeSceneStats& other) :
|
||||
_jurisdictionRoot(NULL) {
|
||||
OctreeSceneStats::OctreeSceneStats(const OctreeSceneStats& other) {
|
||||
copyFromOther(other);
|
||||
}
|
||||
|
||||
|
@ -109,26 +107,6 @@ void OctreeSceneStats::copyFromOther(const OctreeSceneStats& other) {
|
|||
_existsInPacketBitsWritten = other._existsInPacketBitsWritten;
|
||||
_treesRemoved = other._treesRemoved;
|
||||
|
||||
// before copying the jurisdictions, delete any current values...
|
||||
_jurisdictionRoot = nullptr;
|
||||
_jurisdictionEndNodes.clear();
|
||||
|
||||
// Now copy the values from the other
|
||||
if (other._jurisdictionRoot) {
|
||||
auto bytes = bytesRequiredForCodeLength(numberOfThreeBitSectionsInCode(other._jurisdictionRoot.get()));
|
||||
_jurisdictionRoot = createOctalCodePtr(bytes);
|
||||
memcpy(_jurisdictionRoot.get(), other._jurisdictionRoot.get(), bytes);
|
||||
}
|
||||
for (size_t i = 0; i < other._jurisdictionEndNodes.size(); i++) {
|
||||
auto& endNodeCode = other._jurisdictionEndNodes[i];
|
||||
if (endNodeCode) {
|
||||
auto bytes = bytesRequiredForCodeLength(numberOfThreeBitSectionsInCode(endNodeCode.get()));
|
||||
auto endNodeCodeCopy = createOctalCodePtr(bytes);
|
||||
memcpy(endNodeCodeCopy.get(), endNodeCode.get(), bytes);
|
||||
_jurisdictionEndNodes.push_back(endNodeCodeCopy);
|
||||
}
|
||||
}
|
||||
|
||||
_incomingPacket = other._incomingPacket;
|
||||
_incomingBytes = other._incomingBytes;
|
||||
_incomingWastedBytes = other._incomingWastedBytes;
|
||||
|
@ -141,8 +119,7 @@ OctreeSceneStats::~OctreeSceneStats() {
|
|||
reset();
|
||||
}
|
||||
|
||||
void OctreeSceneStats::sceneStarted(bool isFullScene, bool isMoving, const OctreeElementPointer& root,
|
||||
JurisdictionMap* jurisdictionMap) {
|
||||
void OctreeSceneStats::sceneStarted(bool isFullScene, bool isMoving, const OctreeElementPointer& root) {
|
||||
reset(); // resets packet and octree stats
|
||||
_isStarted = true;
|
||||
_start = usecTimestampNow();
|
||||
|
@ -153,14 +130,6 @@ void OctreeSceneStats::sceneStarted(bool isFullScene, bool isMoving, const Octre
|
|||
|
||||
_isFullScene = isFullScene;
|
||||
_isMoving = isMoving;
|
||||
|
||||
// setup jurisdictions
|
||||
if (jurisdictionMap) {
|
||||
std::tie(_jurisdictionRoot, _jurisdictionEndNodes) = jurisdictionMap->getRootAndEndNodeOctalCodes();
|
||||
} else {
|
||||
_jurisdictionRoot = nullptr;
|
||||
_jurisdictionEndNodes.clear();
|
||||
}
|
||||
}
|
||||
|
||||
void OctreeSceneStats::sceneCompleted() {
|
||||
|
@ -236,9 +205,6 @@ void OctreeSceneStats::reset() {
|
|||
_existsBitsWritten = 0;
|
||||
_existsInPacketBitsWritten = 0;
|
||||
_treesRemoved = 0;
|
||||
|
||||
_jurisdictionRoot = nullptr;
|
||||
_jurisdictionEndNodes.clear();
|
||||
}
|
||||
|
||||
void OctreeSceneStats::packetSent(int bytes) {
|
||||
|
@ -374,29 +340,6 @@ int OctreeSceneStats::packIntoPacket() {
|
|||
_statsPacket->writePrimitive(_existsInPacketBitsWritten);
|
||||
_statsPacket->writePrimitive(_treesRemoved);
|
||||
|
||||
// add the root jurisdiction
|
||||
if (_jurisdictionRoot) {
|
||||
// copy the
|
||||
int bytes = (int)bytesRequiredForCodeLength(numberOfThreeBitSectionsInCode(_jurisdictionRoot.get()));
|
||||
_statsPacket->writePrimitive(bytes);
|
||||
_statsPacket->write(reinterpret_cast<char*>(_jurisdictionRoot.get()), bytes);
|
||||
|
||||
// if and only if there's a root jurisdiction, also include the end elements
|
||||
int endNodeCount = (int)_jurisdictionEndNodes.size();
|
||||
|
||||
_statsPacket->writePrimitive(endNodeCount);
|
||||
|
||||
for (int i=0; i < endNodeCount; i++) {
|
||||
auto& endNodeCode = _jurisdictionEndNodes[i];
|
||||
auto bytes = bytesRequiredForCodeLength(numberOfThreeBitSectionsInCode(endNodeCode.get()));
|
||||
_statsPacket->writePrimitive(bytes);
|
||||
_statsPacket->write(reinterpret_cast<char*>(endNodeCode.get()), bytes);
|
||||
}
|
||||
} else {
|
||||
int bytes = 0;
|
||||
_statsPacket->writePrimitive(bytes);
|
||||
}
|
||||
|
||||
return _statsPacket->getPayloadSize();
|
||||
}
|
||||
|
||||
|
@ -458,38 +401,6 @@ int OctreeSceneStats::unpackFromPacket(ReceivedMessage& packet) {
|
|||
packet.readPrimitive(&_existsBitsWritten);
|
||||
packet.readPrimitive(&_existsInPacketBitsWritten);
|
||||
packet.readPrimitive(&_treesRemoved);
|
||||
// before allocating new juridiction, clean up existing ones
|
||||
_jurisdictionRoot = nullptr;
|
||||
_jurisdictionEndNodes.clear();
|
||||
|
||||
// read the root jurisdiction
|
||||
int bytes = 0;
|
||||
packet.readPrimitive(&bytes);
|
||||
|
||||
if (bytes == 0) {
|
||||
_jurisdictionRoot = nullptr;
|
||||
_jurisdictionEndNodes.clear();
|
||||
} else {
|
||||
_jurisdictionRoot = createOctalCodePtr(bytes);
|
||||
packet.read(reinterpret_cast<char*>(_jurisdictionRoot.get()), bytes);
|
||||
|
||||
// if and only if there's a root jurisdiction, also include the end elements
|
||||
_jurisdictionEndNodes.clear();
|
||||
|
||||
int endNodeCount = 0;
|
||||
packet.readPrimitive(&endNodeCount);
|
||||
|
||||
for (int i=0; i < endNodeCount; i++) {
|
||||
int bytes = 0;
|
||||
|
||||
packet.readPrimitive(&bytes);
|
||||
|
||||
auto endNodeCode = createOctalCodePtr(bytes);
|
||||
packet.read(reinterpret_cast<char*>(endNodeCode.get()), bytes);
|
||||
|
||||
_jurisdictionEndNodes.push_back(endNodeCode);
|
||||
}
|
||||
}
|
||||
|
||||
// running averages
|
||||
_elapsedAverage.updateAverage((float)_elapsed);
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
#include <NodeList.h>
|
||||
#include <shared/ReadWriteLockable.h>
|
||||
|
||||
#include "JurisdictionMap.h"
|
||||
#include "OctreePacketData.h"
|
||||
#include "SequenceNumberStats.h"
|
||||
#include "OctalCode.h"
|
||||
|
@ -39,7 +38,7 @@ public:
|
|||
OctreeSceneStats& operator= (const OctreeSceneStats& other); // copy assignment
|
||||
|
||||
/// Call when beginning the computation of a scene. Initializes internal structures
|
||||
void sceneStarted(bool fullScene, bool moving, const OctreeElementPointer& root, JurisdictionMap* jurisdictionMap);
|
||||
void sceneStarted(bool fullScene, bool moving, const OctreeElementPointer& root);
|
||||
bool getIsSceneStarted() const { return _isStarted; }
|
||||
|
||||
/// Call when the computation of a scene is completed. Finalizes internal structures
|
||||
|
@ -143,12 +142,6 @@ public:
|
|||
/// \param Item item The item from the stats you're interested in.
|
||||
const char* getItemValue(Item item);
|
||||
|
||||
/// Returns OctCode for root element of the jurisdiction of this particular octree server
|
||||
OctalCodePtr getJurisdictionRoot() const { return _jurisdictionRoot; }
|
||||
|
||||
/// Returns list of OctCodes for end elements of the jurisdiction of this particular octree server
|
||||
const OctalCodePtrList& getJurisdictionEndNodes() const { return _jurisdictionEndNodes; }
|
||||
|
||||
bool isMoving() const { return _isMoving; }
|
||||
bool isFullScene() const { return _isFullScene; }
|
||||
quint64 getTotalElements() const { return _totalElements; }
|
||||
|
@ -277,9 +270,6 @@ private:
|
|||
static ItemInfo _ITEMS[];
|
||||
static const int MAX_ITEM_VALUE_LENGTH = 128;
|
||||
char _itemValueBuffer[MAX_ITEM_VALUE_LENGTH];
|
||||
|
||||
OctalCodePtr _jurisdictionRoot;
|
||||
std::vector<OctalCodePtr> _jurisdictionEndNodes;
|
||||
};
|
||||
|
||||
/// Map between element IDs and their reported OctreeSceneStats. Typically used by classes that need to know which elements sent
|
||||
|
|
|
@ -13,12 +13,9 @@
|
|||
|
||||
#include "OctreeScriptingInterface.h"
|
||||
|
||||
OctreeScriptingInterface::OctreeScriptingInterface(OctreeEditPacketSender* packetSender,
|
||||
JurisdictionListener* jurisdictionListener) :
|
||||
OctreeScriptingInterface::OctreeScriptingInterface(OctreeEditPacketSender* packetSender) :
|
||||
_packetSender(packetSender),
|
||||
_jurisdictionListener(jurisdictionListener),
|
||||
_managedPacketSender(false),
|
||||
_managedJurisdictionListener(false),
|
||||
_managedPacketSender(false),
|
||||
_initialized(false)
|
||||
{
|
||||
}
|
||||
|
@ -28,12 +25,6 @@ OctreeScriptingInterface::~OctreeScriptingInterface() {
|
|||
}
|
||||
|
||||
void OctreeScriptingInterface::cleanupManagedObjects() {
|
||||
if (_managedJurisdictionListener) {
|
||||
_jurisdictionListener->terminate();
|
||||
_jurisdictionListener->deleteLater();
|
||||
_managedJurisdictionListener = false;
|
||||
_jurisdictionListener = NULL;
|
||||
}
|
||||
if (_managedPacketSender) {
|
||||
_packetSender->terminate();
|
||||
_packetSender->deleteLater();
|
||||
|
@ -46,29 +37,16 @@ void OctreeScriptingInterface::setPacketSender(OctreeEditPacketSender* packetSen
|
|||
_packetSender = packetSender;
|
||||
}
|
||||
|
||||
void OctreeScriptingInterface::setJurisdictionListener(JurisdictionListener* jurisdictionListener) {
|
||||
_jurisdictionListener = jurisdictionListener;
|
||||
}
|
||||
|
||||
void OctreeScriptingInterface::init() {
|
||||
if (_initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (_jurisdictionListener) {
|
||||
_managedJurisdictionListener = false;
|
||||
} else {
|
||||
_managedJurisdictionListener = true;
|
||||
_jurisdictionListener = new JurisdictionListener(getServerNodeType());
|
||||
_jurisdictionListener->initialize(true);
|
||||
}
|
||||
|
||||
if (_packetSender) {
|
||||
_managedPacketSender = false;
|
||||
} else {
|
||||
_managedPacketSender = true;
|
||||
_packetSender = createPacketSender();
|
||||
_packetSender->setServerJurisdictions(_jurisdictionListener->getJurisdictions());
|
||||
}
|
||||
|
||||
if (QCoreApplication::instance()) {
|
||||
|
|
|
@ -14,21 +14,18 @@
|
|||
|
||||
#include <QtCore/QObject>
|
||||
|
||||
#include "JurisdictionListener.h"
|
||||
#include "OctreeEditPacketSender.h"
|
||||
|
||||
/// handles scripting of Particle commands from JS passed to assigned clients
|
||||
class OctreeScriptingInterface : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
OctreeScriptingInterface(OctreeEditPacketSender* packetSender = NULL, JurisdictionListener* jurisdictionListener = NULL);
|
||||
OctreeScriptingInterface(OctreeEditPacketSender* packetSender = nullptr);
|
||||
|
||||
~OctreeScriptingInterface();
|
||||
|
||||
OctreeEditPacketSender* getPacketSender() const { return _packetSender; }
|
||||
JurisdictionListener* getJurisdictionListener() const { return _jurisdictionListener; }
|
||||
void setPacketSender(OctreeEditPacketSender* packetSender);
|
||||
void setJurisdictionListener(JurisdictionListener* jurisdictionListener);
|
||||
void init();
|
||||
|
||||
virtual NodeType_t getServerNodeType() const = 0;
|
||||
|
@ -86,9 +83,7 @@ public slots:
|
|||
protected:
|
||||
/// attached OctreeEditPacketSender that handles queuing and sending of packets to VS
|
||||
OctreeEditPacketSender* _packetSender = nullptr;
|
||||
JurisdictionListener* _jurisdictionListener = nullptr;
|
||||
bool _managedPacketSender;
|
||||
bool _managedJurisdictionListener;
|
||||
bool _initialized;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue