Remove legacy jurisdiction code

This commit is contained in:
Atlante45 2017-12-04 14:43:50 -08:00
parent 4bbce011a4
commit 28f164d7e5
31 changed files with 113 additions and 1519 deletions

View file

@ -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();

View file

@ -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);

View file

@ -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);
}
}

View file

@ -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;

View file

@ -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);

View file

@ -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;

View file

@ -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;

View file

@ -14,7 +14,6 @@
#include <SharedUtil.h>
#include <NodeList.h> // for MAX_PACKET_SIZE
#include <JurisdictionSender.h>
const int MAX_FILENAME_LENGTH = 1024;

View file

@ -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();

View file

@ -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);

View file

@ -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);

View file

@ -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;

View file

@ -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();

View file

@ -48,7 +48,7 @@ protected:
void showAllOctreeServers();
void showOctreeServersOfType(int& serverNumber, NodeType_t serverType,
const char* serverTypeName, NodeToJurisdictionMap& serverJurisdictions);
const char* serverTypeName);
private:

View file

@ -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([&] {

View file

@ -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;

View file

@ -56,8 +56,6 @@ public:
ICEServerPeerInformation,
ICEServerQuery,
OctreeStats,
Jurisdiction,
JurisdictionRequest,
AssignmentClientStatus,
NoisyMute,
AvatarIdentity,

View file

@ -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;
}

View file

@ -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

View file

@ -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
}

View file

@ -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

View file

@ -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;
}

View file

@ -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

View file

@ -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;

View file

@ -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;

View file

@ -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();
}

View file

@ -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

View file

@ -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);

View file

@ -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

View file

@ -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()) {

View file

@ -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;
};