mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 04:44:11 +02:00
Fix JurisdictionMap multithreading issues
Make octal code pointers use shared_ptr, add locks around access.
This commit is contained in:
parent
34e574c148
commit
ef6d758e7f
9 changed files with 138 additions and 216 deletions
|
@ -3656,11 +3656,11 @@ void Application::queryOctree(NodeType_t serverType, PacketType packetType, Node
|
|||
} else {
|
||||
const JurisdictionMap& map = (jurisdictions)[nodeUUID];
|
||||
|
||||
unsigned char* rootCode = map.getRootOctalCode();
|
||||
auto rootCode = map.getRootOctalCode();
|
||||
|
||||
if (rootCode) {
|
||||
VoxelPositionSize rootDetails;
|
||||
voxelDetailsForCode(rootCode, 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),
|
||||
|
@ -3720,11 +3720,11 @@ void Application::queryOctree(NodeType_t serverType, PacketType packetType, Node
|
|||
} else {
|
||||
const JurisdictionMap& map = (jurisdictions)[nodeUUID];
|
||||
|
||||
unsigned char* rootCode = map.getRootOctalCode();
|
||||
auto rootCode = map.getRootOctalCode();
|
||||
|
||||
if (rootCode) {
|
||||
VoxelPositionSize rootDetails;
|
||||
voxelDetailsForCode(rootCode, 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),
|
||||
|
@ -4251,9 +4251,9 @@ void Application::nodeKilled(SharedNodePointer node) {
|
|||
return;
|
||||
}
|
||||
|
||||
unsigned char* rootCode = _entityServerJurisdictions[nodeUUID].getRootOctalCode();
|
||||
auto rootCode = _entityServerJurisdictions[nodeUUID].getRootOctalCode();
|
||||
VoxelPositionSize rootDetails;
|
||||
voxelDetailsForCode(rootCode, rootDetails);
|
||||
voxelDetailsForCode(rootCode.get(), rootDetails);
|
||||
|
||||
qCDebug(interfaceapp, "model server going away...... v[%f, %f, %f, %f]",
|
||||
(double)rootDetails.x, (double)rootDetails.y, (double)rootDetails.z, (double)rootDetails.s);
|
||||
|
@ -4378,7 +4378,7 @@ int Application::processOctreeStats(ReceivedMessage& message, SharedNodePointer
|
|||
}
|
||||
|
||||
VoxelPositionSize rootDetails;
|
||||
voxelDetailsForCode(octreeStats.getJurisdictionRoot(), rootDetails);
|
||||
voxelDetailsForCode(octreeStats.getJurisdictionRoot().get(), rootDetails);
|
||||
|
||||
qCDebug(interfaceapp, "stats from new %s server... [%f, %f, %f, %f]",
|
||||
qPrintable(serverType),
|
||||
|
|
|
@ -433,13 +433,13 @@ void OctreeStatsDialog::showOctreeServersOfType(int& serverCount, NodeType_t ser
|
|||
}
|
||||
const JurisdictionMap& map = serverJurisdictions[nodeUUID];
|
||||
|
||||
unsigned char* rootCode = map.getRootOctalCode();
|
||||
auto rootCode = map.getRootOctalCode();
|
||||
|
||||
if (rootCode) {
|
||||
QString rootCodeHex = octalCodeToHexString(rootCode);
|
||||
QString rootCodeHex = octalCodeToHexString(rootCode.get());
|
||||
|
||||
VoxelPositionSize rootDetails;
|
||||
voxelDetailsForCode(rootCode, rootDetails);
|
||||
voxelDetailsForCode(rootCode.get(), rootDetails);
|
||||
AACube serverBounds(glm::vec3(rootDetails.x, rootDetails.y, rootDetails.z), rootDetails.s);
|
||||
serverDetails << " jurisdiction: "
|
||||
<< qPrintable(rootCodeHex)
|
||||
|
|
|
@ -17,90 +17,11 @@
|
|||
#include <DependencyManager.h>
|
||||
#include <NodeList.h>
|
||||
#include <udt/PacketHeaders.h>
|
||||
#include <OctalCode.h>
|
||||
|
||||
#include "OctreeLogging.h"
|
||||
#include "JurisdictionMap.h"
|
||||
|
||||
|
||||
// standard assignment
|
||||
// copy assignment
|
||||
JurisdictionMap& JurisdictionMap::operator=(const JurisdictionMap& other) {
|
||||
copyContents(other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Copy constructor
|
||||
JurisdictionMap::JurisdictionMap(const JurisdictionMap& other) : _rootOctalCode(NULL) {
|
||||
copyContents(other);
|
||||
}
|
||||
|
||||
void JurisdictionMap::copyContents(unsigned char* rootCodeIn, const std::vector<unsigned char*>& endNodesIn) {
|
||||
unsigned char* rootCode;
|
||||
std::vector<unsigned char*> endNodes;
|
||||
if (rootCodeIn) {
|
||||
size_t bytes = bytesRequiredForCodeLength(numberOfThreeBitSectionsInCode(rootCodeIn));
|
||||
rootCode = new unsigned char[bytes];
|
||||
memcpy(rootCode, rootCodeIn, bytes);
|
||||
} else {
|
||||
rootCode = new unsigned char[1];
|
||||
*rootCode = 0;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < endNodesIn.size(); i++) {
|
||||
if (endNodesIn[i]) {
|
||||
size_t bytes = bytesRequiredForCodeLength(numberOfThreeBitSectionsInCode(endNodesIn[i]));
|
||||
unsigned char* endNodeCode = new unsigned char[bytes];
|
||||
memcpy(endNodeCode, endNodesIn[i], bytes);
|
||||
endNodes.push_back(endNodeCode);
|
||||
}
|
||||
}
|
||||
init(rootCode, endNodes);
|
||||
}
|
||||
|
||||
void JurisdictionMap::copyContents(const JurisdictionMap& other) {
|
||||
_nodeType = other._nodeType;
|
||||
copyContents(other._rootOctalCode, other._endNodes);
|
||||
}
|
||||
|
||||
JurisdictionMap::~JurisdictionMap() {
|
||||
clear();
|
||||
}
|
||||
|
||||
void JurisdictionMap::clear() {
|
||||
if (_rootOctalCode) {
|
||||
delete[] _rootOctalCode;
|
||||
_rootOctalCode = NULL;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < _endNodes.size(); i++) {
|
||||
if (_endNodes[i]) {
|
||||
delete[] _endNodes[i];
|
||||
}
|
||||
}
|
||||
_endNodes.clear();
|
||||
}
|
||||
|
||||
JurisdictionMap::JurisdictionMap(NodeType_t type) : _rootOctalCode(NULL) {
|
||||
_nodeType = type;
|
||||
unsigned char* rootCode = new unsigned char[1];
|
||||
*rootCode = 0;
|
||||
|
||||
std::vector<unsigned char*> emptyEndNodes;
|
||||
init(rootCode, emptyEndNodes);
|
||||
}
|
||||
|
||||
JurisdictionMap::JurisdictionMap(const char* filename) : _rootOctalCode(NULL) {
|
||||
clear(); // clean up our own memory
|
||||
readFromFile(filename);
|
||||
}
|
||||
|
||||
JurisdictionMap::JurisdictionMap(unsigned char* rootOctalCode, const std::vector<unsigned char*>& endNodes)
|
||||
: _rootOctalCode(NULL) {
|
||||
init(rootOctalCode, endNodes);
|
||||
}
|
||||
|
||||
void myDebugoutputBits(unsigned char byte, bool withNewLine) {
|
||||
void myDebugOutputBits(unsigned char byte, bool withNewLine) {
|
||||
if (isalnum(byte)) {
|
||||
printf("[ %d (%c): ", byte, byte);
|
||||
} else {
|
||||
|
@ -117,13 +38,12 @@ void myDebugoutputBits(unsigned char byte, bool withNewLine) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void myDebugPrintOctalCode(const unsigned char* octalCode, bool withNewLine) {
|
||||
if (!octalCode) {
|
||||
printf("NULL");
|
||||
printf("nullptr");
|
||||
} else {
|
||||
for (size_t i = 0; i < bytesRequiredForCodeLength(numberOfThreeBitSectionsInCode(octalCode)); i++) {
|
||||
myDebugoutputBits(octalCode[i],false);
|
||||
myDebugOutputBits(octalCode[i], false);
|
||||
}
|
||||
}
|
||||
if (withNewLine) {
|
||||
|
@ -131,16 +51,53 @@ void myDebugPrintOctalCode(const unsigned char* octalCode, bool withNewLine) {
|
|||
}
|
||||
}
|
||||
|
||||
// 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 std::vector<OctalCodePtr>& endNodesIn) {
|
||||
init(rootCodeIn, endNodesIn);
|
||||
}
|
||||
|
||||
void JurisdictionMap::copyContents(const JurisdictionMap& other) {
|
||||
_nodeType = other._nodeType;
|
||||
|
||||
init(other.getRootOctalCode(), other.getEndNodeOctalCodes());
|
||||
}
|
||||
|
||||
JurisdictionMap::~JurisdictionMap() {
|
||||
}
|
||||
|
||||
JurisdictionMap::JurisdictionMap(NodeType_t type) : _rootOctalCode(nullptr) {
|
||||
_nodeType = type;
|
||||
auto rootCode = std::shared_ptr<unsigned char>(new unsigned char[1], std::default_delete<unsigned char[]>());
|
||||
*rootCode = 0;
|
||||
|
||||
std::vector<OctalCodePtr> 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));
|
||||
_rootOctalCode = std::shared_ptr<unsigned char>(hexStringToOctalCode(QString(rootHexCode)));
|
||||
|
||||
qCDebug(octree, "JurisdictionMap::JurisdictionMap() _rootOctalCode=%p octalCode=", _rootOctalCode);
|
||||
myDebugPrintOctalCode(_rootOctalCode, true);
|
||||
qCDebug(octree, "JurisdictionMap::JurisdictionMap() _rootOctalCode=%p octalCode=", _rootOctalCode.get());
|
||||
myDebugPrintOctalCode(_rootOctalCode.get(), true);
|
||||
|
||||
QString endNodesHexStrings(endNodesHexCodes);
|
||||
QString delimiterPattern(",");
|
||||
|
@ -149,7 +106,7 @@ JurisdictionMap::JurisdictionMap(const char* rootHexCode, const char* endNodesHe
|
|||
for (int i = 0; i < endNodeList.size(); i++) {
|
||||
QString endNodeHexString = endNodeList.at(i);
|
||||
|
||||
unsigned char* endNodeOctcode = hexStringToOctalCode(endNodeHexString);
|
||||
auto endNodeOctcode = hexStringToOctalCode(endNodeHexString);
|
||||
|
||||
qCDebug(octree, "JurisdictionMap::JurisdictionMap() endNodeList(%d)=%s",
|
||||
i, endNodeHexString.toLocal8Bit().constData());
|
||||
|
@ -158,14 +115,14 @@ JurisdictionMap::JurisdictionMap(const char* rootHexCode, const char* endNodesHe
|
|||
_endNodes.push_back(endNodeOctcode);
|
||||
|
||||
qCDebug(octree, "JurisdictionMap::JurisdictionMap() endNodeOctcode=%p octalCode=", endNodeOctcode);
|
||||
myDebugPrintOctalCode(endNodeOctcode, true);
|
||||
myDebugPrintOctalCode(endNodeOctcode.get(), true);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void JurisdictionMap::init(unsigned char* rootOctalCode, const std::vector<unsigned char*>& endNodes) {
|
||||
clear(); // clean up our own memory
|
||||
void JurisdictionMap::init(OctalCodePtr rootOctalCode, const std::vector<OctalCodePtr>& endNodes) {
|
||||
std::lock_guard<std::mutex> lock(_octalCodeMutex);
|
||||
_rootOctalCode = rootOctalCode;
|
||||
_endNodes = endNodes;
|
||||
}
|
||||
|
@ -173,17 +130,19 @@ void JurisdictionMap::init(unsigned char* rootOctalCode, const std::vector<unsig
|
|||
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)) {
|
||||
if (isAncestorOf(nodeOctalCode, _rootOctalCode.get())) {
|
||||
return ABOVE;
|
||||
}
|
||||
|
||||
// otherwise...
|
||||
bool isInJurisdiction = isAncestorOf(_rootOctalCode, nodeOctalCode, childIndex);
|
||||
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], nodeOctalCode);
|
||||
bool isUnderEndNode = isAncestorOf(_endNodes[i].get(), nodeOctalCode);
|
||||
if (isUnderEndNode) {
|
||||
isInJurisdiction = false;
|
||||
break;
|
||||
|
@ -200,8 +159,9 @@ bool JurisdictionMap::readFromFile(const char* filename) {
|
|||
QString rootCode = settings.value("root","00").toString();
|
||||
qCDebug(octree) << "rootCode=" << rootCode;
|
||||
|
||||
_rootOctalCode = hexStringToOctalCode(rootCode);
|
||||
printOctalCode(_rootOctalCode);
|
||||
std::lock_guard<std::mutex> lock(_octalCodeMutex);
|
||||
_rootOctalCode = std::shared_ptr<unsigned char>(hexStringToOctalCode(rootCode));
|
||||
printOctalCode(_rootOctalCode.get());
|
||||
|
||||
settings.beginGroup("endNodes");
|
||||
const QStringList childKeys = settings.childKeys();
|
||||
|
@ -211,8 +171,8 @@ bool JurisdictionMap::readFromFile(const char* filename) {
|
|||
values.insert(childKey, childValue);
|
||||
qCDebug(octree) << childKey << "=" << childValue;
|
||||
|
||||
unsigned char* octcode = hexStringToOctalCode(childValue);
|
||||
printOctalCode(octcode);
|
||||
auto octcode = hexStringToOctalCode(childValue);
|
||||
printOctalCode(octcode.get());
|
||||
|
||||
_endNodes.push_back(octcode);
|
||||
}
|
||||
|
@ -221,30 +181,34 @@ bool JurisdictionMap::readFromFile(const char* filename) {
|
|||
}
|
||||
|
||||
void JurisdictionMap::displayDebugDetails() const {
|
||||
QString rootNodeValue = octalCodeToHexString(_rootOctalCode);
|
||||
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]);
|
||||
QString value = octalCodeToHexString(_endNodes[i].get());
|
||||
qCDebug(octree) << "End node[" << i << "]: " << rootNodeValue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool JurisdictionMap::writeToFile(const char* filename) {
|
||||
std::lock_guard<std::mutex> lock(_octalCodeMutex);
|
||||
|
||||
QString settingsFile(filename);
|
||||
QSettings settings(settingsFile, QSettings::IniFormat);
|
||||
|
||||
|
||||
QString rootNodeValue = octalCodeToHexString(_rootOctalCode);
|
||||
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]);
|
||||
QString value = octalCodeToHexString(_endNodes[i].get());
|
||||
settings.setValue(key, value);
|
||||
}
|
||||
settings.endGroup();
|
||||
|
@ -271,18 +235,19 @@ std::unique_ptr<NLPacket> JurisdictionMap::packIntoPacket() {
|
|||
packet->writePrimitive(type);
|
||||
|
||||
// add the root jurisdiction
|
||||
std::lock_guard<std::mutex> lock(_octalCodeMutex);
|
||||
if (_rootOctalCode) {
|
||||
size_t bytes = bytesRequiredForCodeLength(numberOfThreeBitSectionsInCode(_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), 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++) {
|
||||
unsigned char* endNodeCode = _endNodes[i];
|
||||
auto endNodeCode = _endNodes[i].get();
|
||||
size_t bytes = 0;
|
||||
if (endNodeCode) {
|
||||
bytes = bytesRequiredForCodeLength(numberOfThreeBitSectionsInCode(endNodeCode));
|
||||
|
@ -299,15 +264,17 @@ std::unique_ptr<NLPacket> JurisdictionMap::packIntoPacket() {
|
|||
}
|
||||
|
||||
int JurisdictionMap::unpackFromPacket(ReceivedMessage& message) {
|
||||
clear();
|
||||
|
||||
// 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 = new unsigned char[bytes];
|
||||
message.read(reinterpret_cast<char*>(_rootOctalCode), bytes);
|
||||
_rootOctalCode = std::shared_ptr<unsigned char>(new unsigned char[bytes], std::default_delete<unsigned char[]>());
|
||||
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;
|
||||
|
@ -318,8 +285,8 @@ int JurisdictionMap::unpackFromPacket(ReceivedMessage& message) {
|
|||
message.readPrimitive(&bytes);
|
||||
|
||||
if (bytes <= message.getBytesLeftToRead()) {
|
||||
unsigned char* endNodeCode = new unsigned char[bytes];
|
||||
message.read(reinterpret_cast<char*>(endNodeCode), bytes);
|
||||
auto endNodeCode = std::shared_ptr<unsigned char>(new unsigned char[bytes], std::default_delete<unsigned char[]>());
|
||||
message.read(reinterpret_cast<char*>(endNodeCode.get()), bytes);
|
||||
|
||||
// if the endNodeCode was 0 length then don't add it
|
||||
if (bytes > 0) {
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
#include <NLPacket.h>
|
||||
#include <Node.h>
|
||||
#include <OctalCode.h>
|
||||
|
||||
class JurisdictionMap {
|
||||
public:
|
||||
|
@ -41,7 +42,7 @@ public:
|
|||
|
||||
// application constructors
|
||||
JurisdictionMap(const char* filename);
|
||||
JurisdictionMap(unsigned char* rootOctalCode, const std::vector<unsigned char*>& endNodes);
|
||||
// JurisdictionMap(unsigned char* rootOctalCode, const std::vector<unsigned char*>& endNodes);
|
||||
JurisdictionMap(const char* rootHextString, const char* endNodesHextString);
|
||||
~JurisdictionMap();
|
||||
|
||||
|
@ -50,11 +51,10 @@ public:
|
|||
bool writeToFile(const char* filename);
|
||||
bool readFromFile(const char* filename);
|
||||
|
||||
unsigned char* getRootOctalCode() const { return _rootOctalCode; }
|
||||
unsigned char* getEndNodeOctalCode(int index) const { return _endNodes[index]; }
|
||||
int getEndNodeCount() const { return (int)_endNodes.size(); }
|
||||
OctalCodePtr getRootOctalCode() const { return _rootOctalCode; }
|
||||
std::vector<OctalCodePtr> getEndNodeOctalCodes() const { return _endNodes; }
|
||||
|
||||
void copyContents(unsigned char* rootCodeIn, const std::vector<unsigned char*>& endNodesIn);
|
||||
void copyContents(const OctalCodePtr& rootCodeIn, const std::vector<OctalCodePtr>& endNodesIn);
|
||||
|
||||
int unpackFromPacket(ReceivedMessage& message);
|
||||
std::unique_ptr<NLPacket> packIntoPacket();
|
||||
|
@ -69,11 +69,11 @@ public:
|
|||
|
||||
private:
|
||||
void copyContents(const JurisdictionMap& other); // use assignment instead
|
||||
void clear();
|
||||
void init(unsigned char* rootOctalCode, const std::vector<unsigned char*>& endNodes);
|
||||
void init(OctalCodePtr rootOctalCode, const std::vector<OctalCodePtr>& endNodes);
|
||||
|
||||
unsigned char* _rootOctalCode;
|
||||
std::vector<unsigned char*> _endNodes;
|
||||
mutable std::mutex _octalCodeMutex;
|
||||
OctalCodePtr _rootOctalCode { nullptr };
|
||||
std::vector<OctalCodePtr> _endNodes;
|
||||
NodeType_t _nodeType;
|
||||
};
|
||||
|
||||
|
|
|
@ -78,12 +78,12 @@ void OctreeHeadlessViewer::queryOctree() {
|
|||
}
|
||||
const JurisdictionMap& map = (jurisdictions)[nodeUUID];
|
||||
|
||||
unsigned char* rootCode = map.getRootOctalCode();
|
||||
auto rootCode = map.getRootOctalCode();
|
||||
if (!rootCode) {
|
||||
return;
|
||||
}
|
||||
|
||||
voxelDetailsForCode(rootCode, rootDetails);
|
||||
voxelDetailsForCode(rootCode.get(), rootDetails);
|
||||
foundRootDetails = true;
|
||||
});
|
||||
|
||||
|
@ -146,7 +146,7 @@ void OctreeHeadlessViewer::queryOctree() {
|
|||
}
|
||||
|
||||
const JurisdictionMap& map = (jurisdictions)[nodeUUID];
|
||||
unsigned char* rootCode = map.getRootOctalCode();
|
||||
auto rootCode = map.getRootOctalCode();
|
||||
|
||||
if (!rootCode) {
|
||||
if (wantExtraDebugging) {
|
||||
|
@ -154,7 +154,7 @@ void OctreeHeadlessViewer::queryOctree() {
|
|||
}
|
||||
return;
|
||||
}
|
||||
voxelDetailsForCode(rootCode, rootDetails);
|
||||
voxelDetailsForCode(rootCode.get(), rootDetails);
|
||||
foundRootDetails = true;
|
||||
});
|
||||
|
||||
|
|
|
@ -110,29 +110,21 @@ void OctreeSceneStats::copyFromOther(const OctreeSceneStats& other) {
|
|||
_treesRemoved = other._treesRemoved;
|
||||
|
||||
// before copying the jurisdictions, delete any current values...
|
||||
if (_jurisdictionRoot) {
|
||||
delete[] _jurisdictionRoot;
|
||||
_jurisdictionRoot = NULL;
|
||||
}
|
||||
for (size_t i = 0; i < _jurisdictionEndNodes.size(); i++) {
|
||||
if (_jurisdictionEndNodes[i]) {
|
||||
delete[] _jurisdictionEndNodes[i];
|
||||
}
|
||||
}
|
||||
_jurisdictionRoot = nullptr;
|
||||
_jurisdictionEndNodes.clear();
|
||||
|
||||
// Now copy the values from the other
|
||||
if (other._jurisdictionRoot) {
|
||||
auto bytes = bytesRequiredForCodeLength(numberOfThreeBitSectionsInCode(other._jurisdictionRoot));
|
||||
_jurisdictionRoot = new unsigned char[bytes];
|
||||
memcpy(_jurisdictionRoot, other._jurisdictionRoot, bytes);
|
||||
auto bytes = bytesRequiredForCodeLength(numberOfThreeBitSectionsInCode(other._jurisdictionRoot.get()));
|
||||
_jurisdictionRoot = OctalCodePtr(new unsigned char[bytes]);
|
||||
memcpy(_jurisdictionRoot.get(), other._jurisdictionRoot.get(), bytes);
|
||||
}
|
||||
for (size_t i = 0; i < other._jurisdictionEndNodes.size(); i++) {
|
||||
unsigned char* endNodeCode = other._jurisdictionEndNodes[i];
|
||||
auto& endNodeCode = other._jurisdictionEndNodes[i];
|
||||
if (endNodeCode) {
|
||||
auto bytes = bytesRequiredForCodeLength(numberOfThreeBitSectionsInCode(endNodeCode));
|
||||
unsigned char* endNodeCodeCopy = new unsigned char[bytes];
|
||||
memcpy(endNodeCodeCopy, endNodeCode, bytes);
|
||||
auto bytes = bytesRequiredForCodeLength(numberOfThreeBitSectionsInCode(endNodeCode.get()));
|
||||
auto endNodeCodeCopy = OctalCodePtr(new unsigned char[bytes]);
|
||||
memcpy(endNodeCodeCopy.get(), endNodeCode.get(), bytes);
|
||||
_jurisdictionEndNodes.push_back(endNodeCodeCopy);
|
||||
}
|
||||
}
|
||||
|
@ -162,37 +154,15 @@ void OctreeSceneStats::sceneStarted(bool isFullScene, bool isMoving, OctreeEleme
|
|||
_isFullScene = isFullScene;
|
||||
_isMoving = isMoving;
|
||||
|
||||
if (_jurisdictionRoot) {
|
||||
delete[] _jurisdictionRoot;
|
||||
_jurisdictionRoot = NULL;
|
||||
}
|
||||
_jurisdictionRoot = nullptr;
|
||||
|
||||
// clear existing endNodes before copying new ones...
|
||||
for (size_t i=0; i < _jurisdictionEndNodes.size(); i++) {
|
||||
if (_jurisdictionEndNodes[i]) {
|
||||
delete[] _jurisdictionEndNodes[i];
|
||||
}
|
||||
}
|
||||
_jurisdictionEndNodes.clear();
|
||||
|
||||
// setup jurisdictions
|
||||
if (jurisdictionMap) {
|
||||
unsigned char* jurisdictionRoot = jurisdictionMap->getRootOctalCode();
|
||||
if (jurisdictionRoot) {
|
||||
auto bytes = bytesRequiredForCodeLength(numberOfThreeBitSectionsInCode(jurisdictionRoot));
|
||||
_jurisdictionRoot = new unsigned char[bytes];
|
||||
memcpy(_jurisdictionRoot, jurisdictionRoot, bytes);
|
||||
}
|
||||
|
||||
// copy new endNodes...
|
||||
for (int i = 0; i < jurisdictionMap->getEndNodeCount(); i++) {
|
||||
unsigned char* endNodeCode = jurisdictionMap->getEndNodeOctalCode(i);
|
||||
if (endNodeCode) {
|
||||
auto bytes = bytesRequiredForCodeLength(numberOfThreeBitSectionsInCode(endNodeCode));
|
||||
unsigned char* endNodeCodeCopy = new unsigned char[bytes];
|
||||
memcpy(endNodeCodeCopy, endNodeCode, bytes);
|
||||
_jurisdictionEndNodes.push_back(endNodeCodeCopy);
|
||||
}
|
||||
}
|
||||
_jurisdictionRoot = jurisdictionMap->getRootOctalCode();
|
||||
_jurisdictionEndNodes = jurisdictionMap->getEndNodeOctalCodes();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -270,15 +240,7 @@ void OctreeSceneStats::reset() {
|
|||
_existsInPacketBitsWritten = 0;
|
||||
_treesRemoved = 0;
|
||||
|
||||
if (_jurisdictionRoot) {
|
||||
delete[] _jurisdictionRoot;
|
||||
_jurisdictionRoot = NULL;
|
||||
}
|
||||
for (size_t i = 0; i < _jurisdictionEndNodes.size(); i++) {
|
||||
if (_jurisdictionEndNodes[i]) {
|
||||
delete[] _jurisdictionEndNodes[i];
|
||||
}
|
||||
}
|
||||
_jurisdictionRoot = nullptr;
|
||||
_jurisdictionEndNodes.clear();
|
||||
}
|
||||
|
||||
|
@ -418,9 +380,9 @@ int OctreeSceneStats::packIntoPacket() {
|
|||
// add the root jurisdiction
|
||||
if (_jurisdictionRoot) {
|
||||
// copy the
|
||||
int bytes = (int)bytesRequiredForCodeLength(numberOfThreeBitSectionsInCode(_jurisdictionRoot));
|
||||
int bytes = (int)bytesRequiredForCodeLength(numberOfThreeBitSectionsInCode(_jurisdictionRoot.get()));
|
||||
_statsPacket->writePrimitive(bytes);
|
||||
_statsPacket->write(reinterpret_cast<char*>(_jurisdictionRoot), 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();
|
||||
|
@ -428,10 +390,10 @@ int OctreeSceneStats::packIntoPacket() {
|
|||
_statsPacket->writePrimitive(endNodeCount);
|
||||
|
||||
for (int i=0; i < endNodeCount; i++) {
|
||||
unsigned char* endNodeCode = _jurisdictionEndNodes[i];
|
||||
auto bytes = bytesRequiredForCodeLength(numberOfThreeBitSectionsInCode(endNodeCode));
|
||||
auto& endNodeCode = _jurisdictionEndNodes[i];
|
||||
auto bytes = bytesRequiredForCodeLength(numberOfThreeBitSectionsInCode(endNodeCode.get()));
|
||||
_statsPacket->writePrimitive(bytes);
|
||||
_statsPacket->write(reinterpret_cast<char*>(endNodeCode), bytes);
|
||||
_statsPacket->write(reinterpret_cast<char*>(endNodeCode.get()), bytes);
|
||||
}
|
||||
} else {
|
||||
int bytes = 0;
|
||||
|
@ -500,17 +462,7 @@ int OctreeSceneStats::unpackFromPacket(ReceivedMessage& packet) {
|
|||
packet.readPrimitive(&_existsInPacketBitsWritten);
|
||||
packet.readPrimitive(&_treesRemoved);
|
||||
// before allocating new juridiction, clean up existing ones
|
||||
if (_jurisdictionRoot) {
|
||||
delete[] _jurisdictionRoot;
|
||||
_jurisdictionRoot = NULL;
|
||||
}
|
||||
|
||||
// clear existing endNodes before copying new ones...
|
||||
for (size_t i = 0; i < _jurisdictionEndNodes.size(); i++) {
|
||||
if (_jurisdictionEndNodes[i]) {
|
||||
delete[] _jurisdictionEndNodes[i];
|
||||
}
|
||||
}
|
||||
_jurisdictionRoot = nullptr;
|
||||
_jurisdictionEndNodes.clear();
|
||||
|
||||
// read the root jurisdiction
|
||||
|
@ -518,11 +470,11 @@ int OctreeSceneStats::unpackFromPacket(ReceivedMessage& packet) {
|
|||
packet.readPrimitive(&bytes);
|
||||
|
||||
if (bytes == 0) {
|
||||
_jurisdictionRoot = NULL;
|
||||
_jurisdictionRoot = nullptr;
|
||||
_jurisdictionEndNodes.clear();
|
||||
} else {
|
||||
_jurisdictionRoot = new unsigned char[bytes];
|
||||
packet.read(reinterpret_cast<char*>(_jurisdictionRoot), bytes);
|
||||
_jurisdictionRoot = OctalCodePtr(new unsigned char[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();
|
||||
|
@ -535,8 +487,8 @@ int OctreeSceneStats::unpackFromPacket(ReceivedMessage& packet) {
|
|||
|
||||
packet.readPrimitive(&bytes);
|
||||
|
||||
unsigned char* endNodeCode = new unsigned char[bytes];
|
||||
packet.read(reinterpret_cast<char*>(endNodeCode), bytes);
|
||||
auto endNodeCode = OctalCodePtr(new unsigned char[bytes]);
|
||||
packet.read(reinterpret_cast<char*>(endNodeCode.get()), bytes);
|
||||
|
||||
_jurisdictionEndNodes.push_back(endNodeCode);
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "JurisdictionMap.h"
|
||||
#include "OctreePacketData.h"
|
||||
#include "SequenceNumberStats.h"
|
||||
#include "OctalCode.h"
|
||||
|
||||
#define GREENISH 0x40ff40d0
|
||||
#define YELLOWISH 0xffef40c0
|
||||
|
@ -143,10 +144,10 @@ public:
|
|||
const char* getItemValue(Item item);
|
||||
|
||||
/// Returns OctCode for root element of the jurisdiction of this particular octree server
|
||||
unsigned char* getJurisdictionRoot() const { return _jurisdictionRoot; }
|
||||
OctalCodePtr getJurisdictionRoot() const { return _jurisdictionRoot; }
|
||||
|
||||
/// Returns list of OctCodes for end elements of the jurisdiction of this particular octree server
|
||||
const std::vector<unsigned char*>& getJurisdictionEndNodes() const { return _jurisdictionEndNodes; }
|
||||
const std::vector<OctalCodePtr>& getJurisdictionEndNodes() const { return _jurisdictionEndNodes; }
|
||||
|
||||
bool isMoving() const { return _isMoving; }
|
||||
bool isFullScene() const { return _isFullScene; }
|
||||
|
@ -277,8 +278,8 @@ private:
|
|||
static const int MAX_ITEM_VALUE_LENGTH = 128;
|
||||
char _itemValueBuffer[MAX_ITEM_VALUE_LENGTH];
|
||||
|
||||
unsigned char* _jurisdictionRoot;
|
||||
std::vector<unsigned char*> _jurisdictionEndNodes;
|
||||
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
|
||||
|
|
|
@ -304,14 +304,14 @@ bool isAncestorOf(const unsigned char* possibleAncestor, const unsigned char* po
|
|||
return true;
|
||||
}
|
||||
|
||||
unsigned char* hexStringToOctalCode(const QString& input) {
|
||||
std::shared_ptr<unsigned char> hexStringToOctalCode(const QString& input) {
|
||||
const int HEX_NUMBER_BASE = 16;
|
||||
const int HEX_BYTE_SIZE = 2;
|
||||
int stringIndex = 0;
|
||||
int byteArrayIndex = 0;
|
||||
|
||||
// allocate byte array based on half of string length
|
||||
unsigned char* bytes = new unsigned char[(input.length()) / HEX_BYTE_SIZE];
|
||||
auto bytes = std::shared_ptr<unsigned char>(new unsigned char[(input.length()) / HEX_BYTE_SIZE]);
|
||||
|
||||
// loop through the string - 2 bytes at a time converting
|
||||
// it to decimal equivalent and store in byte array
|
||||
|
@ -321,15 +321,14 @@ unsigned char* hexStringToOctalCode(const QString& input) {
|
|||
if (!ok) {
|
||||
break;
|
||||
}
|
||||
bytes[byteArrayIndex] = (unsigned char)value;
|
||||
bytes.get()[byteArrayIndex] = (unsigned char)value;
|
||||
stringIndex += HEX_BYTE_SIZE;
|
||||
byteArrayIndex++;
|
||||
}
|
||||
|
||||
// something went wrong
|
||||
if (!ok) {
|
||||
delete[] bytes;
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
|
|
@ -12,9 +12,10 @@
|
|||
#ifndef hifi_OctalCode_h
|
||||
#define hifi_OctalCode_h
|
||||
|
||||
#include <string.h>
|
||||
#include <QString>
|
||||
|
||||
#include <memory>
|
||||
|
||||
const int BITS_IN_OCTAL = 3;
|
||||
const int NUMBER_OF_COLORS = 3; // RGB!
|
||||
const int SIZE_OF_COLOR_DATA = NUMBER_OF_COLORS * sizeof(unsigned char); // size in bytes
|
||||
|
@ -22,6 +23,8 @@ const int RED_INDEX = 0;
|
|||
const int GREEN_INDEX = 1;
|
||||
const int BLUE_INDEX = 2;
|
||||
|
||||
using OctalCodePtr = std::shared_ptr<unsigned char>;
|
||||
|
||||
void printOctalCode(const unsigned char* octalCode);
|
||||
size_t bytesRequiredForCodeLength(unsigned char threeBitCodes);
|
||||
int branchIndexWithDescendant(const unsigned char* ancestorOctalCode, const unsigned char* descendantOctalCode);
|
||||
|
@ -58,6 +61,6 @@ typedef enum {
|
|||
OctalCodeComparison compareOctalCodes(const unsigned char* code1, const unsigned char* code2);
|
||||
|
||||
QString octalCodeToHexString(const unsigned char* octalCode);
|
||||
unsigned char* hexStringToOctalCode(const QString& input);
|
||||
std::shared_ptr<unsigned char> hexStringToOctalCode(const QString& input);
|
||||
|
||||
#endif // hifi_OctalCode_h
|
||||
|
|
Loading…
Reference in a new issue