From 874ccf0708d0be16aa4c67ed6c05633ff99ce03f Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 5 Nov 2014 10:57:06 -0800 Subject: [PATCH 01/62] add FindLibcuckoo module and instructions for dropping in libcuckoo --- .gitignore | 4 +++ cmake/modules/FindLibcuckoo.cmake | 29 +++++++++++++++++++ libraries/networking/CMakeLists.txt | 5 +++- .../networking/externals/libcuckoo/readme.txt | 14 +++++++++ 4 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 cmake/modules/FindLibcuckoo.cmake create mode 100644 libraries/networking/externals/libcuckoo/readme.txt diff --git a/.gitignore b/.gitignore index 6e6b69cb66..74a5748b85 100644 --- a/.gitignore +++ b/.gitignore @@ -32,5 +32,9 @@ DerivedData interface/external/*/* !interface/external/*/readme.txt +# ignore libraries externals +libraries/*/externals/*/* +!libraries/*/externals/*/readme.txt + # Ignore interfaceCache for Linux users interface/interfaceCache/ diff --git a/cmake/modules/FindLibcuckoo.cmake b/cmake/modules/FindLibcuckoo.cmake new file mode 100644 index 0000000000..d997f25449 --- /dev/null +++ b/cmake/modules/FindLibcuckoo.cmake @@ -0,0 +1,29 @@ +# FindLibCuckoo.cmake +# +# Try to find libcuckoo. +# +# You can provide a LIBCUCKOO_ROOT_DIR which contains src and include directories +# +# Once done this will define +# +# LIBCUCKOO_FOUND - system found libcuckoo +# LIBCUCKOO_INCLUDE_DIRS - the libcuckoo include directory +# +# Created on 5/11/2014 by Stephen Birarda +# Copyright 2014 High Fidelity, Inc. +# +# Distributed under the Apache License, Version 2.0. +# See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +# + +include("${MACRO_DIR}/HifiLibrarySearchHints.cmake") +hifi_library_search_hints("libcuckoo") + +find_path(LIBCUCKOO_INCLUDE_DIRS cuckoohash_map.hh PATH_SUFFIXES libcuckoo HINTS ${LIBCUCKOO_SEARCH_DIRS}) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args( + libcuckoo + "Could NOT find libcuckoo. Read libraries/networking/externals/libcuckoo/readme.txt" + LIBCUCKOO_INCLUDE_DIRS +) \ No newline at end of file diff --git a/libraries/networking/CMakeLists.txt b/libraries/networking/CMakeLists.txt index 50f41fe643..cf68bc464a 100644 --- a/libraries/networking/CMakeLists.txt +++ b/libraries/networking/CMakeLists.txt @@ -10,9 +10,12 @@ if (WIN32) target_link_libraries(${TARGET_NAME} ws2_32.lib) endif () -# find OpenSSL +# find required dependencies find_package(OpenSSL REQUIRED) +list(APPEND LIBCUCKOO_ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/externals/libcuckoo") +find_package(libcuckoo REQUIRED) + if (APPLE AND ${OPENSSL_INCLUDE_DIR} STREQUAL "/usr/include") # this is a user on OS X using system OpenSSL, which is going to throw warnings since they're deprecating for their common crypto message(WARNING "The found version of OpenSSL is the OS X system version. This will produce deprecation warnings." diff --git a/libraries/networking/externals/libcuckoo/readme.txt b/libraries/networking/externals/libcuckoo/readme.txt new file mode 100644 index 0000000000..b86f8bc609 --- /dev/null +++ b/libraries/networking/externals/libcuckoo/readme.txt @@ -0,0 +1,14 @@ + +Instructions for adding the libcuckoo library to Interface +Stephen Birarda, November 5, 2014 + +1. Download the libcuckoo ZIP from the High Fidelity libcuckoo fork on Github. + https://github.com/highfidelity/libcuckoo/archive/master.zip + +2. Copy the libcuckoo folder from inside the ZIP to libraries/networking/externals/libcuckoo/. + + You should have the following structure: + + libraries/networking/externals/libcuckoo/libcuckoo/cuckoohash_map.hh + +3. Delete your build directory, run cmake and build, and you should be all set. From c8aeab53ba5022e062a8237ee8e303e99e345a2b Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 5 Nov 2014 11:42:18 -0800 Subject: [PATCH 02/62] changes for C++11 support --- CMakeLists.txt | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index b421040a50..938375ebc1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -34,6 +34,23 @@ elseif (CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -fno-strict-aliasing") endif(WIN32) +include(CheckCXXCompilerFlag) +CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11) +CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X) + +if (COMPILER_SUPPORTS_CXX11) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") +elseif(COMPILER_SUPPORTS_CXX0X) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x") +else() + message(STATUS "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.") +endif() + +if (APPLE) + set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LANGUAGE_STANDARD "c++0x") + set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "libc++") +endif () + if (NOT QT_CMAKE_PREFIX_PATH) set(QT_CMAKE_PREFIX_PATH $ENV{QT_CMAKE_PREFIX_PATH}) endif () From 3f442039845a7b30fcf554c9820aab2ef3db5e7c Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 5 Nov 2014 11:42:40 -0800 Subject: [PATCH 03/62] remove getpid usage and replace with Qt solution --- libraries/shared/src/LogHandler.cpp | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/libraries/shared/src/LogHandler.cpp b/libraries/shared/src/LogHandler.cpp index a13f3a9dad..6abfd9e787 100644 --- a/libraries/shared/src/LogHandler.cpp +++ b/libraries/shared/src/LogHandler.cpp @@ -12,15 +12,7 @@ #include -#ifdef _WIN32 -#include -#define getpid _getpid -#define getppid _getpid // hack to build -#define pid_t int // hack to build -#elif __linux__ -#include // for getpid() on linux -#endif - +#include #include #include @@ -122,14 +114,8 @@ QString LogHandler::printMessage(LogMsgType type, const QMessageLogContext& cont prefixString.append(QString(" [%1]").arg(dateString)); if (_shouldOutputPID) { - prefixString.append(QString(" [%1").arg(getpid())); + prefixString.append(QString(" [%1]").arg(QCoreApplication::instance()->applicationPid())); - pid_t parentProcessID = getppid(); - if (parentProcessID != 0) { - prefixString.append(QString(":%1]").arg(parentProcessID)); - } else { - prefixString.append("]"); - } } if (!_targetName.isEmpty()) { From 161b3b83d71d6dfb6ff73400dd1196fff1f54d87 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 5 Nov 2014 11:44:56 -0800 Subject: [PATCH 04/62] find an installed version of libcuckoo --- cmake/modules/FindLibcuckoo.cmake | 2 +- libraries/networking/CMakeLists.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake/modules/FindLibcuckoo.cmake b/cmake/modules/FindLibcuckoo.cmake index d997f25449..dad3d8513e 100644 --- a/cmake/modules/FindLibcuckoo.cmake +++ b/cmake/modules/FindLibcuckoo.cmake @@ -19,7 +19,7 @@ include("${MACRO_DIR}/HifiLibrarySearchHints.cmake") hifi_library_search_hints("libcuckoo") -find_path(LIBCUCKOO_INCLUDE_DIRS cuckoohash_map.hh PATH_SUFFIXES libcuckoo HINTS ${LIBCUCKOO_SEARCH_DIRS}) +find_path(LIBCUCKOO_INCLUDE_DIRS libcuckoo/cuckoohash_map.hh PATH_SUFFIXES include HINTS ${LIBCUCKOO_SEARCH_DIRS}) include(FindPackageHandleStandardArgs) find_package_handle_standard_args( diff --git a/libraries/networking/CMakeLists.txt b/libraries/networking/CMakeLists.txt index cf68bc464a..f10b7b2402 100644 --- a/libraries/networking/CMakeLists.txt +++ b/libraries/networking/CMakeLists.txt @@ -22,7 +22,7 @@ if (APPLE AND ${OPENSSL_INCLUDE_DIR} STREQUAL "/usr/include") "\nWe recommend you install a newer version (at least 1.0.1h) in a different directory and set OPENSSL_ROOT_DIR in your env so Cmake can find it.") endif () -include_directories(SYSTEM "${OPENSSL_INCLUDE_DIR}") +include_directories(SYSTEM "${OPENSSL_INCLUDE_DIR}" "${LIBCUCKOO_INCLUDE_DIRS}") # append OpenSSL to our list of libraries to link list(APPEND ${TARGET_NAME}_LIBRARIES_TO_LINK "${OPENSSL_LIBRARIES}") From 118b3133c564a64a547ebcbe2762edee6bc18d68 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 5 Nov 2014 11:45:14 -0800 Subject: [PATCH 05/62] change call to std::abs to abs in SequenceNumberStats --- libraries/networking/src/SequenceNumberStats.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/networking/src/SequenceNumberStats.cpp b/libraries/networking/src/SequenceNumberStats.cpp index f472159164..58c684e16b 100644 --- a/libraries/networking/src/SequenceNumberStats.cpp +++ b/libraries/networking/src/SequenceNumberStats.cpp @@ -68,7 +68,7 @@ SequenceNumberStats::ArrivalInfo SequenceNumberStats::sequenceNumberReceived(qui int expectedInt = (int)expected; // check if the gap between incoming and expected is reasonable, taking possible rollover into consideration - int absGap = std::abs(incomingInt - expectedInt); + int absGap = abs(incomingInt - expectedInt); if (absGap >= UINT16_RANGE - MAX_REASONABLE_SEQUENCE_GAP) { // rollover likely occurred between incoming and expected. // correct the larger of the two so that it's within [-UINT16_RANGE, -1] while the other remains within [0, UINT16_RANGE-1] From bff67077153fc18426b20c62bbc6b5a9c4c88966 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 5 Nov 2014 12:02:05 -0800 Subject: [PATCH 06/62] repair implicit cast of ints into unsigned colorBuffer --- interface/src/ui/TextRenderer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/ui/TextRenderer.cpp b/interface/src/ui/TextRenderer.cpp index 0db1ab5f00..71f10a8603 100644 --- a/interface/src/ui/TextRenderer.cpp +++ b/interface/src/ui/TextRenderer.cpp @@ -128,7 +128,7 @@ int TextRenderer::draw(int x, int y, const char* str) { leftBottom.x, rightTop.y, ls, tt, }; const int NUM_COLOR_SCALARS_PER_GLYPH = 4; - unsigned int colorBuffer[NUM_COLOR_SCALARS_PER_GLYPH] = { compactColor, compactColor, compactColor, compactColor }; + int colorBuffer[NUM_COLOR_SCALARS_PER_GLYPH] = { compactColor, compactColor, compactColor, compactColor }; gpu::Buffer::Size offset = sizeof(vertexBuffer) * _numGlyphsBatched; gpu::Buffer::Size colorOffset = sizeof(colorBuffer) * _numGlyphsBatched; From b8d0bd5d6bb527c0b560c3d3aa9564b433bbf793 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 5 Nov 2014 13:25:32 -0800 Subject: [PATCH 07/62] allow a target to bubble up required includes --- cmake/macros/LinkHifiLibraries.cmake | 4 ++++ cmake/macros/LinkSharedDependencies.cmake | 10 +++++++++- libraries/networking/CMakeLists.txt | 5 ++++- libraries/networking/src/LimitedNodeList.h | 2 ++ 4 files changed, 19 insertions(+), 2 deletions(-) diff --git a/cmake/macros/LinkHifiLibraries.cmake b/cmake/macros/LinkHifiLibraries.cmake index 9d73963fea..a46023fe9a 100644 --- a/cmake/macros/LinkHifiLibraries.cmake +++ b/cmake/macros/LinkHifiLibraries.cmake @@ -29,6 +29,10 @@ macro(LINK_HIFI_LIBRARIES) get_target_property(LINKED_TARGET_DEPENDENCY_LIBRARIES ${HIFI_LIBRARY} DEPENDENCY_LIBRARIES) list(APPEND ${TARGET_NAME}_LIBRARIES_TO_LINK ${LINKED_TARGET_DEPENDENCY_LIBRARIES}) + # ask the library what its include dependencies are and link them + get_target_property(LINKED_TARGET_DEPENDENCY_INCLUDES ${HIFI_LIBRARY} DEPENDENCY_INCLUDES) + list(APPEND ${TARGET_NAME}_DEPENDENCY_INCLUDES ${LINKED_TARGET_DEPENDENCY_INCLUDES}) + endforeach() endmacro(LINK_HIFI_LIBRARIES) \ No newline at end of file diff --git a/cmake/macros/LinkSharedDependencies.cmake b/cmake/macros/LinkSharedDependencies.cmake index ae478ca530..a73f57dc1d 100644 --- a/cmake/macros/LinkSharedDependencies.cmake +++ b/cmake/macros/LinkSharedDependencies.cmake @@ -17,9 +17,17 @@ macro(LINK_SHARED_DEPENDENCIES) target_link_libraries(${TARGET_NAME} ${${TARGET_NAME}_LIBRARIES_TO_LINK}) endif () + if (${TARGET_NAME}_DEPENDENCY_INCLUDES) + list(REMOVE_DUPLICATES ${TARGET_NAME}_DEPENDENCY_INCLUDES) + + # include those in our own target + include_directories(SYSTEM ${${TARGET_NAME}_DEPENDENCY_INCLUDES}) + endif () + # we've already linked our Qt modules, but we need to bubble them up to parents list(APPEND ${TARGET_NAME}_LIBRARIES_TO_LINK "${${TARGET}_QT_MODULES_TO_LINK}") # set the property on this target so it can be retreived by targets linking to us - set_target_properties(${TARGET_NAME} PROPERTIES DEPENDENCY_LIBRARIES "${${TARGET}_LIBRARIES_TO_LINK}") + set_target_properties(${TARGET_NAME} PROPERTIES DEPENDENCY_LIBRARIES "${${TARGET_NAME}_LIBRARIES_TO_LINK}") + set_target_properties(${TARGET_NAME} PROPERTIES DEPENDENCY_INCLUDES "${${TARGET_NAME}_DEPENDENCY_INCLUDES}") endmacro(LINK_SHARED_DEPENDENCIES) \ No newline at end of file diff --git a/libraries/networking/CMakeLists.txt b/libraries/networking/CMakeLists.txt index f10b7b2402..021401853f 100644 --- a/libraries/networking/CMakeLists.txt +++ b/libraries/networking/CMakeLists.txt @@ -22,10 +22,13 @@ if (APPLE AND ${OPENSSL_INCLUDE_DIR} STREQUAL "/usr/include") "\nWe recommend you install a newer version (at least 1.0.1h) in a different directory and set OPENSSL_ROOT_DIR in your env so Cmake can find it.") endif () -include_directories(SYSTEM "${OPENSSL_INCLUDE_DIR}" "${LIBCUCKOO_INCLUDE_DIRS}") +include_directories(SYSTEM "${OPENSSL_INCLUDE_DIR}") # append OpenSSL to our list of libraries to link list(APPEND ${TARGET_NAME}_LIBRARIES_TO_LINK "${OPENSSL_LIBRARIES}") +# append libcuckoo includes to our list of includes to bubble +list(APPEND ${TARGET_NAME}_DEPENDENCY_INCLUDES "${LIBCUCKOO_INCLUDE_DIRS}") + # call macro to link our dependencies and bubble them up via a property on our target link_shared_dependencies() \ No newline at end of file diff --git a/libraries/networking/src/LimitedNodeList.h b/libraries/networking/src/LimitedNodeList.h index 64495fbd34..9e5610ba4e 100644 --- a/libraries/networking/src/LimitedNodeList.h +++ b/libraries/networking/src/LimitedNodeList.h @@ -28,6 +28,8 @@ #include #include +#include + #include "DomainHandler.h" #include "Node.h" From 35d0d31350a0ade1641e2b9d55df2ed697b5c650 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 5 Nov 2014 13:54:38 -0800 Subject: [PATCH 08/62] change the NodeHash to a cuckoohash_map with CityHash --- cmake/modules/FindLibcuckoo.cmake | 9 +++++++ libraries/networking/CMakeLists.txt | 2 +- libraries/networking/src/LimitedNodeList.h | 8 ++++--- libraries/networking/src/UUIDCityHasher.cpp | 12 ++++++++++ libraries/networking/src/UUIDCityHasher.h | 26 +++++++++++++++++++++ 5 files changed, 53 insertions(+), 4 deletions(-) create mode 100644 libraries/networking/src/UUIDCityHasher.cpp create mode 100644 libraries/networking/src/UUIDCityHasher.h diff --git a/cmake/modules/FindLibcuckoo.cmake b/cmake/modules/FindLibcuckoo.cmake index dad3d8513e..4e87c650c2 100644 --- a/cmake/modules/FindLibcuckoo.cmake +++ b/cmake/modules/FindLibcuckoo.cmake @@ -21,9 +21,18 @@ hifi_library_search_hints("libcuckoo") find_path(LIBCUCKOO_INCLUDE_DIRS libcuckoo/cuckoohash_map.hh PATH_SUFFIXES include HINTS ${LIBCUCKOO_SEARCH_DIRS}) +find_library(CITYHASH_LIBRARY_RELEASE NAME cityhash PATH_SUFFIXES lib HINTS ${LIBCUCKOO_SEARCH_DIRS}) +find_library(CITYHASH_LIBRARY_DEBUG NAME cityhash PATH_SUFFIXES lib HINTS ${LIBCUCKOO_SEARCH_DIRS}) + +include(SelectLibraryConfigurations) +select_library_configurations(CITYHASH) + +set(LIBCUCKOO_LIBRARIES ${CITYHASH_LIBRARY}) + include(FindPackageHandleStandardArgs) find_package_handle_standard_args( libcuckoo "Could NOT find libcuckoo. Read libraries/networking/externals/libcuckoo/readme.txt" LIBCUCKOO_INCLUDE_DIRS + LIBCUCKOO_LIBRARIES ) \ No newline at end of file diff --git a/libraries/networking/CMakeLists.txt b/libraries/networking/CMakeLists.txt index 021401853f..b650c0942c 100644 --- a/libraries/networking/CMakeLists.txt +++ b/libraries/networking/CMakeLists.txt @@ -25,7 +25,7 @@ endif () include_directories(SYSTEM "${OPENSSL_INCLUDE_DIR}") # append OpenSSL to our list of libraries to link -list(APPEND ${TARGET_NAME}_LIBRARIES_TO_LINK "${OPENSSL_LIBRARIES}") +list(APPEND ${TARGET_NAME}_LIBRARIES_TO_LINK "${OPENSSL_LIBRARIES}" "${LIBCUCKOO_LIBRARIES}") # append libcuckoo includes to our list of includes to bubble list(APPEND ${TARGET_NAME}_DEPENDENCY_INCLUDES "${LIBCUCKOO_INCLUDE_DIRS}") diff --git a/libraries/networking/src/LimitedNodeList.h b/libraries/networking/src/LimitedNodeList.h index 9e5610ba4e..100e3a53ea 100644 --- a/libraries/networking/src/LimitedNodeList.h +++ b/libraries/networking/src/LimitedNodeList.h @@ -26,12 +26,13 @@ #include #include #include -#include +#include #include #include "DomainHandler.h" #include "Node.h" +#include "UUIDCityHasher.h" const int MAX_PACKET_SIZE = 1500; @@ -51,9 +52,10 @@ class HifiSockAddr; typedef QSet NodeSet; typedef QSharedPointer SharedNodePointer; -typedef QHash NodeHash; Q_DECLARE_METATYPE(SharedNodePointer) +typedef cuckoohash_map NodeHash; + typedef quint8 PingType_t; namespace PingType { const PingType_t Agnostic = 0; @@ -159,7 +161,7 @@ protected: void changeSocketBufferSizes(int numBytes); QUuid _sessionUUID; - NodeHash _nodeHash; + cuckoohash_map _nodeHash; QMutex _nodeHashMutex; QUdpSocket _nodeSocket; QUdpSocket* _dtlsSocket; diff --git a/libraries/networking/src/UUIDCityHasher.cpp b/libraries/networking/src/UUIDCityHasher.cpp new file mode 100644 index 0000000000..731e287fc0 --- /dev/null +++ b/libraries/networking/src/UUIDCityHasher.cpp @@ -0,0 +1,12 @@ +// +// UUIDCityHasher.cpp +// libraries/networking/src +// +// Created by Stephen Birarda on 2014-11-05. +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "UUIDCityHasher.h" diff --git a/libraries/networking/src/UUIDCityHasher.h b/libraries/networking/src/UUIDCityHasher.h new file mode 100644 index 0000000000..e27e3bdf1b --- /dev/null +++ b/libraries/networking/src/UUIDCityHasher.h @@ -0,0 +1,26 @@ +// +// UUIDCityHasher.h +// libraries/networking/src +// +// Created by Stephen Birarda on 2014-11-05. +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_UUIDCityHasher_h +#define hifi_UUIDCityHasher_h + +#include + +#include "UUID.h" + +class UUIDCityHasher { +public: + size_t operator()(const QUuid& key) const { + return CityHash64(key.toRfc4122().constData(), NUM_BYTES_RFC4122_UUID); + } +}; + +#endif // hifi_UUIDCityHasher_h \ No newline at end of file From a492abc3a1410e5eaab76e72a203976c925b69ef Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 5 Nov 2014 14:40:56 -0800 Subject: [PATCH 09/62] complete LimitedNodeList changes for new cuckoo hash --- libraries/networking/src/LimitedNodeList.cpp | 133 ++++++------------- libraries/networking/src/LimitedNodeList.h | 9 +- libraries/networking/src/Node.cpp | 48 ++++--- libraries/networking/src/Node.h | 2 + libraries/networking/src/NodeList.cpp | 6 +- 5 files changed, 79 insertions(+), 119 deletions(-) diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index 043f0621bb..0f86719761 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -68,7 +68,6 @@ LimitedNodeList* LimitedNodeList::getInstance() { LimitedNodeList::LimitedNodeList(unsigned short socketListenPort, unsigned short dtlsListenPort) : _sessionUUID(), _nodeHash(), - _nodeHashMutex(QMutex::Recursive), _nodeSocket(this), _dtlsSocket(NULL), _localSockAddr(), @@ -344,18 +343,11 @@ int LimitedNodeList::findNodeAndUpdateWithDataFromPacket(const QByteArray& packe } SharedNodePointer LimitedNodeList::nodeWithUUID(const QUuid& nodeUUID, bool blockingLock) { - const int WAIT_TIME = 10; // wait up to 10ms in the try lock case - SharedNodePointer node; - // if caller wants us to block and guarantee the correct answer, then honor that request - if (blockingLock) { - // this will block till we can get access - QMutexLocker locker(&_nodeHashMutex); - node = _nodeHash.value(nodeUUID); - } else if (_nodeHashMutex.tryLock(WAIT_TIME)) { // some callers are willing to get wrong answers but not block - node = _nodeHash.value(nodeUUID); - _nodeHashMutex.unlock(); + try { + return _nodeHash[nodeUUID]; + } catch (std::out_of_range) { + return SharedNodePointer(); } - return node; } SharedNodePointer LimitedNodeList::sendingNodeForPacket(const QByteArray& packet) { @@ -365,22 +357,15 @@ SharedNodePointer LimitedNodeList::sendingNodeForPacket(const QByteArray& packet return nodeWithUUID(nodeUUID); } -NodeHash LimitedNodeList::getNodeHash() { - QMutexLocker locker(&_nodeHashMutex); - return NodeHash(_nodeHash); -} - void LimitedNodeList::eraseAllNodes() { qDebug() << "Clearing the NodeList. Deleting all nodes in list."; - QMutexLocker locker(&_nodeHashMutex); - - NodeHash::iterator nodeItem = _nodeHash.begin(); - - // iterate the nodes in the list - while (nodeItem != _nodeHash.end()) { - nodeItem = killNodeAtHashIterator(nodeItem); + // iterate the current nodes and note that they are going down + for (auto it = _nodeHash.cbegin(); !it.is_end(); it++) { + emit nodeKilled(it->second); } + + _nodeHash.clear(); } void LimitedNodeList::reset() { @@ -388,20 +373,13 @@ void LimitedNodeList::reset() { } void LimitedNodeList::killNodeWithUUID(const QUuid& nodeUUID) { - QMutexLocker locker(&_nodeHashMutex); - - NodeHash::iterator nodeItemToKill = _nodeHash.find(nodeUUID); - if (nodeItemToKill != _nodeHash.end()) { - killNodeAtHashIterator(nodeItemToKill); + SharedNodePointer matchingNode = nodeWithUUID(nodeUUID); + if (matchingNode) { + emit nodeKilled(matchingNode); + _nodeHash.erase(nodeUUID); } } -NodeHash::iterator LimitedNodeList::killNodeAtHashIterator(NodeHash::iterator& nodeItemToKill) { - qDebug() << "Killed" << *nodeItemToKill.value(); - emit nodeKilled(nodeItemToKill.value()); - return _nodeHash.erase(nodeItemToKill); -} - void LimitedNodeList::processKillNode(const QByteArray& dataByteArray) { // read the node id QUuid nodeUUID = QUuid::fromRfc4122(dataByteArray.mid(numBytesForPacketHeader(dataByteArray), NUM_BYTES_RFC4122_UUID)); @@ -411,62 +389,33 @@ void LimitedNodeList::processKillNode(const QByteArray& dataByteArray) { } SharedNodePointer LimitedNodeList::addOrUpdateNode(const QUuid& uuid, NodeType_t nodeType, - const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket) { - _nodeHashMutex.lock(); - - if (!_nodeHash.contains(uuid)) { - + const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket) { + try { + SharedNodePointer matchingNode = _nodeHash[uuid]; + matchingNode->updateSockets(publicSocket, localSocket); + return matchingNode; + } catch (std::out_of_range) { // we didn't have this node, so add them Node* newNode = new Node(uuid, nodeType, publicSocket, localSocket); SharedNodePointer newNodeSharedPointer(newNode, &QObject::deleteLater); _nodeHash.insert(newNode->getUUID(), newNodeSharedPointer); - _nodeHashMutex.unlock(); - qDebug() << "Added" << *newNode; - + emit nodeAdded(newNodeSharedPointer); - + return newNodeSharedPointer; - } else { - _nodeHashMutex.unlock(); - - return updateSocketsForNode(uuid, publicSocket, localSocket); } } -SharedNodePointer LimitedNodeList::updateSocketsForNode(const QUuid& uuid, - const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket) { - - SharedNodePointer matchingNode = nodeWithUUID(uuid); - - if (matchingNode) { - // perform appropriate updates to this node - QMutexLocker locker(&matchingNode->getMutex()); - - // check if we need to change this node's public or local sockets - if (publicSocket != matchingNode->getPublicSocket()) { - matchingNode->setPublicSocket(publicSocket); - qDebug() << "Public socket change for node" << *matchingNode; - } - - if (localSocket != matchingNode->getLocalSocket()) { - matchingNode->setLocalSocket(localSocket); - qDebug() << "Local socket change for node" << *matchingNode; - } - } - - return matchingNode; -} - unsigned LimitedNodeList::broadcastToNodes(const QByteArray& packet, const NodeSet& destinationNodeTypes) { unsigned n = 0; - - foreach (const SharedNodePointer& node, getNodeHash()) { - // only send to the NodeTypes we are asked to send to. - if (destinationNodeTypes.contains(node->getType())) { - writeDatagram(packet, node); + + SnapshotNodeHash snapshotHash = _nodeHash.snapshot_table(); + for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) { + if (destinationNodeTypes.contains(it->second->getType())) { + writeDatagram(packet, it->second); ++n; } } @@ -510,9 +459,11 @@ QByteArray LimitedNodeList::constructPingReplyPacket(const QByteArray& pingPacke SharedNodePointer LimitedNodeList::soloNodeOfType(char nodeType) { if (memchr(SOLO_NODE_TYPES, nodeType, sizeof(SOLO_NODE_TYPES))) { - foreach (const SharedNodePointer& node, getNodeHash()) { - if (node->getType() == nodeType) { - return node; + SnapshotNodeHash snapshotHash = _nodeHash.snapshot_table(); + + for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) { + if (it->second->getType() == nodeType) { + return it->second; } } } @@ -531,28 +482,20 @@ void LimitedNodeList::resetPacketStats() { } void LimitedNodeList::removeSilentNodes() { - - _nodeHashMutex.lock(); - NodeHash::iterator nodeItem = _nodeHash.begin(); - - while (nodeItem != _nodeHash.end()) { - SharedNodePointer node = nodeItem.value(); - + SnapshotNodeHash snapshotHash = _nodeHash.snapshot_table(); + + for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) { + SharedNodePointer node = it->second; node->getMutex().lock(); - + if ((usecTimestampNow() - node->getLastHeardMicrostamp()) > (NODE_SILENCE_THRESHOLD_MSECS * 1000)) { - // call our private method to kill this node (removes it and emits the right signal) - nodeItem = killNodeAtHashIterator(nodeItem); - } else { - // we didn't kill this node, push the iterator forwards - ++nodeItem; + // call the NodeHash erase to get rid of this node + _nodeHash.erase(it->first); } node->getMutex().unlock(); } - - _nodeHashMutex.unlock(); } const uint32_t RFC_5389_MAGIC_COOKIE = 0x2112A442; diff --git a/libraries/networking/src/LimitedNodeList.h b/libraries/networking/src/LimitedNodeList.h index 100e3a53ea..81daa7ace8 100644 --- a/libraries/networking/src/LimitedNodeList.h +++ b/libraries/networking/src/LimitedNodeList.h @@ -55,6 +55,7 @@ typedef QSharedPointer SharedNodePointer; Q_DECLARE_METATYPE(SharedNodePointer) typedef cuckoohash_map NodeHash; +typedef std::vector > SnapshotNodeHash; typedef quint8 PingType_t; namespace PingType { @@ -95,7 +96,7 @@ public: void(*linkedDataCreateCallback)(Node *); - NodeHash getNodeHash(); + const NodeHash& getNodeHash() { return _nodeHash; } int size() const { return _nodeHash.size(); } SharedNodePointer nodeWithUUID(const QUuid& nodeUUID, bool blockingLock = true); @@ -154,15 +155,11 @@ protected: qint64 writeDatagram(const QByteArray& datagram, const HifiSockAddr& destinationSockAddr, const QUuid& connectionSecret); - - NodeHash::iterator killNodeAtHashIterator(NodeHash::iterator& nodeItemToKill); - void changeSocketBufferSizes(int numBytes); QUuid _sessionUUID; - cuckoohash_map _nodeHash; - QMutex _nodeHashMutex; + NodeHash _nodeHash; QUdpSocket _nodeSocket; QUdpSocket* _dtlsSocket; HifiSockAddr _localSockAddr; diff --git a/libraries/networking/src/Node.cpp b/libraries/networking/src/Node.cpp index c2b35d3b7d..de82dde7f0 100644 --- a/libraries/networking/src/Node.cpp +++ b/libraries/networking/src/Node.cpp @@ -94,30 +94,48 @@ void Node::updateClockSkewUsec(int clockSkewSample) { } void Node::setPublicSocket(const HifiSockAddr& publicSocket) { - if (_activeSocket == &_publicSocket) { - // if the active socket was the public socket then reset it to NULL - _activeSocket = NULL; + if (publicSocket != _publicSocket) { + if (_activeSocket == &_publicSocket) { + // if the active socket was the public socket then reset it to NULL + _activeSocket = NULL; + } + + if (!_publicSocket.isNull()) { + qDebug() << "Public socket change for node" << *this; + } + + _publicSocket = publicSocket; } - - _publicSocket = publicSocket; } void Node::setLocalSocket(const HifiSockAddr& localSocket) { - if (_activeSocket == &_localSocket) { - // if the active socket was the local socket then reset it to NULL - _activeSocket = NULL; + if (localSocket != _localSocket) { + if (_activeSocket == &_localSocket) { + // if the active socket was the local socket then reset it to NULL + _activeSocket = NULL; + } + + if (!_localSocket.isNull()) { + qDebug() << "Local socket change for node" << *this; + } + + _localSocket = localSocket; } - - _localSocket = localSocket; } void Node::setSymmetricSocket(const HifiSockAddr& symmetricSocket) { - if (_activeSocket == &_symmetricSocket) { - // if the active socket was the symmetric socket then reset it to NULL - _activeSocket = NULL; + if (symmetricSocket != _symmetricSocket) { + if (_activeSocket == &_symmetricSocket) { + // if the active socket was the symmetric socket then reset it to NULL + _activeSocket = NULL; + } + + if (!_symmetricSocket.isNull()) { + qDebug() << "Symmetric socket change for node" << *this; + } + + _symmetricSocket = symmetricSocket; } - - _symmetricSocket = symmetricSocket; } void Node::activateLocalSocket() { diff --git a/libraries/networking/src/Node.h b/libraries/networking/src/Node.h index acb6c6f453..05b32d0528 100644 --- a/libraries/networking/src/Node.h +++ b/libraries/networking/src/Node.h @@ -81,6 +81,8 @@ public: const HifiSockAddr& getSymmetricSocket() const { return _symmetricSocket; } virtual void setSymmetricSocket(const HifiSockAddr& symmetricSocket); + void updateSockets(const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket); + const HifiSockAddr* getActiveSocket() const { return _activeSocket; } void activatePublicSocket(); diff --git a/libraries/networking/src/NodeList.cpp b/libraries/networking/src/NodeList.cpp index ff3b86880d..6621a6d2e2 100644 --- a/libraries/networking/src/NodeList.cpp +++ b/libraries/networking/src/NodeList.cpp @@ -449,10 +449,10 @@ void NodeList::pingPunchForInactiveNode(const SharedNodePointer& node) { } void NodeList::pingInactiveNodes() { - foreach (const SharedNodePointer& node, getNodeHash()) { - if (!node->getActiveSocket()) { + for (auto it = _nodeHash.cbegin(); !it.is_end(); it++) { + if (!it->second->getActiveSocket()) { // we don't have an active link to this node, ping it to set that up - pingPunchForInactiveNode(node); + pingPunchForInactiveNode(it->second); } } } From 8a72cdd59d581c8455c7a0d76c494137a3fca10f Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 5 Nov 2014 15:09:54 -0800 Subject: [PATCH 10/62] leverage new libcuckoo hash outside LimitedNodeList --- assignment-client/src/audio/AudioMixer.cpp | 35 ++++++++++++---- assignment-client/src/avatars/AvatarMixer.cpp | 8 +++- .../src/entities/EntityServer.cpp | 11 +++-- .../octree/OctreeInboundPacketProcessor.cpp | 2 +- assignment-client/src/octree/OctreeServer.cpp | 9 ++-- domain-server/src/DomainServer.cpp | 42 ++++++++++++++----- interface/src/Application.cpp | 20 ++++++--- interface/src/MetavoxelSystem.cpp | 13 +++++- .../metavoxels/src/MetavoxelClientManager.cpp | 12 +++++- libraries/networking/src/LimitedNodeList.cpp | 11 +++-- libraries/networking/src/LimitedNodeList.h | 4 +- libraries/networking/src/Node.h | 2 - libraries/octree/src/JurisdictionListener.cpp | 8 ++-- .../octree/src/OctreeEditPacketSender.cpp | 28 ++++++++----- libraries/octree/src/OctreeHeadlessViewer.cpp | 10 +++-- libraries/script-engine/src/ScriptEngine.cpp | 6 ++- 16 files changed, 157 insertions(+), 64 deletions(-) diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index 6ca93a7b11..39011b8083 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -437,7 +437,12 @@ int AudioMixer::prepareMixForListeningNode(Node* node) { // loop through all other nodes that have sufficient audio to mix int streamsMixed = 0; - foreach (const SharedNodePointer& otherNode, NodeList::getInstance()->getNodeHash()) { + + NodeHashSnapshot snapshotHash = NodeList::getInstance()->getNodeHash().snapshot_table(); + + for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) { + SharedNodePointer otherNode = it->second; + if (otherNode->getLinkedData()) { AudioMixerClientData* otherNodeClientData = (AudioMixerClientData*) otherNode->getLinkedData(); @@ -480,7 +485,11 @@ void AudioMixer::readPendingDatagram(const QByteArray& receivedPacket, const Hif QByteArray packet = receivedPacket; populatePacketHeader(packet, PacketTypeMuteEnvironment); - foreach (const SharedNodePointer& node, nodeList->getNodeHash()) { + NodeHashSnapshot snapshotHash = nodeList->getNodeHash().snapshot_table(); + + for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) { + SharedNodePointer node = it->second; + if (node->getType() == NodeType::Agent && node->getActiveSocket() && node->getLinkedData() && node != nodeList->sendingNodeForPacket(receivedPacket)) { nodeList->writeDatagram(packet, packet.size(), node); } @@ -548,8 +557,10 @@ void AudioMixer::sendStatsPacket() { NodeList* nodeList = NodeList::getInstance(); int clientNumber = 0; - foreach (const SharedNodePointer& node, nodeList->getNodeHash()) { - + + NodeHashSnapshot snapshotHash = nodeList->getNodeHash().snapshot_table(); + + for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) { // if we're too large, send the packet if (sizeOfStats > TOO_BIG_FOR_MTU) { nodeList->sendStatsToDomainServer(statsObject2); @@ -559,9 +570,9 @@ void AudioMixer::sendStatsPacket() { } clientNumber++; - AudioMixerClientData* clientData = static_cast(node->getLinkedData()); + AudioMixerClientData* clientData = static_cast(it->second->getLinkedData()); if (clientData) { - QString property = "jitterStats." + node->getUUID().toString(); + QString property = "jitterStats." + it->first.toString(); QString value = clientData->getAudioStreamStatsString(); statsObject2[qPrintable(property)] = value; somethingToSend = true; @@ -706,7 +717,11 @@ void AudioMixer::run() { _lastPerSecondCallbackTime = now; } - foreach (const SharedNodePointer& node, nodeList->getNodeHash()) { + NodeHashSnapshot snapshotHash = nodeList->getNodeHash().snapshot_table(); + + for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) { + SharedNodePointer node = it->second; + if (node->getLinkedData()) { AudioMixerClientData* nodeData = (AudioMixerClientData*)node->getLinkedData(); @@ -873,7 +888,11 @@ void AudioMixer::perSecondActions() { _timeSpentPerHashMatchCallStats.getWindowSum() / WINDOW_LENGTH_USECS * 100.0, _timeSpentPerHashMatchCallStats.getCurrentIntervalSum() / USECS_PER_SECOND * 100.0); - foreach(const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) { + NodeHashSnapshot snapshotHash = NodeList::getInstance()->getNodeHash().snapshot_table(); + + for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) { + SharedNodePointer node = it->second; + if (node->getLinkedData()) { AudioMixerClientData* nodeData = (AudioMixerClientData*)node->getLinkedData(); diff --git a/assignment-client/src/avatars/AvatarMixer.cpp b/assignment-client/src/avatars/AvatarMixer.cpp index 3ec7c5cfbf..3c2fa92c7c 100644 --- a/assignment-client/src/avatars/AvatarMixer.cpp +++ b/assignment-client/src/avatars/AvatarMixer.cpp @@ -122,7 +122,9 @@ void AvatarMixer::broadcastAvatarData() { AvatarMixerClientData* nodeData = NULL; AvatarMixerClientData* otherNodeData = NULL; - foreach (const SharedNodePointer& node, nodeList->getNodeHash()) { + NodeHashSnapshot snapshotHash = nodeList->getNodeHash().snapshot_table(); + for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) { + SharedNodePointer node = it->second; if (node->getLinkedData() && node->getType() == NodeType::Agent && node->getActiveSocket() && (nodeData = reinterpret_cast(node->getLinkedData()))->getMutex().tryLock()) { ++_sumListeners; @@ -135,7 +137,9 @@ void AvatarMixer::broadcastAvatarData() { // this is an AGENT we have received head data from // send back a packet with other active node data to this node - foreach (const SharedNodePointer& otherNode, nodeList->getNodeHash()) { + NodeHashSnapshot snapshotHash = nodeList->getNodeHash().snapshot_table(); + for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) { + SharedNodePointer otherNode = it->second; if (otherNode->getLinkedData() && otherNode->getUUID() != node->getUUID() && (otherNodeData = reinterpret_cast(otherNode->getLinkedData()))->getMutex().tryLock()) { diff --git a/assignment-client/src/entities/EntityServer.cpp b/assignment-client/src/entities/EntityServer.cpp index 2b7d6873cc..31999f91f7 100644 --- a/assignment-client/src/entities/EntityServer.cpp +++ b/assignment-client/src/entities/EntityServer.cpp @@ -123,9 +123,14 @@ void EntityServer::pruneDeletedEntities() { if (tree->hasAnyDeletedEntities()) { quint64 earliestLastDeletedEntitiesSent = usecTimestampNow() + 1; // in the future - foreach (const SharedNodePointer& otherNode, NodeList::getInstance()->getNodeHash()) { - if (otherNode->getLinkedData()) { - EntityNodeData* nodeData = static_cast(otherNode->getLinkedData()); + + NodeHashSnapshot snapshotHash = NodeList::getInstance()->getNodeHash().snapshot_table(); + + for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) { + SharedNodePointer node = it->second; + + if (node->getLinkedData()) { + EntityNodeData* nodeData = static_cast(node->getLinkedData()); quint64 nodeLastDeletedEntitiesSentAt = nodeData->getLastDeletedEntitiesSentAt(); if (nodeLastDeletedEntitiesSentAt < earliestLastDeletedEntitiesSent) { earliestLastDeletedEntitiesSent = nodeLastDeletedEntitiesSentAt; diff --git a/assignment-client/src/octree/OctreeInboundPacketProcessor.cpp b/assignment-client/src/octree/OctreeInboundPacketProcessor.cpp index bd3a7ceee5..b85eb46ebc 100644 --- a/assignment-client/src/octree/OctreeInboundPacketProcessor.cpp +++ b/assignment-client/src/octree/OctreeInboundPacketProcessor.cpp @@ -248,7 +248,7 @@ int OctreeInboundPacketProcessor::sendNackPackets() { continue; } - const SharedNodePointer& destinationNode = NodeList::getInstance()->getNodeHash().value(nodeUUID); + const SharedNodePointer& destinationNode = NodeList::getInstance()->nodeWithUUID(nodeUUID); // retrieve sequence number stats of node, prune its missing set SequenceNumberStats& sequenceNumberStats = nodeStats.getIncomingEditSequenceNumberStats(); diff --git a/assignment-client/src/octree/OctreeServer.cpp b/assignment-client/src/octree/OctreeServer.cpp index 121cac0273..2b38ce3cdd 100644 --- a/assignment-client/src/octree/OctreeServer.cpp +++ b/assignment-client/src/octree/OctreeServer.cpp @@ -1137,9 +1137,12 @@ void OctreeServer::aboutToFinish() { qDebug() << qPrintable(_safeServerName) << "server STARTING about to finish..."; qDebug() << qPrintable(_safeServerName) << "inform Octree Inbound Packet Processor that we are shutting down..."; _octreeInboundPacketProcessor->shuttingDown(); - foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) { - qDebug() << qPrintable(_safeServerName) << "server about to finish while node still connected node:" << *node; - forceNodeShutdown(node); + + NodeHashSnapshot snapshotHash = NodeList::getInstance()->getNodeHash().snapshot_table(); + + for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) { + qDebug() << qPrintable(_safeServerName) << "server about to finish while node still connected node:" << *it->second; + forceNodeShutdown(it->second); } qDebug() << qPrintable(_safeServerName) << "server ENDING about to finish..."; } diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index dbaaca43fa..5dddfd70dd 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -821,7 +821,10 @@ void DomainServer::sendDomainListToNode(const SharedNodePointer& node, const Hif if (nodeData->isAuthenticated()) { // if this authenticated node has any interest types, send back those nodes as well - foreach (const SharedNodePointer& otherNode, nodeList->getNodeHash()) { + NodeHashSnapshot snapshotHash = nodeList->getNodeHash().snapshot_table(); + + for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) { + SharedNodePointer otherNode = it->second; // reset our nodeByteArray and nodeDataStream QByteArray nodeByteArray; @@ -960,7 +963,10 @@ void DomainServer::readAvailableDatagrams() { void DomainServer::setupPendingAssignmentCredits() { // enumerate the NodeList to find the assigned nodes - foreach (const SharedNodePointer& node, LimitedNodeList::getInstance()->getNodeHash()) { + NodeHashSnapshot snapshotHash = NodeList::getInstance()->getNodeHash().snapshot_table(); + + for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) { + SharedNodePointer node = it->second; DomainServerNodeData* nodeData = reinterpret_cast(node->getLinkedData()); if (!nodeData->getAssignmentUUID().isNull() && !nodeData->getWalletUUID().isNull()) { @@ -1119,7 +1125,13 @@ void DomainServer::sendHeartbeatToDataServer(const QString& networkAddress) { // add the number of currently connected agent users int numConnectedAuthedUsers = 0; - foreach(const SharedNodePointer& node, LimitedNodeList::getInstance()->getNodeHash()) { + + NodeHashSnapshot snapshotHash = NodeList::getInstance()->getNodeHash().snapshot_table(); + + for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) { + + SharedNodePointer node = it->second; + if (node->getLinkedData() && !static_cast(node->getLinkedData())->getUsername().isEmpty()) { ++numConnectedAuthedUsers; } @@ -1242,8 +1254,9 @@ void DomainServer::processDatagram(const QByteArray& receivedPacket, const HifiS parseNodeDataFromByteArray(packetStream, throwawayNodeType, nodePublicAddress, nodeLocalAddress, senderSockAddr); - SharedNodePointer checkInNode = nodeList->updateSocketsForNode(nodeUUID, - nodePublicAddress, nodeLocalAddress); + SharedNodePointer checkInNode = nodeList->nodeWithUUID(nodeUUID); + checkInNode->setPublicSocket(nodePublicAddress); + checkInNode->setLocalSocket(nodeLocalAddress); // update last receive to now quint64 timeNow = usecTimestampNow(); @@ -1425,7 +1438,12 @@ bool DomainServer::handleHTTPRequest(HTTPConnection* connection, const QUrl& url QJsonObject assignedNodesJSON; // enumerate the NodeList to find the assigned nodes - foreach (const SharedNodePointer& node, LimitedNodeList::getInstance()->getNodeHash()) { + NodeHashSnapshot snapshotHash = NodeList::getInstance()->getNodeHash().snapshot_table(); + + for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) { + + SharedNodePointer node = it->second; + DomainServerNodeData* nodeData = reinterpret_cast(node->getLinkedData()); if (!nodeData->getAssignmentUUID().isNull()) { @@ -1489,9 +1507,11 @@ bool DomainServer::handleHTTPRequest(HTTPConnection* connection, const QUrl& url // enumerate the NodeList to find the assigned nodes LimitedNodeList* nodeList = LimitedNodeList::getInstance(); - foreach (const SharedNodePointer& node, nodeList->getNodeHash()) { + NodeHashSnapshot snapshotHash = nodeList->getNodeHash().snapshot_table(); + + for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) { // add the node using the UUID as the key - nodesJSONArray.append(jsonObjectForNode(node)); + nodesJSONArray.append(jsonObjectForNode(it->second)); } rootJSON["nodes"] = nodesJSONArray; @@ -2023,8 +2043,10 @@ void DomainServer::addStaticAssignmentsToQueue() { bool foundMatchingAssignment = false; // enumerate the nodes and check if there is one with an attached assignment with matching UUID - foreach (const SharedNodePointer& node, LimitedNodeList::getInstance()->getNodeHash()) { - if (node->getUUID() == staticAssignment->data()->getUUID()) { + NodeHashSnapshot snapshotHash = NodeList::getInstance()->getNodeHash().snapshot_table(); + + for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) { + if (it->first == staticAssignment->data()->getUUID()) { foundMatchingAssignment = true; } } diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 6d8b612bc3..f5842ed4c3 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2405,7 +2405,10 @@ int Application::sendNackPackets() { char packet[MAX_PACKET_SIZE]; // iterates thru all nodes in NodeList - foreach(const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) { + NodeHashSnapshot snapshotHash = NodeList::getInstance()->getNodeHash().snapshot_table(); + + for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) { + SharedNodePointer node = it->second; if (node->getActiveSocket() && ( node->getType() == NodeType::VoxelServer @@ -2503,7 +2506,13 @@ void Application::queryOctree(NodeType_t serverType, PacketType packetType, Node int inViewServers = 0; int unknownJurisdictionServers = 0; - foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) { + NodeList* nodeList = NodeList::getInstance(); + NodeHashSnapshot snapshotHash = nodeList->getNodeHash().snapshot_table(); + + for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) { + + SharedNodePointer node = it->second; + // only send to the NodeTypes that are serverType if (node->getActiveSocket() && node->getType() == serverType) { totalServers++; @@ -2560,10 +2569,9 @@ void Application::queryOctree(NodeType_t serverType, PacketType packetType, Node if (wantExtraDebugging) { qDebug("perServerPPS: %d perUnknownServer: %d", perServerPPS, perUnknownServer); } - - NodeList* nodeList = NodeList::getInstance(); - - foreach (const SharedNodePointer& node, nodeList->getNodeHash()) { + + for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) { + SharedNodePointer node = it->second; // only send to the NodeTypes that are serverType if (node->getActiveSocket() && node->getType() == serverType) { diff --git a/interface/src/MetavoxelSystem.cpp b/interface/src/MetavoxelSystem.cpp index 4c0acc553a..20a7bc906f 100644 --- a/interface/src/MetavoxelSystem.cpp +++ b/interface/src/MetavoxelSystem.cpp @@ -163,7 +163,12 @@ void MetavoxelSystem::render() { } void MetavoxelSystem::refreshVoxelData() { - foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) { + NodeHashSnapshot snapshotHash = NodeList::getInstance()->getNodeHash().snapshot_table(); + + for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) { + + SharedNodePointer node = it->second; + if (node->getType() == NodeType::MetavoxelServer) { QMutexLocker locker(&node->getMutex()); MetavoxelSystemClient* client = static_cast(node->getLinkedData()); @@ -685,7 +690,11 @@ MetavoxelClient* MetavoxelSystem::createClient(const SharedNodePointer& node) { } void MetavoxelSystem::guideToAugmented(MetavoxelVisitor& visitor, bool render) { - foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) { + NodeHashSnapshot snapshotHash = NodeList::getInstance()->getNodeHash().snapshot_table(); + + for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) { + SharedNodePointer node = it->second; + if (node->getType() == NodeType::MetavoxelServer) { QMutexLocker locker(&node->getMutex()); MetavoxelSystemClient* client = static_cast(node->getLinkedData()); diff --git a/libraries/metavoxels/src/MetavoxelClientManager.cpp b/libraries/metavoxels/src/MetavoxelClientManager.cpp index f1c086da67..7765b8cda2 100644 --- a/libraries/metavoxels/src/MetavoxelClientManager.cpp +++ b/libraries/metavoxels/src/MetavoxelClientManager.cpp @@ -42,7 +42,11 @@ SharedObjectPointer MetavoxelClientManager::findFirstRaySpannerIntersection(cons const glm::vec3& direction, const AttributePointer& attribute, float& distance) { SharedObjectPointer closestSpanner; float closestDistance = FLT_MAX; - foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) { + + NodeHashSnapshot snapshotHash = NodeList::getInstance()->getNodeHash().snapshot_table(); + for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) { + SharedNodePointer node = it->second; + if (node->getType() == NodeType::MetavoxelServer) { QMutexLocker locker(&node->getMutex()); MetavoxelClient* client = static_cast(node->getLinkedData()); @@ -115,7 +119,11 @@ MetavoxelClient* MetavoxelClientManager::createClient(const SharedNodePointer& n } void MetavoxelClientManager::guide(MetavoxelVisitor& visitor) { - foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) { + NodeHashSnapshot snapshotHash = NodeList::getInstance()->getNodeHash().snapshot_table(); + + for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) { + SharedNodePointer node = it->second; + if (node->getType() == NodeType::MetavoxelServer) { QMutexLocker locker(&node->getMutex()); MetavoxelClient* client = static_cast(node->getLinkedData()); diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index 0f86719761..5a103076b6 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -392,7 +392,10 @@ SharedNodePointer LimitedNodeList::addOrUpdateNode(const QUuid& uuid, NodeType_t const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket) { try { SharedNodePointer matchingNode = _nodeHash[uuid]; - matchingNode->updateSockets(publicSocket, localSocket); + + matchingNode->setPublicSocket(publicSocket); + matchingNode->setLocalSocket(localSocket); + return matchingNode; } catch (std::out_of_range) { // we didn't have this node, so add them @@ -412,7 +415,7 @@ SharedNodePointer LimitedNodeList::addOrUpdateNode(const QUuid& uuid, NodeType_t unsigned LimitedNodeList::broadcastToNodes(const QByteArray& packet, const NodeSet& destinationNodeTypes) { unsigned n = 0; - SnapshotNodeHash snapshotHash = _nodeHash.snapshot_table(); + NodeHashSnapshot snapshotHash = _nodeHash.snapshot_table(); for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) { if (destinationNodeTypes.contains(it->second->getType())) { writeDatagram(packet, it->second); @@ -459,7 +462,7 @@ QByteArray LimitedNodeList::constructPingReplyPacket(const QByteArray& pingPacke SharedNodePointer LimitedNodeList::soloNodeOfType(char nodeType) { if (memchr(SOLO_NODE_TYPES, nodeType, sizeof(SOLO_NODE_TYPES))) { - SnapshotNodeHash snapshotHash = _nodeHash.snapshot_table(); + NodeHashSnapshot snapshotHash = _nodeHash.snapshot_table(); for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) { if (it->second->getType() == nodeType) { @@ -483,7 +486,7 @@ void LimitedNodeList::resetPacketStats() { void LimitedNodeList::removeSilentNodes() { - SnapshotNodeHash snapshotHash = _nodeHash.snapshot_table(); + NodeHashSnapshot snapshotHash = _nodeHash.snapshot_table(); for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) { SharedNodePointer node = it->second; diff --git a/libraries/networking/src/LimitedNodeList.h b/libraries/networking/src/LimitedNodeList.h index 81daa7ace8..63f93458f3 100644 --- a/libraries/networking/src/LimitedNodeList.h +++ b/libraries/networking/src/LimitedNodeList.h @@ -55,7 +55,7 @@ typedef QSharedPointer SharedNodePointer; Q_DECLARE_METATYPE(SharedNodePointer) typedef cuckoohash_map NodeHash; -typedef std::vector > SnapshotNodeHash; +typedef std::vector > NodeHashSnapshot; typedef quint8 PingType_t; namespace PingType { @@ -104,8 +104,6 @@ public: SharedNodePointer addOrUpdateNode(const QUuid& uuid, NodeType_t nodeType, const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket); - SharedNodePointer updateSocketsForNode(const QUuid& uuid, - const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket); const HifiSockAddr& getLocalSockAddr() const { return _localSockAddr; } diff --git a/libraries/networking/src/Node.h b/libraries/networking/src/Node.h index 05b32d0528..acb6c6f453 100644 --- a/libraries/networking/src/Node.h +++ b/libraries/networking/src/Node.h @@ -81,8 +81,6 @@ public: const HifiSockAddr& getSymmetricSocket() const { return _symmetricSocket; } virtual void setSymmetricSocket(const HifiSockAddr& symmetricSocket); - void updateSockets(const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket); - const HifiSockAddr* getActiveSocket() const { return _activeSocket; } void activatePublicSocket(); diff --git a/libraries/octree/src/JurisdictionListener.cpp b/libraries/octree/src/JurisdictionListener.cpp index f3d9e31acc..606a6c13f2 100644 --- a/libraries/octree/src/JurisdictionListener.cpp +++ b/libraries/octree/src/JurisdictionListener.cpp @@ -40,9 +40,11 @@ bool JurisdictionListener::queueJurisdictionRequest() { NodeList* nodeList = NodeList::getInstance(); - foreach (const SharedNodePointer& node, nodeList->getNodeHash()) { - if (node->getType() == getNodeType() && node->getActiveSocket()) { - _packetSender.queuePacketForSending(node, QByteArray(reinterpret_cast(bufferOut), sizeOut)); + NodeHashSnapshot nodeHashSnapshot = nodeList->getNodeHash().snapshot_table(); + + for (auto it = nodeHashSnapshot.begin(); it != nodeHashSnapshot.end(); it++) { + if (it->second->getType() == getNodeType() && it->second->getActiveSocket()) { + _packetSender.queuePacketForSending(it->second, QByteArray(reinterpret_cast(bufferOut), sizeOut)); nodeCount++; } } diff --git a/libraries/octree/src/OctreeEditPacketSender.cpp b/libraries/octree/src/OctreeEditPacketSender.cpp index 65308f906f..19de2e37e9 100644 --- a/libraries/octree/src/OctreeEditPacketSender.cpp +++ b/libraries/octree/src/OctreeEditPacketSender.cpp @@ -52,12 +52,13 @@ bool OctreeEditPacketSender::serversExist() const { bool hasServers = false; bool atLeastOneJurisdictionMissing = false; // assume the best NodeList* nodeList = NodeList::getInstance(); - - foreach (const SharedNodePointer& node, nodeList->getNodeHash()) { - + + NodeHashSnapshot snapshotHash = nodeList->getNodeHash().snapshot_table(); + for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) { // only send to the NodeTypes that are getMyNodeType() + SharedNodePointer node = it->second; 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) { @@ -86,8 +87,11 @@ void OctreeEditPacketSender::queuePacketToNode(const QUuid& nodeUUID, unsigned c bool wantDebug = false; NodeList* nodeList = NodeList::getInstance(); - - foreach (const SharedNodePointer& node, nodeList->getNodeHash()) { + + NodeHashSnapshot snapshotHash = nodeList->getNodeHash().snapshot_table(); + for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) { + SharedNodePointer node = it->second; + // only send to the NodeTypes that are getMyNodeType() if (node->getType() == getMyNodeType() && ((node->getUUID() == nodeUUID) || (nodeUUID.isNull()))) { @@ -194,8 +198,10 @@ void OctreeEditPacketSender::queuePacketToNodes(unsigned char* buffer, size_t le // 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 - - foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) { + + NodeHashSnapshot snapshotHash = NodeList::getInstance()->getNodeHash().snapshot_table(); + for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) { + SharedNodePointer node = it->second; // only send to the NodeTypes that are getMyNodeType() if (node->getActiveSocket() && node->getType() == getMyNodeType()) { QUuid nodeUUID = node->getUUID(); @@ -249,7 +255,9 @@ void OctreeEditPacketSender::queueOctreeEditMessage(PacketType type, unsigned ch _packetsQueueLock.lock(); - foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) { + NodeHashSnapshot snapshotHash = NodeList::getInstance()->getNodeHash().snapshot_table(); + for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) { + SharedNodePointer node = it->second; // only send to the NodeTypes that are getMyNodeType() if (node->getActiveSocket() && node->getType() == getMyNodeType()) { QUuid nodeUUID = node->getUUID(); @@ -384,7 +392,7 @@ void OctreeEditPacketSender::processNackPacket(const QByteArray& packet) { // retrieve packet from history const QByteArray* packet = sentPacketHistory.getPacket(sequenceNumber); if (packet) { - const SharedNodePointer& node = NodeList::getInstance()->getNodeHash().value(sendingNodeUUID); + const SharedNodePointer& node = NodeList::getInstance()->nodeWithUUID(sendingNodeUUID); queuePacketForSending(node, *packet); } } diff --git a/libraries/octree/src/OctreeHeadlessViewer.cpp b/libraries/octree/src/OctreeHeadlessViewer.cpp index 2f21c7a899..b363c654c1 100644 --- a/libraries/octree/src/OctreeHeadlessViewer.cpp +++ b/libraries/octree/src/OctreeHeadlessViewer.cpp @@ -76,8 +76,10 @@ void OctreeHeadlessViewer::queryOctree() { int totalServers = 0; int inViewServers = 0; int unknownJurisdictionServers = 0; - - foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) { + + NodeHashSnapshot snapshotHash = NodeList::getInstance()->getNodeHash().snapshot_table(); + for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) { + SharedNodePointer node = it->second; // only send to the NodeTypes that are serverType if (node->getActiveSocket() && node->getType() == serverType) { totalServers++; @@ -142,11 +144,11 @@ void OctreeHeadlessViewer::queryOctree() { NodeList* nodeList = NodeList::getInstance(); - foreach (const SharedNodePointer& node, nodeList->getNodeHash()) { + for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) { + SharedNodePointer node = it->second; // 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(); diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index fb98124fc9..340d5b3e20 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -520,7 +520,11 @@ void ScriptEngine::run() { // write audio packet to AudioMixer nodes NodeList* nodeList = NodeList::getInstance(); - foreach(const SharedNodePointer& node, nodeList->getNodeHash()) { + NodeHashSnapshot snapshotHash = nodeList->getNodeHash().snapshot_table(); + + for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) { + SharedNodePointer node = it->second; + // only send to nodes of type AudioMixer if (node->getType() == NodeType::AudioMixer) { // pack sequence number From 63c5dacdd07a93cbb3455c453746aee09a5b5aa7 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 5 Nov 2014 15:12:42 -0800 Subject: [PATCH 11/62] final changes to use new hash from LimitedNodeList --- interface/src/ui/NodeBounds.cpp | 7 +++++-- interface/src/ui/OctreeStatsDialog.cpp | 6 ++++-- interface/src/ui/Stats.cpp | 7 +++++-- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/interface/src/ui/NodeBounds.cpp b/interface/src/ui/NodeBounds.cpp index 49509cc9cf..6298385c90 100644 --- a/interface/src/ui/NodeBounds.cpp +++ b/interface/src/ui/NodeBounds.cpp @@ -53,8 +53,11 @@ void NodeBounds::draw() { float selectedScale = 0; NodeList* nodeList = NodeList::getInstance(); - - foreach (const SharedNodePointer& node, nodeList->getNodeHash()) { + NodeHashSnapshot snapshotHash = nodeList->getNodeHash().snapshot_table(); + + for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) { + SharedNodePointer node = it->second; + NodeType_t nodeType = node->getType(); if (nodeType == NodeType::VoxelServer && _showVoxelNodes) { diff --git a/interface/src/ui/OctreeStatsDialog.cpp b/interface/src/ui/OctreeStatsDialog.cpp index e51b9b1f42..8a6d6442f5 100644 --- a/interface/src/ui/OctreeStatsDialog.cpp +++ b/interface/src/ui/OctreeStatsDialog.cpp @@ -248,8 +248,10 @@ void OctreeStatsDialog::showOctreeServersOfType(int& serverCount, NodeType_t ser QLocale locale(QLocale::English); NodeList* nodeList = NodeList::getInstance(); - - foreach (const SharedNodePointer& node, nodeList->getNodeHash()) { + NodeHashSnapshot snapshotHash = nodeList->getNodeHash().snapshot_table(); + + for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) { + SharedNodePointer node = it->second; // only send to the NodeTypes that are NodeType_t_VOXEL_SERVER if (node->getType() == serverType) { serverCount++; diff --git a/interface/src/ui/Stats.cpp b/interface/src/ui/Stats.cpp index 9bad475838..8e4b900180 100644 --- a/interface/src/ui/Stats.cpp +++ b/interface/src/ui/Stats.cpp @@ -328,8 +328,11 @@ void Stats::display( // Now handle voxel servers, since there could be more than one, we average their ping times unsigned long totalPingVoxel = 0; int voxelServerCount = 0; - - foreach (const SharedNodePointer& node, nodeList->getNodeHash()) { + + NodeHashSnapshot snapshotHash = nodeList->getNodeHash().snapshot_table(); + + for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) { + SharedNodePointer node = it->second; // TODO: this should also support entities if (node->getType() == NodeType::VoxelServer) { totalPingVoxel += node->getPingMs(); From a39ed798aea41f9407bfee66869e77845f659573 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 5 Nov 2014 15:45:51 -0800 Subject: [PATCH 12/62] replace libcuckoo requirement with tbb --- cmake/modules/FindLibcuckoo.cmake | 38 ---- cmake/modules/FindTBB.cmake | 283 ++++++++++++++++++++++++++ libraries/networking/CMakeLists.txt | 8 +- libraries/networking/src/NodeList.cpp | 3 +- 4 files changed, 288 insertions(+), 44 deletions(-) delete mode 100644 cmake/modules/FindLibcuckoo.cmake create mode 100644 cmake/modules/FindTBB.cmake diff --git a/cmake/modules/FindLibcuckoo.cmake b/cmake/modules/FindLibcuckoo.cmake deleted file mode 100644 index 4e87c650c2..0000000000 --- a/cmake/modules/FindLibcuckoo.cmake +++ /dev/null @@ -1,38 +0,0 @@ -# FindLibCuckoo.cmake -# -# Try to find libcuckoo. -# -# You can provide a LIBCUCKOO_ROOT_DIR which contains src and include directories -# -# Once done this will define -# -# LIBCUCKOO_FOUND - system found libcuckoo -# LIBCUCKOO_INCLUDE_DIRS - the libcuckoo include directory -# -# Created on 5/11/2014 by Stephen Birarda -# Copyright 2014 High Fidelity, Inc. -# -# Distributed under the Apache License, Version 2.0. -# See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -# - -include("${MACRO_DIR}/HifiLibrarySearchHints.cmake") -hifi_library_search_hints("libcuckoo") - -find_path(LIBCUCKOO_INCLUDE_DIRS libcuckoo/cuckoohash_map.hh PATH_SUFFIXES include HINTS ${LIBCUCKOO_SEARCH_DIRS}) - -find_library(CITYHASH_LIBRARY_RELEASE NAME cityhash PATH_SUFFIXES lib HINTS ${LIBCUCKOO_SEARCH_DIRS}) -find_library(CITYHASH_LIBRARY_DEBUG NAME cityhash PATH_SUFFIXES lib HINTS ${LIBCUCKOO_SEARCH_DIRS}) - -include(SelectLibraryConfigurations) -select_library_configurations(CITYHASH) - -set(LIBCUCKOO_LIBRARIES ${CITYHASH_LIBRARY}) - -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args( - libcuckoo - "Could NOT find libcuckoo. Read libraries/networking/externals/libcuckoo/readme.txt" - LIBCUCKOO_INCLUDE_DIRS - LIBCUCKOO_LIBRARIES -) \ No newline at end of file diff --git a/cmake/modules/FindTBB.cmake b/cmake/modules/FindTBB.cmake new file mode 100644 index 0000000000..e5ca100391 --- /dev/null +++ b/cmake/modules/FindTBB.cmake @@ -0,0 +1,283 @@ +# Locate Intel Threading Building Blocks include paths and libraries +# FindTBB.cmake can be found at https://code.google.com/p/findtbb/ +# Written by Hannes Hofmann +# Improvements by Gino van den Bergen , +# Florian Uhlig , +# Jiri Marsik + +# The MIT License +# +# Copyright (c) 2011 Hannes Hofmann +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +# GvdB: This module uses the environment variable TBB_ARCH_PLATFORM which defines architecture and compiler. +# e.g. "ia32/vc8" or "em64t/cc4.1.0_libc2.4_kernel2.6.16.21" +# TBB_ARCH_PLATFORM is set by the build script tbbvars[.bat|.sh|.csh], which can be found +# in the TBB installation directory (TBB_INSTALL_DIR). +# +# GvdB: Mac OS X distribution places libraries directly in lib directory. +# +# For backwards compatibility, you may explicitely set the CMake variables TBB_ARCHITECTURE and TBB_COMPILER. +# TBB_ARCHITECTURE [ ia32 | em64t | itanium ] +# which architecture to use +# TBB_COMPILER e.g. vc9 or cc3.2.3_libc2.3.2_kernel2.4.21 or cc4.0.1_os10.4.9 +# which compiler to use (detected automatically on Windows) + +# This module respects +# TBB_INSTALL_DIR or $ENV{TBB21_INSTALL_DIR} or $ENV{TBB_INSTALL_DIR} + +# This module defines +# TBB_INCLUDE_DIRS, where to find task_scheduler_init.h, etc. +# TBB_LIBRARY_DIRS, where to find libtbb, libtbbmalloc +# TBB_DEBUG_LIBRARY_DIRS, where to find libtbb_debug, libtbbmalloc_debug +# TBB_INSTALL_DIR, the base TBB install directory +# TBB_LIBRARIES, the libraries to link against to use TBB. +# TBB_DEBUG_LIBRARIES, the libraries to link against to use TBB with debug symbols. +# TBB_FOUND, If false, don't try to use TBB. +# TBB_INTERFACE_VERSION, as defined in tbb/tbb_stddef.h + + +if (WIN32) + # has em64t/vc8 em64t/vc9 + # has ia32/vc7.1 ia32/vc8 ia32/vc9 + set(_TBB_DEFAULT_INSTALL_DIR "C:/Program Files/Intel/TBB" "C:/Program Files (x86)/Intel/TBB") + set(_TBB_LIB_NAME "tbb") + set(_TBB_LIB_MALLOC_NAME "${_TBB_LIB_NAME}malloc") + set(_TBB_LIB_DEBUG_NAME "${_TBB_LIB_NAME}_debug") + set(_TBB_LIB_MALLOC_DEBUG_NAME "${_TBB_LIB_MALLOC_NAME}_debug") + if (MSVC71) + set (_TBB_COMPILER "vc7.1") + endif(MSVC71) + if (MSVC80) + set(_TBB_COMPILER "vc8") + endif(MSVC80) + if (MSVC90) + set(_TBB_COMPILER "vc9") + endif(MSVC90) + if(MSVC10) + set(_TBB_COMPILER "vc10") + endif(MSVC10) + # Todo: add other Windows compilers such as ICL. + set(_TBB_ARCHITECTURE ${TBB_ARCHITECTURE}) +endif (WIN32) + +if (UNIX) + if (APPLE) + # MAC + set(_TBB_DEFAULT_INSTALL_DIR "/Library/Frameworks/Intel_TBB.framework/Versions") + # libs: libtbb.dylib, libtbbmalloc.dylib, *_debug + set(_TBB_LIB_NAME "tbb") + set(_TBB_LIB_MALLOC_NAME "${_TBB_LIB_NAME}malloc") + set(_TBB_LIB_DEBUG_NAME "${_TBB_LIB_NAME}_debug") + set(_TBB_LIB_MALLOC_DEBUG_NAME "${_TBB_LIB_MALLOC_NAME}_debug") + # default flavor on apple: ia32/cc4.0.1_os10.4.9 + # Jiri: There is no reason to presume there is only one flavor and + # that user's setting of variables should be ignored. + if(NOT TBB_COMPILER) + set(_TBB_COMPILER "cc4.0.1_os10.4.9") + elseif (NOT TBB_COMPILER) + set(_TBB_COMPILER ${TBB_COMPILER}) + endif(NOT TBB_COMPILER) + if(NOT TBB_ARCHITECTURE) + set(_TBB_ARCHITECTURE "ia32") + elseif(NOT TBB_ARCHITECTURE) + set(_TBB_ARCHITECTURE ${TBB_ARCHITECTURE}) + endif(NOT TBB_ARCHITECTURE) + else (APPLE) + # LINUX + set(_TBB_DEFAULT_INSTALL_DIR "/opt/intel/tbb" "/usr/local/include" "/usr/include") + set(_TBB_LIB_NAME "tbb") + set(_TBB_LIB_MALLOC_NAME "${_TBB_LIB_NAME}malloc") + set(_TBB_LIB_DEBUG_NAME "${_TBB_LIB_NAME}_debug") + set(_TBB_LIB_MALLOC_DEBUG_NAME "${_TBB_LIB_MALLOC_NAME}_debug") + # has em64t/cc3.2.3_libc2.3.2_kernel2.4.21 em64t/cc3.3.3_libc2.3.3_kernel2.6.5 em64t/cc3.4.3_libc2.3.4_kernel2.6.9 em64t/cc4.1.0_libc2.4_kernel2.6.16.21 + # has ia32/* + # has itanium/* + set(_TBB_COMPILER ${TBB_COMPILER}) + set(_TBB_ARCHITECTURE ${TBB_ARCHITECTURE}) + endif (APPLE) +endif (UNIX) + +if (CMAKE_SYSTEM MATCHES "SunOS.*") +# SUN +# not yet supported +# has em64t/cc3.4.3_kernel5.10 +# has ia32/* +endif (CMAKE_SYSTEM MATCHES "SunOS.*") + + +#-- Clear the public variables +set (TBB_FOUND "NO") + + +#-- Find TBB install dir and set ${_TBB_INSTALL_DIR} and cached ${TBB_INSTALL_DIR} +# first: use CMake variable TBB_INSTALL_DIR +if (TBB_INSTALL_DIR) + set (_TBB_INSTALL_DIR ${TBB_INSTALL_DIR}) +endif (TBB_INSTALL_DIR) +# second: use environment variable +if (NOT _TBB_INSTALL_DIR) + if (NOT "$ENV{TBB_INSTALL_DIR}" STREQUAL "") + set (_TBB_INSTALL_DIR $ENV{TBB_INSTALL_DIR}) + endif (NOT "$ENV{TBB_INSTALL_DIR}" STREQUAL "") + # Intel recommends setting TBB21_INSTALL_DIR + if (NOT "$ENV{TBB21_INSTALL_DIR}" STREQUAL "") + set (_TBB_INSTALL_DIR $ENV{TBB21_INSTALL_DIR}) + endif (NOT "$ENV{TBB21_INSTALL_DIR}" STREQUAL "") + if (NOT "$ENV{TBB22_INSTALL_DIR}" STREQUAL "") + set (_TBB_INSTALL_DIR $ENV{TBB22_INSTALL_DIR}) + endif (NOT "$ENV{TBB22_INSTALL_DIR}" STREQUAL "") + if (NOT "$ENV{TBB30_INSTALL_DIR}" STREQUAL "") + set (_TBB_INSTALL_DIR $ENV{TBB30_INSTALL_DIR}) + endif (NOT "$ENV{TBB30_INSTALL_DIR}" STREQUAL "") +endif (NOT _TBB_INSTALL_DIR) +# third: try to find path automatically +if (NOT _TBB_INSTALL_DIR) + if (_TBB_DEFAULT_INSTALL_DIR) + set (_TBB_INSTALL_DIR ${_TBB_DEFAULT_INSTALL_DIR}) + endif (_TBB_DEFAULT_INSTALL_DIR) +endif (NOT _TBB_INSTALL_DIR) +# sanity check +if (NOT _TBB_INSTALL_DIR) + message ("ERROR: Unable to find Intel TBB install directory. ${_TBB_INSTALL_DIR}") +else (NOT _TBB_INSTALL_DIR) +# finally: set the cached CMake variable TBB_INSTALL_DIR +if (NOT TBB_INSTALL_DIR) + set (TBB_INSTALL_DIR ${_TBB_INSTALL_DIR} CACHE PATH "Intel TBB install directory") + mark_as_advanced(TBB_INSTALL_DIR) +endif (NOT TBB_INSTALL_DIR) + + +#-- A macro to rewrite the paths of the library. This is necessary, because +# find_library() always found the em64t/vc9 version of the TBB libs +macro(TBB_CORRECT_LIB_DIR var_name) +# if (NOT "${_TBB_ARCHITECTURE}" STREQUAL "em64t") + string(REPLACE em64t "${_TBB_ARCHITECTURE}" ${var_name} ${${var_name}}) +# endif (NOT "${_TBB_ARCHITECTURE}" STREQUAL "em64t") + string(REPLACE ia32 "${_TBB_ARCHITECTURE}" ${var_name} ${${var_name}}) + string(REPLACE vc7.1 "${_TBB_COMPILER}" ${var_name} ${${var_name}}) + string(REPLACE vc8 "${_TBB_COMPILER}" ${var_name} ${${var_name}}) + string(REPLACE vc9 "${_TBB_COMPILER}" ${var_name} ${${var_name}}) + string(REPLACE vc10 "${_TBB_COMPILER}" ${var_name} ${${var_name}}) +endmacro(TBB_CORRECT_LIB_DIR var_content) + + +#-- Look for include directory and set ${TBB_INCLUDE_DIR} +set (TBB_INC_SEARCH_DIR ${_TBB_INSTALL_DIR}/include) +# Jiri: tbbvars now sets the CPATH environment variable to the directory +# containing the headers. +find_path(TBB_INCLUDE_DIR + tbb/task_scheduler_init.h + PATHS ${TBB_INC_SEARCH_DIR} ENV CPATH +) +mark_as_advanced(TBB_INCLUDE_DIR) + + +#-- Look for libraries +# GvdB: $ENV{TBB_ARCH_PLATFORM} is set by the build script tbbvars[.bat|.sh|.csh] +if (NOT $ENV{TBB_ARCH_PLATFORM} STREQUAL "") + set (_TBB_LIBRARY_DIR + ${_TBB_INSTALL_DIR}/lib/$ENV{TBB_ARCH_PLATFORM} + ${_TBB_INSTALL_DIR}/$ENV{TBB_ARCH_PLATFORM}/lib + ) +endif (NOT $ENV{TBB_ARCH_PLATFORM} STREQUAL "") +# Jiri: This block isn't mutually exclusive with the previous one +# (hence no else), instead I test if the user really specified +# the variables in question. +if ((NOT ${TBB_ARCHITECTURE} STREQUAL "") AND (NOT ${TBB_COMPILER} STREQUAL "")) + # HH: deprecated + message(STATUS "[Warning] FindTBB.cmake: The use of TBB_ARCHITECTURE and TBB_COMPILER is deprecated and may not be supported in future versions. Please set \$ENV{TBB_ARCH_PLATFORM} (using tbbvars.[bat|csh|sh]).") + # Jiri: It doesn't hurt to look in more places, so I store the hints from + # ENV{TBB_ARCH_PLATFORM} and the TBB_ARCHITECTURE and TBB_COMPILER + # variables and search them both. + set (_TBB_LIBRARY_DIR "${_TBB_INSTALL_DIR}/${_TBB_ARCHITECTURE}/${_TBB_COMPILER}/lib" ${_TBB_LIBRARY_DIR}) +endif ((NOT ${TBB_ARCHITECTURE} STREQUAL "") AND (NOT ${TBB_COMPILER} STREQUAL "")) + +# GvdB: Mac OS X distribution places libraries directly in lib directory. +list(APPEND _TBB_LIBRARY_DIR ${_TBB_INSTALL_DIR}/lib) + +# Jiri: No reason not to check the default paths. From recent versions, +# tbbvars has started exporting the LIBRARY_PATH and LD_LIBRARY_PATH +# variables, which now point to the directories of the lib files. +# It all makes more sense to use the ${_TBB_LIBRARY_DIR} as a HINTS +# argument instead of the implicit PATHS as it isn't hard-coded +# but computed by system introspection. Searching the LIBRARY_PATH +# and LD_LIBRARY_PATH environment variables is now even more important +# that tbbvars doesn't export TBB_ARCH_PLATFORM and it facilitates +# the use of TBB built from sources. +find_library(TBB_LIBRARY ${_TBB_LIB_NAME} HINTS ${_TBB_LIBRARY_DIR} + PATHS ENV LIBRARY_PATH ENV LD_LIBRARY_PATH) +find_library(TBB_MALLOC_LIBRARY ${_TBB_LIB_MALLOC_NAME} HINTS ${_TBB_LIBRARY_DIR} + PATHS ENV LIBRARY_PATH ENV LD_LIBRARY_PATH) + +#Extract path from TBB_LIBRARY name +get_filename_component(TBB_LIBRARY_DIR ${TBB_LIBRARY} PATH) + +#TBB_CORRECT_LIB_DIR(TBB_LIBRARY) +#TBB_CORRECT_LIB_DIR(TBB_MALLOC_LIBRARY) +mark_as_advanced(TBB_LIBRARY TBB_MALLOC_LIBRARY) + +#-- Look for debug libraries +# Jiri: Changed the same way as for the release libraries. +find_library(TBB_LIBRARY_DEBUG ${_TBB_LIB_DEBUG_NAME} HINTS ${_TBB_LIBRARY_DIR} + PATHS ENV LIBRARY_PATH ENV LD_LIBRARY_PATH) +find_library(TBB_MALLOC_LIBRARY_DEBUG ${_TBB_LIB_MALLOC_DEBUG_NAME} HINTS ${_TBB_LIBRARY_DIR} + PATHS ENV LIBRARY_PATH ENV LD_LIBRARY_PATH) + +# Jiri: Self-built TBB stores the debug libraries in a separate directory. +# Extract path from TBB_LIBRARY_DEBUG name +get_filename_component(TBB_LIBRARY_DEBUG_DIR ${TBB_LIBRARY_DEBUG} PATH) + +#TBB_CORRECT_LIB_DIR(TBB_LIBRARY_DEBUG) +#TBB_CORRECT_LIB_DIR(TBB_MALLOC_LIBRARY_DEBUG) +mark_as_advanced(TBB_LIBRARY_DEBUG TBB_MALLOC_LIBRARY_DEBUG) + + +if (TBB_INCLUDE_DIR) + if (TBB_LIBRARY) + set (TBB_FOUND "YES") + set (TBB_LIBRARIES ${TBB_LIBRARY} ${TBB_MALLOC_LIBRARY} ${TBB_LIBRARIES}) + set (TBB_DEBUG_LIBRARIES ${TBB_LIBRARY_DEBUG} ${TBB_MALLOC_LIBRARY_DEBUG} ${TBB_DEBUG_LIBRARIES}) + set (TBB_INCLUDE_DIRS ${TBB_INCLUDE_DIR} CACHE PATH "TBB include directory" FORCE) + set (TBB_LIBRARY_DIRS ${TBB_LIBRARY_DIR} CACHE PATH "TBB library directory" FORCE) + # Jiri: Self-built TBB stores the debug libraries in a separate directory. + set (TBB_DEBUG_LIBRARY_DIRS ${TBB_LIBRARY_DEBUG_DIR} CACHE PATH "TBB debug library directory" FORCE) + mark_as_advanced(TBB_INCLUDE_DIRS TBB_LIBRARY_DIRS TBB_DEBUG_LIBRARY_DIRS TBB_LIBRARIES TBB_DEBUG_LIBRARIES) + message(STATUS "Found Intel TBB") + endif (TBB_LIBRARY) +endif (TBB_INCLUDE_DIR) + +if (NOT TBB_FOUND) + message("ERROR: Intel TBB NOT found!") + message(STATUS "Looked for Threading Building Blocks in ${_TBB_INSTALL_DIR}") + # do only throw fatal, if this pkg is REQUIRED + if (TBB_FIND_REQUIRED) + message(FATAL_ERROR "Could NOT find TBB library.") + endif (TBB_FIND_REQUIRED) +endif (NOT TBB_FOUND) + +endif (NOT _TBB_INSTALL_DIR) + +if (TBB_FOUND) + set(TBB_INTERFACE_VERSION 0) + FILE(READ "${TBB_INCLUDE_DIRS}/tbb/tbb_stddef.h" _TBB_VERSION_CONTENTS) + STRING(REGEX REPLACE ".*#define TBB_INTERFACE_VERSION ([0-9]+).*" "\\1" TBB_INTERFACE_VERSION "${_TBB_VERSION_CONTENTS}") + set(TBB_INTERFACE_VERSION "${TBB_INTERFACE_VERSION}") +endif (TBB_FOUND) diff --git a/libraries/networking/CMakeLists.txt b/libraries/networking/CMakeLists.txt index b650c0942c..7c8b628183 100644 --- a/libraries/networking/CMakeLists.txt +++ b/libraries/networking/CMakeLists.txt @@ -12,9 +12,7 @@ endif () # find required dependencies find_package(OpenSSL REQUIRED) - -list(APPEND LIBCUCKOO_ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/externals/libcuckoo") -find_package(libcuckoo REQUIRED) +find_package(TBB REQUIRED) if (APPLE AND ${OPENSSL_INCLUDE_DIR} STREQUAL "/usr/include") # this is a user on OS X using system OpenSSL, which is going to throw warnings since they're deprecating for their common crypto @@ -25,10 +23,10 @@ endif () include_directories(SYSTEM "${OPENSSL_INCLUDE_DIR}") # append OpenSSL to our list of libraries to link -list(APPEND ${TARGET_NAME}_LIBRARIES_TO_LINK "${OPENSSL_LIBRARIES}" "${LIBCUCKOO_LIBRARIES}") +list(APPEND ${TARGET_NAME}_LIBRARIES_TO_LINK "${OPENSSL_LIBRARIES}" "${TBB_LIBRARIES}") # append libcuckoo includes to our list of includes to bubble -list(APPEND ${TARGET_NAME}_DEPENDENCY_INCLUDES "${LIBCUCKOO_INCLUDE_DIRS}") +list(APPEND ${TARGET_NAME}_DEPENDENCY_INCLUDES "${TBB_INCLUDE_DIRS}") # call macro to link our dependencies and bubble them up via a property on our target link_shared_dependencies() \ No newline at end of file diff --git a/libraries/networking/src/NodeList.cpp b/libraries/networking/src/NodeList.cpp index 6621a6d2e2..fe8efe42c4 100644 --- a/libraries/networking/src/NodeList.cpp +++ b/libraries/networking/src/NodeList.cpp @@ -449,7 +449,8 @@ void NodeList::pingPunchForInactiveNode(const SharedNodePointer& node) { } void NodeList::pingInactiveNodes() { - for (auto it = _nodeHash.cbegin(); !it.is_end(); it++) { + NodeHashSnapshot snapshotHash = _nodeHash.snapshot_table(); + for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) { if (!it->second->getActiveSocket()) { // we don't have an active link to this node, ping it to set that up pingPunchForInactiveNode(it->second); From e0c4f14c8163f55c4c28abca1fa9df461b256440 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 6 Nov 2014 11:19:16 -0800 Subject: [PATCH 13/62] move networking lib to TBB concurrent_unordered_map --- libraries/networking/src/LimitedNodeList.cpp | 63 ++++++++++---------- libraries/networking/src/LimitedNodeList.h | 63 +++++++++++++++----- libraries/networking/src/NodeList.cpp | 9 ++- libraries/networking/src/UUIDCityHasher.cpp | 12 ---- libraries/networking/src/UUIDCityHasher.h | 26 -------- libraries/networking/src/UUIDHasher.h | 26 ++++++++ 6 files changed, 108 insertions(+), 91 deletions(-) delete mode 100644 libraries/networking/src/UUIDCityHasher.cpp delete mode 100644 libraries/networking/src/UUIDCityHasher.h create mode 100644 libraries/networking/src/UUIDHasher.h diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index 5a103076b6..818d35c0e5 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -21,6 +21,8 @@ #include +#include + #include "AccountManager.h" #include "Assignment.h" #include "HifiSockAddr.h" @@ -342,9 +344,9 @@ int LimitedNodeList::findNodeAndUpdateWithDataFromPacket(const QByteArray& packe return 0; } -SharedNodePointer LimitedNodeList::nodeWithUUID(const QUuid& nodeUUID, bool blockingLock) { +SharedNodePointer LimitedNodeList::nodeWithUUID(const QUuid& nodeUUID) { try { - return _nodeHash[nodeUUID]; + return _nodeHash.at(nodeUUID); } catch (std::out_of_range) { return SharedNodePointer(); } @@ -360,12 +362,12 @@ SharedNodePointer LimitedNodeList::sendingNodeForPacket(const QByteArray& packet void LimitedNodeList::eraseAllNodes() { qDebug() << "Clearing the NodeList. Deleting all nodes in list."; - // iterate the current nodes and note that they are going down - for (auto it = _nodeHash.cbegin(); !it.is_end(); it++) { + // iterate the current nodes, emit that they are dying and remove them from the hash + QWriteLocker writeLock(&_nodeMutex); + for (NodeHash::iterator it = _nodeHash.begin(); it != _nodeHash.end(); ++it) { emit nodeKilled(it->second); + it = _nodeHash.unsafe_erase(it); } - - _nodeHash.clear(); } void LimitedNodeList::reset() { @@ -373,10 +375,13 @@ void LimitedNodeList::reset() { } void LimitedNodeList::killNodeWithUUID(const QUuid& nodeUUID) { - SharedNodePointer matchingNode = nodeWithUUID(nodeUUID); - if (matchingNode) { + NodeHash::iterator it = _nodeHash.find(nodeUUID); + if (it != _nodeHash.end()) { + SharedNodePointer matchingNode = it->second; + + QWriteLocker writeLocker(&_nodeMutex); + _nodeHash.unsafe_erase(it); emit nodeKilled(matchingNode); - _nodeHash.erase(nodeUUID); } } @@ -391,7 +396,7 @@ void LimitedNodeList::processKillNode(const QByteArray& dataByteArray) { SharedNodePointer LimitedNodeList::addOrUpdateNode(const QUuid& uuid, NodeType_t nodeType, const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket) { try { - SharedNodePointer matchingNode = _nodeHash[uuid]; + SharedNodePointer matchingNode = _nodeHash.at(uuid); matchingNode->setPublicSocket(publicSocket); matchingNode->setLocalSocket(localSocket); @@ -402,7 +407,7 @@ SharedNodePointer LimitedNodeList::addOrUpdateNode(const QUuid& uuid, NodeType_t Node* newNode = new Node(uuid, nodeType, publicSocket, localSocket); SharedNodePointer newNodeSharedPointer(newNode, &QObject::deleteLater); - _nodeHash.insert(newNode->getUUID(), newNodeSharedPointer); + _nodeHash.insert(UUIDNodePair(newNode->getUUID(), newNodeSharedPointer)); qDebug() << "Added" << *newNode; @@ -415,13 +420,12 @@ SharedNodePointer LimitedNodeList::addOrUpdateNode(const QUuid& uuid, NodeType_t unsigned LimitedNodeList::broadcastToNodes(const QByteArray& packet, const NodeSet& destinationNodeTypes) { unsigned n = 0; - NodeHashSnapshot snapshotHash = _nodeHash.snapshot_table(); - for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) { - if (destinationNodeTypes.contains(it->second->getType())) { - writeDatagram(packet, it->second); + eachNode([&](const SharedNodePointer& node){ + if (destinationNodeTypes.contains(node->getType())) { + writeDatagram(packet, node); ++n; } - } + }); return n; } @@ -460,17 +464,9 @@ QByteArray LimitedNodeList::constructPingReplyPacket(const QByteArray& pingPacke } SharedNodePointer LimitedNodeList::soloNodeOfType(char nodeType) { - - if (memchr(SOLO_NODE_TYPES, nodeType, sizeof(SOLO_NODE_TYPES))) { - NodeHashSnapshot snapshotHash = _nodeHash.snapshot_table(); - - for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) { - if (it->second->getType() == nodeType) { - return it->second; - } - } - } - return SharedNodePointer(); + return nodeMatchingPredicate([&](const SharedNodePointer& node){ + return node->getType() == nodeType; + }); } void LimitedNodeList::getPacketStats(float& packetsPerSecond, float& bytesPerSecond) { @@ -485,20 +481,21 @@ void LimitedNodeList::resetPacketStats() { } void LimitedNodeList::removeSilentNodes() { - - NodeHashSnapshot snapshotHash = _nodeHash.snapshot_table(); - - for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) { + eachNodeHashIterator([this](NodeHash::iterator& it){ SharedNodePointer node = it->second; node->getMutex().lock(); if ((usecTimestampNow() - node->getLastHeardMicrostamp()) > (NODE_SILENCE_THRESHOLD_MSECS * 1000)) { // call the NodeHash erase to get rid of this node - _nodeHash.erase(it->first); + it = _nodeHash.unsafe_erase(it); + emit nodeKilled(node); + } else { + // we didn't erase this node, push the iterator forwards + ++it; } node->getMutex().unlock(); - } + }); } const uint32_t RFC_5389_MAGIC_COOKIE = 0x2112A442; diff --git a/libraries/networking/src/LimitedNodeList.h b/libraries/networking/src/LimitedNodeList.h index 63f93458f3..c7a8ccecf5 100644 --- a/libraries/networking/src/LimitedNodeList.h +++ b/libraries/networking/src/LimitedNodeList.h @@ -20,19 +20,18 @@ #include // not on windows, not needed for mac or windows #endif -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include -#include +#include #include "DomainHandler.h" #include "Node.h" -#include "UUIDCityHasher.h" +#include "UUIDHasher.h" const int MAX_PACKET_SIZE = 1500; @@ -54,8 +53,9 @@ typedef QSet NodeSet; typedef QSharedPointer SharedNodePointer; Q_DECLARE_METATYPE(SharedNodePointer) -typedef cuckoohash_map NodeHash; -typedef std::vector > NodeHashSnapshot; +using namespace tbb; +typedef std::pair UUIDNodePair; +typedef concurrent_unordered_map NodeHash; typedef quint8 PingType_t; namespace PingType { @@ -74,7 +74,6 @@ public: const QUuid& getSessionUUID() const { return _sessionUUID; } void setSessionUUID(const QUuid& sessionUUID); - void rebindNodeSocket(); QUdpSocket& getNodeSocket() { return _nodeSocket; } QUdpSocket& getDTLSSocket(); @@ -95,11 +94,10 @@ public: const HifiSockAddr& overridenSockAddr = HifiSockAddr()); void(*linkedDataCreateCallback)(Node *); - - const NodeHash& getNodeHash() { return _nodeHash; } + int size() const { return _nodeHash.size(); } - SharedNodePointer nodeWithUUID(const QUuid& nodeUUID, bool blockingLock = true); + SharedNodePointer nodeWithUUID(const QUuid& nodeUUID); SharedNodePointer sendingNodeForPacket(const QByteArray& packet); SharedNodePointer addOrUpdateNode(const QUuid& uuid, NodeType_t nodeType, @@ -128,6 +126,29 @@ public: void sendHeartbeatToIceServer(const HifiSockAddr& iceServerSockAddr, QUuid headerID = QUuid(), const QUuid& connectRequestID = QUuid()); + + template + void eachNode(NodeLambda functor) { + QReadLocker readLock(&_nodeMutex); + + for (NodeHash::const_iterator it = _nodeHash.cbegin(); it != _nodeHash.cend(); ++it) { + functor(it->second); + } + } + + template + SharedNodePointer nodeMatchingPredicate(const PredLambda predicate) { + QReadLocker readLock(&_nodeMutex); + + for (NodeHash::const_iterator it = _nodeHash.cbegin(); it != _nodeHash.cend(); ++it) { + if (predicate(it->second)) { + return it->second; + } + } + + return SharedNodePointer(); + } + public slots: void reset(); void eraseAllNodes(); @@ -158,6 +179,7 @@ protected: QUuid _sessionUUID; NodeHash _nodeHash; + QReadWriteLock _nodeMutex; QUdpSocket _nodeSocket; QUdpSocket* _dtlsSocket; HifiSockAddr _localSockAddr; @@ -166,6 +188,17 @@ protected: int _numCollectedPackets; int _numCollectedBytes; QElapsedTimer _packetStatTimer; + + template + void eachNodeHashIterator(IteratorLambda functor) { + QWriteLocker writeLock(&_nodeMutex); + NodeHash::iterator it = _nodeHash.begin(); + + while (it != _nodeHash.end()) { + functor(it); + } + } + }; #endif // hifi_LimitedNodeList_h diff --git a/libraries/networking/src/NodeList.cpp b/libraries/networking/src/NodeList.cpp index fe8efe42c4..bf992e7b88 100644 --- a/libraries/networking/src/NodeList.cpp +++ b/libraries/networking/src/NodeList.cpp @@ -449,13 +449,12 @@ void NodeList::pingPunchForInactiveNode(const SharedNodePointer& node) { } void NodeList::pingInactiveNodes() { - NodeHashSnapshot snapshotHash = _nodeHash.snapshot_table(); - for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) { - if (!it->second->getActiveSocket()) { + eachNode([this](const SharedNodePointer& node){ + if (!node->getActiveSocket()) { // we don't have an active link to this node, ping it to set that up - pingPunchForInactiveNode(it->second); + pingPunchForInactiveNode(node); } - } + }); } void NodeList::activateSocketFromNodeCommunication(const QByteArray& packet, const SharedNodePointer& sendingNode) { diff --git a/libraries/networking/src/UUIDCityHasher.cpp b/libraries/networking/src/UUIDCityHasher.cpp deleted file mode 100644 index 731e287fc0..0000000000 --- a/libraries/networking/src/UUIDCityHasher.cpp +++ /dev/null @@ -1,12 +0,0 @@ -// -// UUIDCityHasher.cpp -// libraries/networking/src -// -// Created by Stephen Birarda on 2014-11-05. -// Copyright 2014 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#include "UUIDCityHasher.h" diff --git a/libraries/networking/src/UUIDCityHasher.h b/libraries/networking/src/UUIDCityHasher.h deleted file mode 100644 index e27e3bdf1b..0000000000 --- a/libraries/networking/src/UUIDCityHasher.h +++ /dev/null @@ -1,26 +0,0 @@ -// -// UUIDCityHasher.h -// libraries/networking/src -// -// Created by Stephen Birarda on 2014-11-05. -// Copyright 2014 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#ifndef hifi_UUIDCityHasher_h -#define hifi_UUIDCityHasher_h - -#include - -#include "UUID.h" - -class UUIDCityHasher { -public: - size_t operator()(const QUuid& key) const { - return CityHash64(key.toRfc4122().constData(), NUM_BYTES_RFC4122_UUID); - } -}; - -#endif // hifi_UUIDCityHasher_h \ No newline at end of file diff --git a/libraries/networking/src/UUIDHasher.h b/libraries/networking/src/UUIDHasher.h new file mode 100644 index 0000000000..d5d16e21e9 --- /dev/null +++ b/libraries/networking/src/UUIDHasher.h @@ -0,0 +1,26 @@ +// +// UUIDHasher.h +// libraries/networking/src +// +// Created by Stephen Birarda on 2014-11-05. +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_UUIDHasher_h +#define hifi_UUIDHasher_h + +#include "UUID.h" + +class UUIDHasher { +public: + size_t operator()(const QUuid& uuid) const { + return uuid.data1 ^ uuid.data2 ^ (uuid.data3 << 16) + ^ ((uuid.data4[0] << 24) | (uuid.data4[1] << 16) | (uuid.data4[2] << 8) | uuid.data4[3]) + ^ ((uuid.data4[4] << 24) | (uuid.data4[5] << 16) | (uuid.data4[6] << 8) | uuid.data4[7]); + } +}; + +#endif // hifi_UUIDHasher_h \ No newline at end of file From c80633499fbfc67f87cbb2e363e9771630b36044 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 6 Nov 2014 11:35:07 -0800 Subject: [PATCH 14/62] make eachNode callers return bool to say if iteration should continue --- libraries/networking/src/LimitedNodeList.cpp | 2 ++ libraries/networking/src/LimitedNodeList.h | 4 +++- libraries/networking/src/NodeList.cpp | 2 ++ libraries/octree/src/JurisdictionListener.cpp | 14 ++++++-------- libraries/octree/src/OctreeEditPacketSender.cpp | 13 ++++++------- 5 files changed, 19 insertions(+), 16 deletions(-) diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index 818d35c0e5..2661c83b5c 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -425,6 +425,8 @@ unsigned LimitedNodeList::broadcastToNodes(const QByteArray& packet, const NodeS writeDatagram(packet, node); ++n; } + + return true; }); return n; diff --git a/libraries/networking/src/LimitedNodeList.h b/libraries/networking/src/LimitedNodeList.h index c7a8ccecf5..750e5b8688 100644 --- a/libraries/networking/src/LimitedNodeList.h +++ b/libraries/networking/src/LimitedNodeList.h @@ -132,7 +132,9 @@ public: QReadLocker readLock(&_nodeMutex); for (NodeHash::const_iterator it = _nodeHash.cbegin(); it != _nodeHash.cend(); ++it) { - functor(it->second); + if (!functor(it->second)) { + break; + } } } diff --git a/libraries/networking/src/NodeList.cpp b/libraries/networking/src/NodeList.cpp index bf992e7b88..7271dfe446 100644 --- a/libraries/networking/src/NodeList.cpp +++ b/libraries/networking/src/NodeList.cpp @@ -454,6 +454,8 @@ void NodeList::pingInactiveNodes() { // we don't have an active link to this node, ping it to set that up pingPunchForInactiveNode(node); } + + return true; }); } diff --git a/libraries/octree/src/JurisdictionListener.cpp b/libraries/octree/src/JurisdictionListener.cpp index 606a6c13f2..f16daf9f0d 100644 --- a/libraries/octree/src/JurisdictionListener.cpp +++ b/libraries/octree/src/JurisdictionListener.cpp @@ -38,16 +38,14 @@ bool JurisdictionListener::queueJurisdictionRequest() { int sizeOut = populatePacketHeader(reinterpret_cast(bufferOut), PacketTypeJurisdictionRequest); int nodeCount = 0; - NodeList* nodeList = NodeList::getInstance(); - - NodeHashSnapshot nodeHashSnapshot = nodeList->getNodeHash().snapshot_table(); - - for (auto it = nodeHashSnapshot.begin(); it != nodeHashSnapshot.end(); it++) { - if (it->second->getType() == getNodeType() && it->second->getActiveSocket()) { - _packetSender.queuePacketForSending(it->second, QByteArray(reinterpret_cast(bufferOut), sizeOut)); + NodeList::getInstance()->eachNode([&](const SharedNodePointer& node) { + if (node->getType() == getNodeType() && node->getActiveSocket()) { + _packetSender.queuePacketForSending(node, QByteArray(reinterpret_cast(bufferOut), sizeOut)); nodeCount++; } - } + + return true; + }); if (nodeCount > 0){ _packetSender.setPacketsPerSecond(nodeCount); diff --git a/libraries/octree/src/OctreeEditPacketSender.cpp b/libraries/octree/src/OctreeEditPacketSender.cpp index 19de2e37e9..1a126576d3 100644 --- a/libraries/octree/src/OctreeEditPacketSender.cpp +++ b/libraries/octree/src/OctreeEditPacketSender.cpp @@ -51,12 +51,8 @@ OctreeEditPacketSender::~OctreeEditPacketSender() { bool OctreeEditPacketSender::serversExist() const { bool hasServers = false; bool atLeastOneJurisdictionMissing = false; // assume the best - NodeList* nodeList = NodeList::getInstance(); - NodeHashSnapshot snapshotHash = nodeList->getNodeHash().snapshot_table(); - for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) { - // only send to the NodeTypes that are getMyNodeType() - SharedNodePointer node = it->second; + NodeList::getInstance()->eachNode([&](const SharedNodePointer& node){ if (node->getType() == getMyNodeType() && node->getActiveSocket()) { QUuid nodeUUID = node->getUUID(); @@ -72,10 +68,13 @@ bool OctreeEditPacketSender::serversExist() const { } hasServers = true; } + if (atLeastOneJurisdictionMissing) { - break; // no point in looking further... + return false; // no point in looking further - return false from anonymous function + } else { + return true; } - } + }); return (hasServers && !atLeastOneJurisdictionMissing); } From da8fc5d5c578efb0dcc29c599c45cc00c15dd886 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 6 Nov 2014 11:43:20 -0800 Subject: [PATCH 15/62] migrate octree library to tbb concurrent map --- .../octree/src/OctreeEditPacketSender.cpp | 108 +++++++++--------- libraries/octree/src/OctreeHeadlessViewer.cpp | 54 ++++----- 2 files changed, 79 insertions(+), 83 deletions(-) diff --git a/libraries/octree/src/OctreeEditPacketSender.cpp b/libraries/octree/src/OctreeEditPacketSender.cpp index 1a126576d3..c0866a981e 100644 --- a/libraries/octree/src/OctreeEditPacketSender.cpp +++ b/libraries/octree/src/OctreeEditPacketSender.cpp @@ -85,54 +85,50 @@ void OctreeEditPacketSender::queuePacketToNode(const QUuid& nodeUUID, unsigned c size_t length, qint64 satoshiCost) { bool wantDebug = false; - NodeList* nodeList = NodeList::getInstance(); - - NodeHashSnapshot snapshotHash = nodeList->getNodeHash().snapshot_table(); - for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) { - SharedNodePointer node = it->second; - + NodeList::getInstance()->eachNode([&](const SharedNodePointer& node){ // only send to the NodeTypes that are getMyNodeType() - if (node->getType() == getMyNodeType() && - ((node->getUUID() == nodeUUID) || (nodeUUID.isNull()))) { - if (node->getActiveSocket()) { - - // pack sequence number - int numBytesPacketHeader = numBytesForPacketHeader(reinterpret_cast(buffer)); - unsigned char* sequenceAt = buffer + numBytesPacketHeader; - quint16 sequence = _outgoingSequenceNumbers[nodeUUID]++; - memcpy(sequenceAt, &sequence, sizeof(quint16)); + if (node->getType() == getMyNodeType() + && ((node->getUUID() == nodeUUID) || (nodeUUID.isNull())) + && node->getActiveSocket()) { + + // pack sequence number + int numBytesPacketHeader = numBytesForPacketHeader(reinterpret_cast(buffer)); + unsigned char* sequenceAt = buffer + numBytesPacketHeader; + quint16 sequence = _outgoingSequenceNumbers[nodeUUID]++; + memcpy(sequenceAt, &sequence, sizeof(quint16)); + + // send packet + QByteArray packet(reinterpret_cast(buffer), length); + + queuePacketForSending(node, packet); + + if (hasDestinationWalletUUID() && satoshiCost > 0) { + // if we have a destination wallet UUID and a cost associated with this packet, signal that it + // needs to be sent + emit octreePaymentRequired(satoshiCost, nodeUUID, _destinationWalletUUID); + } + + // add packet to history + _sentPacketHistories[nodeUUID].packetSent(sequence, packet); + + // debugging output... + if (wantDebug) { + int numBytesPacketHeader = numBytesForPacketHeader(reinterpret_cast(buffer)); + unsigned short int sequence = (*((unsigned short int*)(buffer + numBytesPacketHeader))); + quint64 createdAt = (*((quint64*)(buffer + numBytesPacketHeader + sizeof(sequence)))); + quint64 queuedAt = usecTimestampNow(); + quint64 transitTime = queuedAt - createdAt; - // send packet - QByteArray packet(reinterpret_cast(buffer), length); - - queuePacketForSending(node, packet); - - if (hasDestinationWalletUUID() && satoshiCost > 0) { - // if we have a destination wallet UUID and a cost associated with this packet, signal that it - // needs to be sent - emit octreePaymentRequired(satoshiCost, nodeUUID, _destinationWalletUUID); - } - - // add packet to history - _sentPacketHistories[nodeUUID].packetSent(sequence, packet); - - // debugging output... - if (wantDebug) { - int numBytesPacketHeader = numBytesForPacketHeader(reinterpret_cast(buffer)); - unsigned short int sequence = (*((unsigned short int*)(buffer + numBytesPacketHeader))); - quint64 createdAt = (*((quint64*)(buffer + numBytesPacketHeader + sizeof(sequence)))); - quint64 queuedAt = usecTimestampNow(); - quint64 transitTime = queuedAt - createdAt; - - qDebug() << "OctreeEditPacketSender::queuePacketToNode() queued " << buffer[0] << - " - command to node bytes=" << length << - " satoshiCost=" << satoshiCost << - " sequence=" << sequence << - " transitTimeSoFar=" << transitTime << " usecs"; - } + qDebug() << "OctreeEditPacketSender::queuePacketToNode() queued " << buffer[0] << + " - command to node bytes=" << length << + " satoshiCost=" << satoshiCost << + " sequence=" << sequence << + " transitTimeSoFar=" << transitTime << " usecs"; } } - } + + return true; + }); } void OctreeEditPacketSender::processPreServerExistsPackets() { @@ -198,9 +194,7 @@ void OctreeEditPacketSender::queuePacketToNodes(unsigned char* buffer, size_t le // for a different server... So we need to actually manage multiple queued packets... one // for each server - NodeHashSnapshot snapshotHash = NodeList::getInstance()->getNodeHash().snapshot_table(); - for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) { - SharedNodePointer node = it->second; + NodeList::getInstance()->eachNode([&](const SharedNodePointer& node){ // only send to the NodeTypes that are getMyNodeType() if (node->getActiveSocket() && node->getType() == getMyNodeType()) { QUuid nodeUUID = node->getUUID(); @@ -215,7 +209,9 @@ void OctreeEditPacketSender::queuePacketToNodes(unsigned char* buffer, size_t le queuePacketToNode(nodeUUID, buffer, length, satoshiCost); } } - } + + return true; + }); } @@ -254,9 +250,7 @@ void OctreeEditPacketSender::queueOctreeEditMessage(PacketType type, unsigned ch _packetsQueueLock.lock(); - NodeHashSnapshot snapshotHash = NodeList::getInstance()->getNodeHash().snapshot_table(); - for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) { - SharedNodePointer node = it->second; + NodeList::getInstance()->eachNode([&](const SharedNodePointer& node){ // only send to the NodeTypes that are getMyNodeType() if (node->getActiveSocket() && node->getType() == getMyNodeType()) { QUuid nodeUUID = node->getUUID(); @@ -279,19 +273,19 @@ void OctreeEditPacketSender::queueOctreeEditMessage(PacketType type, unsigned ch if (isMyJurisdiction) { EditPacketBuffer& packetBuffer = _pendingEditPackets[nodeUUID]; packetBuffer._nodeUUID = nodeUUID; - + // If we're switching type, then we send the last one and start over if ((type != packetBuffer._currentType && packetBuffer._currentSize > 0) || (packetBuffer._currentSize + length >= (size_t)_maxPacketSize)) { releaseQueuedPacket(packetBuffer); initializePacket(packetBuffer, type); } - + // If the buffer is empty and not correctly initialized for our type... if (type != packetBuffer._currentType && packetBuffer._currentSize == 0) { initializePacket(packetBuffer, type); } - + // 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 @@ -299,13 +293,15 @@ void OctreeEditPacketSender::queueOctreeEditMessage(PacketType type, unsigned ch if (node->getClockSkewUsec() != 0) { adjustEditPacketForClockSkew(type, editPacketBuffer, length, node->getClockSkewUsec()); } - + memcpy(&packetBuffer._currentBuffer[packetBuffer._currentSize], editPacketBuffer, length); packetBuffer._currentSize += length; packetBuffer._satoshiCost += satoshiCost; } } - } + + return true; + }); _packetsQueueLock.unlock(); diff --git a/libraries/octree/src/OctreeHeadlessViewer.cpp b/libraries/octree/src/OctreeHeadlessViewer.cpp index b363c654c1..e40ae712e9 100644 --- a/libraries/octree/src/OctreeHeadlessViewer.cpp +++ b/libraries/octree/src/OctreeHeadlessViewer.cpp @@ -77,16 +77,14 @@ void OctreeHeadlessViewer::queryOctree() { int inViewServers = 0; int unknownJurisdictionServers = 0; - NodeHashSnapshot snapshotHash = NodeList::getInstance()->getNodeHash().snapshot_table(); - for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) { - SharedNodePointer node = it->second; + NodeList::getInstance()->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... jurisdictions.lockForRead(); @@ -95,18 +93,18 @@ void OctreeHeadlessViewer::queryOctree() { unknownJurisdictionServers++; } else { const JurisdictionMap& map = (jurisdictions)[nodeUUID]; - + unsigned char* rootCode = map.getRootOctalCode(); - + if (rootCode) { VoxelPositionSize rootDetails; voxelDetailsForCode(rootCode, rootDetails); jurisdictions.unlock(); AACube serverBounds(glm::vec3(rootDetails.x, rootDetails.y, rootDetails.z), rootDetails.s); serverBounds.scale(TREE_SCALE); - + ViewFrustum::location serverFrustumLocation = _viewFrustum.cubeInFrustum(serverBounds); - + if (serverFrustumLocation != ViewFrustum::OUTSIDE) { inViewServers++; } @@ -115,7 +113,9 @@ void OctreeHeadlessViewer::queryOctree() { } } } - } + + return true; + }); if (wantExtraDebugging) { qDebug("Servers: total %d, in view %d, unknown jurisdiction %d", @@ -143,18 +143,16 @@ void OctreeHeadlessViewer::queryOctree() { } NodeList* nodeList = NodeList::getInstance(); - - for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) { - SharedNodePointer node = it->second; + 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... jurisdictions.lockForRead(); @@ -166,16 +164,16 @@ void OctreeHeadlessViewer::queryOctree() { } } else { const JurisdictionMap& map = (jurisdictions)[nodeUUID]; - + unsigned char* rootCode = map.getRootOctalCode(); - + if (rootCode) { VoxelPositionSize rootDetails; voxelDetailsForCode(rootCode, rootDetails); jurisdictions.unlock(); AACube serverBounds(glm::vec3(rootDetails.x, rootDetails.y, rootDetails.z), rootDetails.s); serverBounds.scale(TREE_SCALE); - + ViewFrustum::location serverFrustumLocation = _viewFrustum.cubeInFrustum(serverBounds); if (serverFrustumLocation != ViewFrustum::OUTSIDE) { inView = true; @@ -189,7 +187,7 @@ void OctreeHeadlessViewer::queryOctree() { } } } - + if (inView) { _octreeQuery.setMaxOctreePacketsPerSecond(perServerPPS); if (wantExtraDebugging) { @@ -198,9 +196,9 @@ void OctreeHeadlessViewer::queryOctree() { } else if (unknownView) { if (wantExtraDebugging) { qDebug() << "no known jurisdiction for node " << *node << ", give it budget of " - << perUnknownServer << " to send us jurisdiction."; + << 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 @@ -224,19 +222,21 @@ void OctreeHeadlessViewer::queryOctree() { } // set up the packet for sending... unsigned char* endOfQueryPacket = queryPacket; - + // insert packet type/version and node UUID endOfQueryPacket += populatePacketHeader(reinterpret_cast(endOfQueryPacket), packetType); - + // encode the query data... endOfQueryPacket += _octreeQuery.getBroadcastData(endOfQueryPacket); - + int packetLength = endOfQueryPacket - queryPacket; - + // make sure we still have an active socket nodeList->writeUnverifiedDatagram(reinterpret_cast(queryPacket), packetLength, node); } - } + + return true; + }); } From 270823be438184199866abb885a2c475a84e65cd Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 6 Nov 2014 13:39:15 -0800 Subject: [PATCH 16/62] update domain-server to leverage intel tbb hash --- domain-server/src/DomainServer.cpp | 100 ++++++++----------- libraries/networking/src/LimitedNodeList.cpp | 7 +- 2 files changed, 42 insertions(+), 65 deletions(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 5dddfd70dd..cbd70f9edc 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -821,52 +821,50 @@ void DomainServer::sendDomainListToNode(const SharedNodePointer& node, const Hif if (nodeData->isAuthenticated()) { // if this authenticated node has any interest types, send back those nodes as well - NodeHashSnapshot snapshotHash = nodeList->getNodeHash().snapshot_table(); - - for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) { - SharedNodePointer otherNode = it->second; - + nodeList->eachNode([&](const SharedNodePointer& otherNode){ // reset our nodeByteArray and nodeDataStream QByteArray nodeByteArray; QDataStream nodeDataStream(&nodeByteArray, QIODevice::Append); - + if (otherNode->getUUID() != node->getUUID() && nodeInterestList.contains(otherNode->getType())) { - + // don't send avatar nodes to other avatars, that will come from avatar mixer nodeDataStream << *otherNode.data(); - + // pack the secret that these two nodes will use to communicate with each other QUuid secretUUID = nodeData->getSessionSecretHash().value(otherNode->getUUID()); if (secretUUID.isNull()) { // generate a new secret UUID these two nodes can use secretUUID = QUuid::createUuid(); - + // set that on the current Node's sessionSecretHash nodeData->getSessionSecretHash().insert(otherNode->getUUID(), secretUUID); - + // set it on the other Node's sessionSecretHash reinterpret_cast(otherNode->getLinkedData()) ->getSessionSecretHash().insert(node->getUUID(), secretUUID); - + } - + nodeDataStream << secretUUID; - + if (broadcastPacket.size() + nodeByteArray.size() > dataMTU) { // we need to break here and start a new packet // so send the current one - + nodeList->writeDatagram(broadcastPacket, node, senderSockAddr); - + // reset the broadcastPacket structure broadcastPacket.resize(numBroadcastPacketLeadBytes); broadcastDataStream.device()->seek(numBroadcastPacketLeadBytes); } - + // append the nodeByteArray to the current state of broadcastDataStream broadcastPacket.append(nodeByteArray); } - } + + return true; + }); } // always write the last broadcastPacket @@ -963,17 +961,14 @@ void DomainServer::readAvailableDatagrams() { void DomainServer::setupPendingAssignmentCredits() { // enumerate the NodeList to find the assigned nodes - NodeHashSnapshot snapshotHash = NodeList::getInstance()->getNodeHash().snapshot_table(); - - for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) { - SharedNodePointer node = it->second; + NodeList::getInstance()->eachNode([&](const SharedNodePointer& node){ DomainServerNodeData* nodeData = reinterpret_cast(node->getLinkedData()); - + if (!nodeData->getAssignmentUUID().isNull() && !nodeData->getWalletUUID().isNull()) { // check if we have a non-finalized transaction for this node to add this amount to TransactionHash::iterator i = _pendingAssignmentCredits.find(nodeData->getWalletUUID()); WalletTransaction* existingTransaction = NULL; - + while (i != _pendingAssignmentCredits.end() && i.key() == nodeData->getWalletUUID()) { if (!i.value()->isFinalized()) { existingTransaction = i.value(); @@ -982,16 +977,16 @@ void DomainServer::setupPendingAssignmentCredits() { ++i; } } - + qint64 elapsedMsecsSinceLastPayment = nodeData->getPaymentIntervalTimer().elapsed(); nodeData->getPaymentIntervalTimer().restart(); - + const float CREDITS_PER_HOUR = 0.10f; const float CREDITS_PER_MSEC = CREDITS_PER_HOUR / (60 * 60 * 1000); const int SATOSHIS_PER_MSEC = CREDITS_PER_MSEC * SATOSHIS_PER_CREDIT; - + float pendingCredits = elapsedMsecsSinceLastPayment * SATOSHIS_PER_MSEC; - + if (existingTransaction) { existingTransaction->incrementAmount(pendingCredits); } else { @@ -1000,7 +995,9 @@ void DomainServer::setupPendingAssignmentCredits() { _pendingAssignmentCredits.insert(nodeData->getWalletUUID(), freshTransaction); } } - } + + return true; + }); } void DomainServer::sendPendingTransactionsToServer() { @@ -1126,16 +1123,13 @@ void DomainServer::sendHeartbeatToDataServer(const QString& networkAddress) { // add the number of currently connected agent users int numConnectedAuthedUsers = 0; - NodeHashSnapshot snapshotHash = NodeList::getInstance()->getNodeHash().snapshot_table(); - - for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) { - - SharedNodePointer node = it->second; - + NodeList::getInstance()->eachNode([&numConnectedAuthedUsers](const SharedNodePointer& node){ if (node->getLinkedData() && !static_cast(node->getLinkedData())->getUsername().isEmpty()) { ++numConnectedAuthedUsers; } - } + + return true; + }); const QString DOMAIN_HEARTBEAT_KEY = "heartbeat"; const QString HEARTBEAT_NUM_USERS_KEY = "num_users"; @@ -1438,20 +1432,17 @@ bool DomainServer::handleHTTPRequest(HTTPConnection* connection, const QUrl& url QJsonObject assignedNodesJSON; // enumerate the NodeList to find the assigned nodes - NodeHashSnapshot snapshotHash = NodeList::getInstance()->getNodeHash().snapshot_table(); - - for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) { - - SharedNodePointer node = it->second; - + NodeList::getInstance()->eachNode([this, &assignedNodesJSON](const SharedNodePointer& node){ DomainServerNodeData* nodeData = reinterpret_cast(node->getLinkedData()); - + if (!nodeData->getAssignmentUUID().isNull()) { // add the node using the UUID as the key QString uuidString = uuidStringWithoutCurlyBraces(nodeData->getAssignmentUUID()); assignedNodesJSON[uuidString] = jsonObjectForNode(node); } - } + + return true; + }); assignmentJSON["fulfilled"] = assignedNodesJSON; @@ -1505,14 +1496,12 @@ bool DomainServer::handleHTTPRequest(HTTPConnection* connection, const QUrl& url QJsonArray nodesJSONArray; // enumerate the NodeList to find the assigned nodes - LimitedNodeList* nodeList = LimitedNodeList::getInstance(); - - NodeHashSnapshot snapshotHash = nodeList->getNodeHash().snapshot_table(); - - for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) { + LimitedNodeList::getInstance()->eachNode([this, &nodesJSONArray](const SharedNodePointer& node){ // add the node using the UUID as the key - nodesJSONArray.append(jsonObjectForNode(it->second)); - } + nodesJSONArray.append(jsonObjectForNode(node)); + + return true; + }); rootJSON["nodes"] = nodesJSONArray; @@ -2040,18 +2029,9 @@ void DomainServer::addStaticAssignmentsToQueue() { QHash::iterator staticAssignment = staticHashCopy.begin(); while (staticAssignment != staticHashCopy.end()) { // add any of the un-matched static assignments to the queue - bool foundMatchingAssignment = false; // enumerate the nodes and check if there is one with an attached assignment with matching UUID - NodeHashSnapshot snapshotHash = NodeList::getInstance()->getNodeHash().snapshot_table(); - - for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) { - if (it->first == staticAssignment->data()->getUUID()) { - foundMatchingAssignment = true; - } - } - - if (!foundMatchingAssignment) { + if (NodeList::getInstance()->nodeWithUUID(staticAssignment->data()->getUUID())) { // this assignment has not been fulfilled - reset the UUID and add it to the assignment queue refreshStaticAssignmentAndAddToQueue(*staticAssignment); } diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index 2661c83b5c..4202444749 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -345,11 +345,8 @@ int LimitedNodeList::findNodeAndUpdateWithDataFromPacket(const QByteArray& packe } SharedNodePointer LimitedNodeList::nodeWithUUID(const QUuid& nodeUUID) { - try { - return _nodeHash.at(nodeUUID); - } catch (std::out_of_range) { - return SharedNodePointer(); - } + NodeHash::const_iterator it = _nodeHash.find(nodeUUID); + return it == _nodeHash.cend() ? SharedNodePointer() : it->second; } SharedNodePointer LimitedNodeList::sendingNodeForPacket(const QByteArray& packet) { From e92376cf649192a5480d53332bcbb08c9749f41c Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 6 Nov 2014 13:41:55 -0800 Subject: [PATCH 17/62] distinguish between eachNode and eachNodeBreakable --- domain-server/src/DomainServer.cpp | 10 ---------- libraries/networking/src/LimitedNodeList.cpp | 2 -- libraries/networking/src/LimitedNodeList.h | 9 +++++++++ libraries/networking/src/NodeList.cpp | 2 -- libraries/octree/src/JurisdictionListener.cpp | 2 -- libraries/octree/src/OctreeEditPacketSender.cpp | 8 +------- libraries/octree/src/OctreeHeadlessViewer.cpp | 4 ---- 7 files changed, 10 insertions(+), 27 deletions(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index cbd70f9edc..cb4b1c8026 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -862,8 +862,6 @@ void DomainServer::sendDomainListToNode(const SharedNodePointer& node, const Hif // append the nodeByteArray to the current state of broadcastDataStream broadcastPacket.append(nodeByteArray); } - - return true; }); } @@ -995,8 +993,6 @@ void DomainServer::setupPendingAssignmentCredits() { _pendingAssignmentCredits.insert(nodeData->getWalletUUID(), freshTransaction); } } - - return true; }); } @@ -1127,8 +1123,6 @@ void DomainServer::sendHeartbeatToDataServer(const QString& networkAddress) { if (node->getLinkedData() && !static_cast(node->getLinkedData())->getUsername().isEmpty()) { ++numConnectedAuthedUsers; } - - return true; }); const QString DOMAIN_HEARTBEAT_KEY = "heartbeat"; @@ -1440,8 +1434,6 @@ bool DomainServer::handleHTTPRequest(HTTPConnection* connection, const QUrl& url QString uuidString = uuidStringWithoutCurlyBraces(nodeData->getAssignmentUUID()); assignedNodesJSON[uuidString] = jsonObjectForNode(node); } - - return true; }); assignmentJSON["fulfilled"] = assignedNodesJSON; @@ -1499,8 +1491,6 @@ bool DomainServer::handleHTTPRequest(HTTPConnection* connection, const QUrl& url LimitedNodeList::getInstance()->eachNode([this, &nodesJSONArray](const SharedNodePointer& node){ // add the node using the UUID as the key nodesJSONArray.append(jsonObjectForNode(node)); - - return true; }); rootJSON["nodes"] = nodesJSONArray; diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index 4202444749..ac63941882 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -422,8 +422,6 @@ unsigned LimitedNodeList::broadcastToNodes(const QByteArray& packet, const NodeS writeDatagram(packet, node); ++n; } - - return true; }); return n; diff --git a/libraries/networking/src/LimitedNodeList.h b/libraries/networking/src/LimitedNodeList.h index 750e5b8688..25c560b2e2 100644 --- a/libraries/networking/src/LimitedNodeList.h +++ b/libraries/networking/src/LimitedNodeList.h @@ -131,6 +131,15 @@ public: void eachNode(NodeLambda functor) { QReadLocker readLock(&_nodeMutex); + for (NodeHash::const_iterator it = _nodeHash.cbegin(); it != _nodeHash.cend(); ++it) { + functor(it->second); + } + } + + template + void eachNodeBreakable(BreakableNodeLambda functor) { + QReadLocker readLock(&_nodeMutex); + for (NodeHash::const_iterator it = _nodeHash.cbegin(); it != _nodeHash.cend(); ++it) { if (!functor(it->second)) { break; diff --git a/libraries/networking/src/NodeList.cpp b/libraries/networking/src/NodeList.cpp index 7271dfe446..bf992e7b88 100644 --- a/libraries/networking/src/NodeList.cpp +++ b/libraries/networking/src/NodeList.cpp @@ -454,8 +454,6 @@ void NodeList::pingInactiveNodes() { // we don't have an active link to this node, ping it to set that up pingPunchForInactiveNode(node); } - - return true; }); } diff --git a/libraries/octree/src/JurisdictionListener.cpp b/libraries/octree/src/JurisdictionListener.cpp index f16daf9f0d..bcd5e9ac1c 100644 --- a/libraries/octree/src/JurisdictionListener.cpp +++ b/libraries/octree/src/JurisdictionListener.cpp @@ -43,8 +43,6 @@ bool JurisdictionListener::queueJurisdictionRequest() { _packetSender.queuePacketForSending(node, QByteArray(reinterpret_cast(bufferOut), sizeOut)); nodeCount++; } - - return true; }); if (nodeCount > 0){ diff --git a/libraries/octree/src/OctreeEditPacketSender.cpp b/libraries/octree/src/OctreeEditPacketSender.cpp index c0866a981e..8c94316d28 100644 --- a/libraries/octree/src/OctreeEditPacketSender.cpp +++ b/libraries/octree/src/OctreeEditPacketSender.cpp @@ -52,7 +52,7 @@ bool OctreeEditPacketSender::serversExist() const { bool hasServers = false; bool atLeastOneJurisdictionMissing = false; // assume the best - NodeList::getInstance()->eachNode([&](const SharedNodePointer& node){ + NodeList::getInstance()->eachNodeBreakable([&](const SharedNodePointer& node){ if (node->getType() == getMyNodeType() && node->getActiveSocket()) { QUuid nodeUUID = node->getUUID(); @@ -126,8 +126,6 @@ void OctreeEditPacketSender::queuePacketToNode(const QUuid& nodeUUID, unsigned c " transitTimeSoFar=" << transitTime << " usecs"; } } - - return true; }); } @@ -209,8 +207,6 @@ void OctreeEditPacketSender::queuePacketToNodes(unsigned char* buffer, size_t le queuePacketToNode(nodeUUID, buffer, length, satoshiCost); } } - - return true; }); } @@ -299,8 +295,6 @@ void OctreeEditPacketSender::queueOctreeEditMessage(PacketType type, unsigned ch packetBuffer._satoshiCost += satoshiCost; } } - - return true; }); _packetsQueueLock.unlock(); diff --git a/libraries/octree/src/OctreeHeadlessViewer.cpp b/libraries/octree/src/OctreeHeadlessViewer.cpp index e40ae712e9..e0ca22e4e8 100644 --- a/libraries/octree/src/OctreeHeadlessViewer.cpp +++ b/libraries/octree/src/OctreeHeadlessViewer.cpp @@ -113,8 +113,6 @@ void OctreeHeadlessViewer::queryOctree() { } } } - - return true; }); if (wantExtraDebugging) { @@ -234,8 +232,6 @@ void OctreeHeadlessViewer::queryOctree() { // make sure we still have an active socket nodeList->writeUnverifiedDatagram(reinterpret_cast(queryPacket), packetLength, node); } - - return true; }); } From 948615afe5dc90e1187e1a2fff7493f9e8f19118 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 6 Nov 2014 13:44:03 -0800 Subject: [PATCH 18/62] move metavoxels library to tbb concurrent map --- .../metavoxels/src/MetavoxelClientManager.cpp | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/libraries/metavoxels/src/MetavoxelClientManager.cpp b/libraries/metavoxels/src/MetavoxelClientManager.cpp index 7765b8cda2..3148f870c2 100644 --- a/libraries/metavoxels/src/MetavoxelClientManager.cpp +++ b/libraries/metavoxels/src/MetavoxelClientManager.cpp @@ -43,24 +43,22 @@ SharedObjectPointer MetavoxelClientManager::findFirstRaySpannerIntersection(cons SharedObjectPointer closestSpanner; float closestDistance = FLT_MAX; - NodeHashSnapshot snapshotHash = NodeList::getInstance()->getNodeHash().snapshot_table(); - for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) { - SharedNodePointer node = it->second; - + NodeList::getInstance()->eachNode([&](const SharedNodePointer& node){ if (node->getType() == NodeType::MetavoxelServer) { QMutexLocker locker(&node->getMutex()); MetavoxelClient* client = static_cast(node->getLinkedData()); if (client) { float clientDistance; SharedObjectPointer clientSpanner = client->getDataCopy().findFirstRaySpannerIntersection( - origin, direction, attribute, clientDistance); + origin, direction, attribute, clientDistance); if (clientSpanner && clientDistance < closestDistance) { closestSpanner = clientSpanner; closestDistance = clientDistance; } } } - } + }); + if (closestSpanner) { distance = closestDistance; } @@ -119,11 +117,7 @@ MetavoxelClient* MetavoxelClientManager::createClient(const SharedNodePointer& n } void MetavoxelClientManager::guide(MetavoxelVisitor& visitor) { - NodeHashSnapshot snapshotHash = NodeList::getInstance()->getNodeHash().snapshot_table(); - - for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) { - SharedNodePointer node = it->second; - + NodeList::getInstance()->eachNode([&visitor](const SharedNodePointer& node){ if (node->getType() == NodeType::MetavoxelServer) { QMutexLocker locker(&node->getMutex()); MetavoxelClient* client = static_cast(node->getLinkedData()); @@ -131,7 +125,7 @@ void MetavoxelClientManager::guide(MetavoxelVisitor& visitor) { client->getDataCopy().guide(visitor); } } - } + }); } MetavoxelUpdater::MetavoxelUpdater(MetavoxelClientManager* clientManager) : From 51bc5d10b55de0654f471c2be8978d7b48de2edb Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 6 Nov 2014 13:46:26 -0800 Subject: [PATCH 19/62] fix network includes in LimitedNodeList --- libraries/networking/src/LimitedNodeList.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/networking/src/LimitedNodeList.h b/libraries/networking/src/LimitedNodeList.h index 25c560b2e2..a29902a7c9 100644 --- a/libraries/networking/src/LimitedNodeList.h +++ b/libraries/networking/src/LimitedNodeList.h @@ -24,8 +24,8 @@ #include #include #include -#include -#include +#include +#include #include From 38f2b2ac6a841dafe5afc70de01df83f39060e92 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 6 Nov 2014 13:47:56 -0800 Subject: [PATCH 20/62] move script-engine library to intel tbb concurrent map --- libraries/script-engine/src/ScriptEngine.cpp | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index 340d5b3e20..5b5dd6cd53 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -520,21 +520,17 @@ void ScriptEngine::run() { // write audio packet to AudioMixer nodes NodeList* nodeList = NodeList::getInstance(); - NodeHashSnapshot snapshotHash = nodeList->getNodeHash().snapshot_table(); - - for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) { - SharedNodePointer node = it->second; - + nodeList->eachNode([this, &nodeList, &audioPacket, &numPreSequenceNumberBytes](const SharedNodePointer& node){ // only send to nodes of type AudioMixer if (node->getType() == NodeType::AudioMixer) { // pack sequence number quint16 sequence = _outgoingScriptAudioSequenceNumbers[node->getUUID()]++; memcpy(audioPacket.data() + numPreSequenceNumberBytes, &sequence, sizeof(quint16)); - + // send audio packet nodeList->writeDatagram(audioPacket, node); } - } + }); } } From 1a953b5906a9da2b6b29fc6c609180328cabf2b0 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 6 Nov 2014 13:53:10 -0800 Subject: [PATCH 21/62] migrate node hash calls from AudioMixer to new tbb format --- assignment-client/src/audio/AudioMixer.cpp | 52 +++++++------------ assignment-client/src/avatars/AvatarMixer.cpp | 12 ++--- 2 files changed, 22 insertions(+), 42 deletions(-) diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index 39011b8083..4236072857 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -438,16 +438,12 @@ int AudioMixer::prepareMixForListeningNode(Node* node) { // loop through all other nodes that have sufficient audio to mix int streamsMixed = 0; - NodeHashSnapshot snapshotHash = NodeList::getInstance()->getNodeHash().snapshot_table(); - - for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) { - SharedNodePointer otherNode = it->second; - + NodeList::getInstance()->eachNode([&](const SharedNodePointer& otherNode){ if (otherNode->getLinkedData()) { AudioMixerClientData* otherNodeClientData = (AudioMixerClientData*) otherNode->getLinkedData(); - + // enumerate the ARBs attached to the otherNode and add all that should be added to mix - + const QHash& otherNodeAudioStreams = otherNodeClientData->getAudioStreams(); QHash::ConstIterator i; for (i = otherNodeAudioStreams.constBegin(); i != otherNodeAudioStreams.constEnd(); i++) { @@ -457,14 +453,15 @@ int AudioMixer::prepareMixForListeningNode(Node* node) { if (otherNodeStream->getType() == PositionalAudioStream::Microphone) { streamUUID = otherNode->getUUID(); } - + if (*otherNode != *node || otherNodeStream->shouldLoopbackForNode()) { - streamsMixed += addStreamToMixForListeningNodeWithStream(listenerNodeData, streamUUID, - otherNodeStream, nodeAudioStream); + streamsMixed += addStreamToMixForListeningNodeWithStream(listenerNodeData, streamUUID, + otherNodeStream, nodeAudioStream); } } } - } + }); + return streamsMixed; } @@ -485,16 +482,11 @@ void AudioMixer::readPendingDatagram(const QByteArray& receivedPacket, const Hif QByteArray packet = receivedPacket; populatePacketHeader(packet, PacketTypeMuteEnvironment); - NodeHashSnapshot snapshotHash = nodeList->getNodeHash().snapshot_table(); - - for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) { - SharedNodePointer node = it->second; - + nodeList->eachNode([&](const SharedNodePointer& node){ if (node->getType() == NodeType::Agent && node->getActiveSocket() && node->getLinkedData() && node != nodeList->sendingNodeForPacket(receivedPacket)) { nodeList->writeDatagram(packet, packet.size(), node); } - } - + }); } else { // let processNodeData handle it. nodeList->processNodeData(senderSockAddr, receivedPacket); @@ -558,9 +550,8 @@ void AudioMixer::sendStatsPacket() { NodeList* nodeList = NodeList::getInstance(); int clientNumber = 0; - NodeHashSnapshot snapshotHash = nodeList->getNodeHash().snapshot_table(); - for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) { + nodeList->eachNode([&](const SharedNodePointer& node) { // if we're too large, send the packet if (sizeOfStats > TOO_BIG_FOR_MTU) { nodeList->sendStatsToDomainServer(statsObject2); @@ -570,15 +561,15 @@ void AudioMixer::sendStatsPacket() { } clientNumber++; - AudioMixerClientData* clientData = static_cast(it->second->getLinkedData()); + AudioMixerClientData* clientData = static_cast(node->getLinkedData()); if (clientData) { - QString property = "jitterStats." + it->first.toString(); + QString property = "jitterStats." + node->getUUID().toString(); QString value = clientData->getAudioStreamStatsString(); statsObject2[qPrintable(property)] = value; somethingToSend = true; sizeOfStats += property.size() + value.size(); } - } + }); if (somethingToSend) { nodeList->sendStatsToDomainServer(statsObject2); @@ -717,10 +708,7 @@ void AudioMixer::run() { _lastPerSecondCallbackTime = now; } - NodeHashSnapshot snapshotHash = nodeList->getNodeHash().snapshot_table(); - - for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) { - SharedNodePointer node = it->second; + nodeList->eachNode([&](const SharedNodePointer& node) { if (node->getLinkedData()) { AudioMixerClientData* nodeData = (AudioMixerClientData*)node->getLinkedData(); @@ -830,7 +818,7 @@ void AudioMixer::run() { ++_sumListeners; } } - } + }); ++_numStatFrames; @@ -888,11 +876,7 @@ void AudioMixer::perSecondActions() { _timeSpentPerHashMatchCallStats.getWindowSum() / WINDOW_LENGTH_USECS * 100.0, _timeSpentPerHashMatchCallStats.getCurrentIntervalSum() / USECS_PER_SECOND * 100.0); - NodeHashSnapshot snapshotHash = NodeList::getInstance()->getNodeHash().snapshot_table(); - - for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) { - SharedNodePointer node = it->second; - + NodeList::getInstance()->eachNode([](const SharedNodePointer& node) { if (node->getLinkedData()) { AudioMixerClientData* nodeData = (AudioMixerClientData*)node->getLinkedData(); @@ -902,7 +886,7 @@ void AudioMixer::perSecondActions() { nodeData->printUpstreamDownstreamStats(); } } - } + }); } _datagramsReadPerCallStats.currentIntervalComplete(); diff --git a/assignment-client/src/avatars/AvatarMixer.cpp b/assignment-client/src/avatars/AvatarMixer.cpp index 3c2fa92c7c..107ce29ac9 100644 --- a/assignment-client/src/avatars/AvatarMixer.cpp +++ b/assignment-client/src/avatars/AvatarMixer.cpp @@ -122,9 +122,7 @@ void AvatarMixer::broadcastAvatarData() { AvatarMixerClientData* nodeData = NULL; AvatarMixerClientData* otherNodeData = NULL; - NodeHashSnapshot snapshotHash = nodeList->getNodeHash().snapshot_table(); - for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) { - SharedNodePointer node = it->second; + nodeList->eachNode([&](const SharedNodePointer& node) { if (node->getLinkedData() && node->getType() == NodeType::Agent && node->getActiveSocket() && (nodeData = reinterpret_cast(node->getLinkedData()))->getMutex().tryLock()) { ++_sumListeners; @@ -137,9 +135,7 @@ void AvatarMixer::broadcastAvatarData() { // this is an AGENT we have received head data from // send back a packet with other active node data to this node - NodeHashSnapshot snapshotHash = nodeList->getNodeHash().snapshot_table(); - for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) { - SharedNodePointer otherNode = it->second; + nodeList->eachNode([&](const SharedNodePointer& otherNode) { if (otherNode->getLinkedData() && otherNode->getUUID() != node->getUUID() && (otherNodeData = reinterpret_cast(otherNode->getLinkedData()))->getMutex().tryLock()) { @@ -207,13 +203,13 @@ void AvatarMixer::broadcastAvatarData() { otherNodeData->getMutex().unlock(); } - } + }); nodeList->writeDatagram(mixedAvatarByteArray, node); nodeData->getMutex().unlock(); } - } + }); _lastFrameTimestamp = QDateTime::currentMSecsSinceEpoch(); } From 881d03b11dd6060c0919d6006683ccbe256071bc Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 6 Nov 2014 13:54:40 -0800 Subject: [PATCH 22/62] migrate EntityServer and OctreeServer to tbb concurrent map --- assignment-client/src/entities/EntityServer.cpp | 9 +++------ assignment-client/src/octree/OctreeServer.cpp | 9 ++++----- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/assignment-client/src/entities/EntityServer.cpp b/assignment-client/src/entities/EntityServer.cpp index 31999f91f7..a39e7acbf4 100644 --- a/assignment-client/src/entities/EntityServer.cpp +++ b/assignment-client/src/entities/EntityServer.cpp @@ -124,11 +124,7 @@ void EntityServer::pruneDeletedEntities() { quint64 earliestLastDeletedEntitiesSent = usecTimestampNow() + 1; // in the future - NodeHashSnapshot snapshotHash = NodeList::getInstance()->getNodeHash().snapshot_table(); - - for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) { - SharedNodePointer node = it->second; - + NodeList::getInstance()->eachNode([&earliestLastDeletedEntitiesSent](const SharedNodePointer& node) { if (node->getLinkedData()) { EntityNodeData* nodeData = static_cast(node->getLinkedData()); quint64 nodeLastDeletedEntitiesSentAt = nodeData->getLastDeletedEntitiesSentAt(); @@ -136,7 +132,8 @@ void EntityServer::pruneDeletedEntities() { earliestLastDeletedEntitiesSent = nodeLastDeletedEntitiesSentAt; } } - } + }); + tree->forgetEntitiesDeletedBefore(earliestLastDeletedEntitiesSent); } } diff --git a/assignment-client/src/octree/OctreeServer.cpp b/assignment-client/src/octree/OctreeServer.cpp index 2b38ce3cdd..e6211a046a 100644 --- a/assignment-client/src/octree/OctreeServer.cpp +++ b/assignment-client/src/octree/OctreeServer.cpp @@ -1138,12 +1138,11 @@ void OctreeServer::aboutToFinish() { qDebug() << qPrintable(_safeServerName) << "inform Octree Inbound Packet Processor that we are shutting down..."; _octreeInboundPacketProcessor->shuttingDown(); - NodeHashSnapshot snapshotHash = NodeList::getInstance()->getNodeHash().snapshot_table(); + NodeList::getInstance()->eachNode([this](const SharedNodePointer& node) { + qDebug() << qPrintable(_safeServerName) << "server about to finish while node still connected node:" << *node; + forceNodeShutdown(node); + }); - for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) { - qDebug() << qPrintable(_safeServerName) << "server about to finish while node still connected node:" << *it->second; - forceNodeShutdown(it->second); - } qDebug() << qPrintable(_safeServerName) << "server ENDING about to finish..."; } From 0e9e8a003692a4ac4b42005da026a53c22b015a1 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 6 Nov 2014 13:56:19 -0800 Subject: [PATCH 23/62] remove libcuckoo and readme --- .gitignore | 4 ---- .../networking/externals/libcuckoo/readme.txt | 14 -------------- 2 files changed, 18 deletions(-) delete mode 100644 libraries/networking/externals/libcuckoo/readme.txt diff --git a/.gitignore b/.gitignore index 74a5748b85..6e6b69cb66 100644 --- a/.gitignore +++ b/.gitignore @@ -32,9 +32,5 @@ DerivedData interface/external/*/* !interface/external/*/readme.txt -# ignore libraries externals -libraries/*/externals/*/* -!libraries/*/externals/*/readme.txt - # Ignore interfaceCache for Linux users interface/interfaceCache/ diff --git a/libraries/networking/externals/libcuckoo/readme.txt b/libraries/networking/externals/libcuckoo/readme.txt deleted file mode 100644 index b86f8bc609..0000000000 --- a/libraries/networking/externals/libcuckoo/readme.txt +++ /dev/null @@ -1,14 +0,0 @@ - -Instructions for adding the libcuckoo library to Interface -Stephen Birarda, November 5, 2014 - -1. Download the libcuckoo ZIP from the High Fidelity libcuckoo fork on Github. - https://github.com/highfidelity/libcuckoo/archive/master.zip - -2. Copy the libcuckoo folder from inside the ZIP to libraries/networking/externals/libcuckoo/. - - You should have the following structure: - - libraries/networking/externals/libcuckoo/libcuckoo/cuckoohash_map.hh - -3. Delete your build directory, run cmake and build, and you should be all set. From 455cbac8a5d4a5c8f2a8869a56e366a288cdcaea Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 6 Nov 2014 15:16:45 -0800 Subject: [PATCH 24/62] repairs to node hash iterations in Application --- interface/src/Application.cpp | 87 ++++++++++++++++------------------- 1 file changed, 40 insertions(+), 47 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index f5842ed4c3..516701d085 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2405,75 +2405,73 @@ int Application::sendNackPackets() { char packet[MAX_PACKET_SIZE]; // iterates thru all nodes in NodeList - NodeHashSnapshot snapshotHash = NodeList::getInstance()->getNodeHash().snapshot_table(); + NodeList* nodeList = NodeList::getInstance(); - for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) { - SharedNodePointer node = it->second; + nodeList->eachNode([&](const SharedNodePointer& node){ - if (node->getActiveSocket() && - ( node->getType() == NodeType::VoxelServer - || node->getType() == NodeType::EntityServer) - ) { - + if (node->getActiveSocket() + && (node->getType() == NodeType::VoxelServer || node->getType() == NodeType::EntityServer)) { + QUuid nodeUUID = node->getUUID(); - + // if there are octree packets from this node that are waiting to be processed, // don't send a NACK since the missing packets may be among those waiting packets. if (_octreeProcessor.hasPacketsToProcessFrom(nodeUUID)) { - continue; + return; } _octreeSceneStatsLock.lockForRead(); - + // retreive octree scene stats of this node if (_octreeServerSceneStats.find(nodeUUID) == _octreeServerSceneStats.end()) { _octreeSceneStatsLock.unlock(); - continue; + return; } - + // get sequence number stats of node, prune its missing set, and make a copy of the missing set SequenceNumberStats& sequenceNumberStats = _octreeServerSceneStats[nodeUUID].getIncomingOctreeSequenceNumberStats(); sequenceNumberStats.pruneMissingSet(); const QSet missingSequenceNumbers = sequenceNumberStats.getMissingSet(); - + _octreeSceneStatsLock.unlock(); - + // construct nack packet(s) for this node int numSequenceNumbersAvailable = missingSequenceNumbers.size(); QSet::const_iterator missingSequenceNumbersIterator = missingSequenceNumbers.constBegin(); while (numSequenceNumbersAvailable > 0) { - + char* dataAt = packet; int bytesRemaining = MAX_PACKET_SIZE; - + // pack header int numBytesPacketHeader = populatePacketHeader(packet, PacketTypeOctreeDataNack); dataAt += numBytesPacketHeader; bytesRemaining -= numBytesPacketHeader; - + // calculate and pack the number of sequence numbers int numSequenceNumbersRoomFor = (bytesRemaining - sizeof(uint16_t)) / sizeof(OCTREE_PACKET_SEQUENCE); uint16_t numSequenceNumbers = min(numSequenceNumbersAvailable, numSequenceNumbersRoomFor); uint16_t* numSequenceNumbersAt = (uint16_t*)dataAt; *numSequenceNumbersAt = numSequenceNumbers; dataAt += sizeof(uint16_t); - + // pack sequence numbers for (int i = 0; i < numSequenceNumbers; i++) { OCTREE_PACKET_SEQUENCE* sequenceNumberAt = (OCTREE_PACKET_SEQUENCE*)dataAt; *sequenceNumberAt = *missingSequenceNumbersIterator; dataAt += sizeof(OCTREE_PACKET_SEQUENCE); - + missingSequenceNumbersIterator++; } numSequenceNumbersAvailable -= numSequenceNumbers; - + // send it - NodeList::getInstance()->writeUnverifiedDatagram(packet, dataAt - packet, node); + nodeList->writeUnverifiedDatagram(packet, dataAt - packet, node); packetsSent++; } } - } + }); + return packetsSent; } @@ -2507,12 +2505,8 @@ void Application::queryOctree(NodeType_t serverType, PacketType packetType, Node int unknownJurisdictionServers = 0; NodeList* nodeList = NodeList::getInstance(); - NodeHashSnapshot snapshotHash = nodeList->getNodeHash().snapshot_table(); - for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) { - - SharedNodePointer node = it->second; - + nodeList->eachNode([&](const SharedNodePointer& node) { // only send to the NodeTypes that are serverType if (node->getActiveSocket() && node->getType() == serverType) { totalServers++; @@ -2543,7 +2537,7 @@ void Application::queryOctree(NodeType_t serverType, PacketType packetType, Node } } } - } + }); if (wantExtraDebugging) { qDebug("Servers: total %d, in view %d, unknown jurisdiction %d", @@ -2570,18 +2564,17 @@ void Application::queryOctree(NodeType_t serverType, PacketType packetType, Node qDebug("perServerPPS: %d perUnknownServer: %d", perServerPPS, perUnknownServer); } - for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) { - SharedNodePointer node = it->second; + 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()) { @@ -2591,15 +2584,15 @@ void Application::queryOctree(NodeType_t serverType, PacketType packetType, Node } } else { const JurisdictionMap& map = (jurisdictions)[nodeUUID]; - + unsigned char* rootCode = map.getRootOctalCode(); - + if (rootCode) { VoxelPositionSize rootDetails; voxelDetailsForCode(rootCode, rootDetails); AACube serverBounds(glm::vec3(rootDetails.x, rootDetails.y, rootDetails.z), rootDetails.s); serverBounds.scale(TREE_SCALE); - + ViewFrustum::location serverFrustumLocation = _viewFrustum.cubeInFrustum(serverBounds); if (serverFrustumLocation != ViewFrustum::OUTSIDE) { inView = true; @@ -2612,15 +2605,15 @@ void Application::queryOctree(NodeType_t serverType, PacketType packetType, Node } } } - + if (inView) { _octreeQuery.setMaxOctreePacketsPerSecond(perServerPPS); } else if (unknownView) { if (wantExtraDebugging) { qDebug() << "no known jurisdiction for node " << *node << ", give it budget of " - << perUnknownServer << " to send us jurisdiction."; + << 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 @@ -2644,22 +2637,22 @@ void Application::queryOctree(NodeType_t serverType, PacketType packetType, Node } // set up the packet for sending... unsigned char* endOfQueryPacket = queryPacket; - + // insert packet type/version and node UUID endOfQueryPacket += populatePacketHeader(reinterpret_cast(endOfQueryPacket), packetType); - + // encode the query data... endOfQueryPacket += _octreeQuery.getBroadcastData(endOfQueryPacket); - + int packetLength = endOfQueryPacket - queryPacket; - + // make sure we still have an active socket nodeList->writeUnverifiedDatagram(reinterpret_cast(queryPacket), packetLength, node); - + // Feed number of bytes to corresponding channel of the bandwidth meter _bandwidthMeter.outputStream(BandwidthMeter::VOXELS).updateValue(packetLength); } - } + }); } ///////////////////////////////////////////////////////////////////////////////////// From aa7e99567253708152e69a5aff0681d1174631f6 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 6 Nov 2014 15:18:56 -0800 Subject: [PATCH 25/62] update MetavoxelSystem.cpp to new tbb node iteration --- interface/src/MetavoxelSystem.cpp | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/interface/src/MetavoxelSystem.cpp b/interface/src/MetavoxelSystem.cpp index 20a7bc906f..2ca17e32c1 100644 --- a/interface/src/MetavoxelSystem.cpp +++ b/interface/src/MetavoxelSystem.cpp @@ -163,12 +163,7 @@ void MetavoxelSystem::render() { } void MetavoxelSystem::refreshVoxelData() { - NodeHashSnapshot snapshotHash = NodeList::getInstance()->getNodeHash().snapshot_table(); - - for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) { - - SharedNodePointer node = it->second; - + NodeList::getInstance()->eachNode([](const SharedNodePointer& node){ if (node->getType() == NodeType::MetavoxelServer) { QMutexLocker locker(&node->getMutex()); MetavoxelSystemClient* client = static_cast(node->getLinkedData()); @@ -176,7 +171,7 @@ void MetavoxelSystem::refreshVoxelData() { QMetaObject::invokeMethod(client, "refreshVoxelData"); } } - } + }); } class RayHeightfieldIntersectionVisitor : public RayIntersectionVisitor { @@ -690,11 +685,7 @@ MetavoxelClient* MetavoxelSystem::createClient(const SharedNodePointer& node) { } void MetavoxelSystem::guideToAugmented(MetavoxelVisitor& visitor, bool render) { - NodeHashSnapshot snapshotHash = NodeList::getInstance()->getNodeHash().snapshot_table(); - - for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) { - SharedNodePointer node = it->second; - + NodeList::getInstance()->eachNode([&visitor, &render](const SharedNodePointer& node) { if (node->getType() == NodeType::MetavoxelServer) { QMutexLocker locker(&node->getMutex()); MetavoxelSystemClient* client = static_cast(node->getLinkedData()); @@ -708,7 +699,7 @@ void MetavoxelSystem::guideToAugmented(MetavoxelVisitor& visitor, bool render) { } } } - } + }); } Throttle::Throttle() : From d82e2fb8f448c8b8a40658a71be377c458bb655b Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 6 Nov 2014 15:21:18 -0800 Subject: [PATCH 26/62] update NodeBounds.cpp to new tbb node iteration --- interface/src/ui/NodeBounds.cpp | 38 +++++++++++++++------------------ 1 file changed, 17 insertions(+), 21 deletions(-) diff --git a/interface/src/ui/NodeBounds.cpp b/interface/src/ui/NodeBounds.cpp index 6298385c90..dedc687cc2 100644 --- a/interface/src/ui/NodeBounds.cpp +++ b/interface/src/ui/NodeBounds.cpp @@ -53,65 +53,61 @@ void NodeBounds::draw() { float selectedScale = 0; NodeList* nodeList = NodeList::getInstance(); - NodeHashSnapshot snapshotHash = nodeList->getNodeHash().snapshot_table(); - - for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) { - SharedNodePointer node = it->second; - + nodeList->eachNode([&](const SharedNodePointer& node){ NodeType_t nodeType = node->getType(); - + if (nodeType == NodeType::VoxelServer && _showVoxelNodes) { serverJurisdictions = &voxelServerJurisdictions; } else if (nodeType == NodeType::EntityServer && _showEntityNodes) { serverJurisdictions = &entityServerJurisdictions; } else { - continue; + return; } - + QUuid nodeUUID = node->getUUID(); serverJurisdictions->lockForRead(); if (serverJurisdictions->find(nodeUUID) != serverJurisdictions->end()) { const JurisdictionMap& map = (*serverJurisdictions)[nodeUUID]; - + unsigned char* rootCode = map.getRootOctalCode(); - + if (rootCode) { VoxelPositionSize rootDetails; voxelDetailsForCode(rootCode, rootDetails); serverJurisdictions->unlock(); glm::vec3 location(rootDetails.x, rootDetails.y, rootDetails.z); location *= (float)TREE_SCALE; - + AACube serverBounds(location, rootDetails.s * TREE_SCALE); - + glm::vec3 center = serverBounds.getVertex(BOTTOM_RIGHT_NEAR) - + ((serverBounds.getVertex(TOP_LEFT_FAR) - serverBounds.getVertex(BOTTOM_RIGHT_NEAR)) / 2.0f); - + + ((serverBounds.getVertex(TOP_LEFT_FAR) - serverBounds.getVertex(BOTTOM_RIGHT_NEAR)) / 2.0f); + const float VOXEL_NODE_SCALE = 1.00f; const float ENTITY_NODE_SCALE = 0.99f; - + float scaleFactor = rootDetails.s * TREE_SCALE; - + // Scale by 0.92 - 1.00 depending on the scale of the node. This allows smaller nodes to scale in // a bit and not overlap larger nodes. scaleFactor *= 0.92 + (rootDetails.s * 0.08); - + // Scale different node types slightly differently because it's common for them to overlap. if (nodeType == NodeType::VoxelServer) { scaleFactor *= VOXEL_NODE_SCALE; } else if (nodeType == NodeType::EntityServer) { scaleFactor *= ENTITY_NODE_SCALE; } - + float red, green, blue; getColorForNodeType(nodeType, red, green, blue); drawNodeBorder(center, scaleFactor, red, green, blue); - + float distance; BoxFace face; bool inside = serverBounds.contains(mouseRayOrigin); bool colliding = serverBounds.findRayIntersection(mouseRayOrigin, mouseRayDirection, distance, face); - + // If the camera is inside a node it will be "selected" if you don't have your cursor over another node // that you aren't inside. if (colliding && (!selectedNode || (!inside && (distance < selectedDistance || selectedIsInside)))) { @@ -127,7 +123,7 @@ void NodeBounds::draw() { } else { serverJurisdictions->unlock(); } - } + }); if (selectedNode) { glPushMatrix(); From ce02d79d415e9ef4411ffc03fe971ccafb2d676c Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 6 Nov 2014 15:22:30 -0800 Subject: [PATCH 27/62] update OctreeStatsDialog to new tbb node iteration --- interface/src/ui/OctreeStatsDialog.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/interface/src/ui/OctreeStatsDialog.cpp b/interface/src/ui/OctreeStatsDialog.cpp index 8a6d6442f5..14da45e1d1 100644 --- a/interface/src/ui/OctreeStatsDialog.cpp +++ b/interface/src/ui/OctreeStatsDialog.cpp @@ -248,10 +248,8 @@ void OctreeStatsDialog::showOctreeServersOfType(int& serverCount, NodeType_t ser QLocale locale(QLocale::English); NodeList* nodeList = NodeList::getInstance(); - NodeHashSnapshot snapshotHash = nodeList->getNodeHash().snapshot_table(); - - for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) { - SharedNodePointer node = it->second; + nodeList->eachNode([&](const SharedNodePointer& node){ + // only send to the NodeTypes that are NodeType_t_VOXEL_SERVER if (node->getType() == serverType) { serverCount++; @@ -422,7 +420,7 @@ void OctreeStatsDialog::showOctreeServersOfType(int& serverCount, NodeType_t ser serverDetails << linkDetails.str(); _labels[_voxelServerLables[serverCount - 1]]->setText(serverDetails.str().c_str()); } // is VOXEL_SERVER - } + }); } void OctreeStatsDialog::reject() { From 2f66e56e46eb3f900f2b9385259e6b319b7c2821 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 6 Nov 2014 15:23:30 -0800 Subject: [PATCH 28/62] update Stats to new tbb node iteration --- interface/src/ui/Stats.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/interface/src/ui/Stats.cpp b/interface/src/ui/Stats.cpp index 8e4b900180..08eaac9334 100644 --- a/interface/src/ui/Stats.cpp +++ b/interface/src/ui/Stats.cpp @@ -329,10 +329,7 @@ void Stats::display( unsigned long totalPingVoxel = 0; int voxelServerCount = 0; - NodeHashSnapshot snapshotHash = nodeList->getNodeHash().snapshot_table(); - - for (auto it = snapshotHash.begin(); it != snapshotHash.end(); it++) { - SharedNodePointer node = it->second; + nodeList->eachNode([&totalPingVoxel, &pingVoxelMax, &voxelServerCount](const SharedNodePointer& node){ // TODO: this should also support entities if (node->getType() == NodeType::VoxelServer) { totalPingVoxel += node->getPingMs(); @@ -341,7 +338,7 @@ void Stats::display( pingVoxelMax = node->getPingMs(); } } - } + }); if (voxelServerCount) { pingVoxel = totalPingVoxel/voxelServerCount; From 996c76c723f4dd591707be56da8ad74ecbce06fb Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 6 Nov 2014 16:05:01 -0800 Subject: [PATCH 29/62] repairs for node teardown on domain dissappear or node disconnect --- domain-server/src/DomainServer.cpp | 4 +-- libraries/networking/src/LimitedNodeList.cpp | 34 ++++++++++++++++---- libraries/networking/src/LimitedNodeList.h | 2 ++ 3 files changed, 31 insertions(+), 9 deletions(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index cb4b1c8026..153fbae0c9 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -2019,9 +2019,9 @@ void DomainServer::addStaticAssignmentsToQueue() { QHash::iterator staticAssignment = staticHashCopy.begin(); while (staticAssignment != staticHashCopy.end()) { // add any of the un-matched static assignments to the queue - + // enumerate the nodes and check if there is one with an attached assignment with matching UUID - if (NodeList::getInstance()->nodeWithUUID(staticAssignment->data()->getUUID())) { + if (!NodeList::getInstance()->nodeWithUUID(staticAssignment->data()->getUUID())) { // this assignment has not been fulfilled - reset the UUID and add it to the assignment queue refreshStaticAssignmentAndAddToQueue(*staticAssignment); } diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index ac63941882..767935bf3d 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -359,11 +359,18 @@ SharedNodePointer LimitedNodeList::sendingNodeForPacket(const QByteArray& packet void LimitedNodeList::eraseAllNodes() { qDebug() << "Clearing the NodeList. Deleting all nodes in list."; + QSet killedNodes; + eachNode([&killedNodes](const SharedNodePointer& node){ + killedNodes.insert(node); + }); + // iterate the current nodes, emit that they are dying and remove them from the hash - QWriteLocker writeLock(&_nodeMutex); - for (NodeHash::iterator it = _nodeHash.begin(); it != _nodeHash.end(); ++it) { - emit nodeKilled(it->second); - it = _nodeHash.unsafe_erase(it); + _nodeMutex.lockForWrite(); + _nodeHash.clear(); + _nodeMutex.unlock(); + + foreach(const SharedNodePointer& killedNode, killedNodes) { + handleNodeKill(killedNode); } } @@ -378,7 +385,8 @@ void LimitedNodeList::killNodeWithUUID(const QUuid& nodeUUID) { QWriteLocker writeLocker(&_nodeMutex); _nodeHash.unsafe_erase(it); - emit nodeKilled(matchingNode); + + handleNodeKill(matchingNode); } } @@ -390,6 +398,11 @@ void LimitedNodeList::processKillNode(const QByteArray& dataByteArray) { killNodeWithUUID(nodeUUID); } +void LimitedNodeList::handleNodeKill(const SharedNodePointer& node) { + qDebug() << "Killed" << *node; + emit nodeKilled(node); +} + SharedNodePointer LimitedNodeList::addOrUpdateNode(const QUuid& uuid, NodeType_t nodeType, const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket) { try { @@ -478,14 +491,17 @@ void LimitedNodeList::resetPacketStats() { } void LimitedNodeList::removeSilentNodes() { - eachNodeHashIterator([this](NodeHash::iterator& it){ + QSet killedNodes; + + eachNodeHashIterator([&](NodeHash::iterator& it){ SharedNodePointer node = it->second; node->getMutex().lock(); if ((usecTimestampNow() - node->getLastHeardMicrostamp()) > (NODE_SILENCE_THRESHOLD_MSECS * 1000)) { // call the NodeHash erase to get rid of this node it = _nodeHash.unsafe_erase(it); - emit nodeKilled(node); + + killedNodes.insert(node); } else { // we didn't erase this node, push the iterator forwards ++it; @@ -493,6 +509,10 @@ void LimitedNodeList::removeSilentNodes() { node->getMutex().unlock(); }); + + foreach(const SharedNodePointer& killedNode, killedNodes) { + handleNodeKill(killedNode); + } } const uint32_t RFC_5389_MAGIC_COOKIE = 0x2112A442; diff --git a/libraries/networking/src/LimitedNodeList.h b/libraries/networking/src/LimitedNodeList.h index a29902a7c9..d713f69d29 100644 --- a/libraries/networking/src/LimitedNodeList.h +++ b/libraries/networking/src/LimitedNodeList.h @@ -187,6 +187,8 @@ protected: const QUuid& connectionSecret); void changeSocketBufferSizes(int numBytes); + + void handleNodeKill(const SharedNodePointer& node); QUuid _sessionUUID; NodeHash _nodeHash; From a688f48bf7678f6e2563ccafa677465c8e3dd1f4 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 15 Dec 2014 10:02:01 -0800 Subject: [PATCH 30/62] indicate that user should run tbbvars for FindTBB --- BUILD.md | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/BUILD.md b/BUILD.md index e1d920b8df..f676c29a9d 100644 --- a/BUILD.md +++ b/BUILD.md @@ -5,6 +5,7 @@ Dependencies * [glm](http://glm.g-truc.net/0.9.5/index.html) ~> 0.9.5.2 * [OpenSSL](https://www.openssl.org/related/binaries.html) ~> 1.0.1g * IMPORTANT: OpenSSL 1.0.1g is critical to avoid a security vulnerability. +* [Intel Threading Building Blocks](https://www.threadingbuildingblocks.org/) ~> 4.3 #####Linux only * [freeglut](http://freeglut.sourceforge.net/) ~> 2.8.0 @@ -55,7 +56,7 @@ In the examples below the variable $NAME would be replaced by the name of the de UNIX === -In general, as long as external dependencies are placed in OS standard locations, CMake will successfully find them during its run. When possible, you may choose to install depencies from your package manager of choice, or from source. +In general, as long as external dependencies are placed in OS standard locations, CMake will successfully find them during its run. When possible, you may choose to install depencies from your package manager of choice, or from source. ####Linux Should you choose not to install Qt5 via a package manager that handles dependencies for you, you may be missing some Qt5 dependencies. On Ubuntu, for example, the following additional packages are required: @@ -67,7 +68,7 @@ Should you choose not to install Qt5 via a package manager that handles dependen [Homebrew](http://brew.sh/) is an excellent package manager for OS X. It makes install of all hifi dependencies very simple. brew tap highfidelity/homebrew-formulas - brew install cmake glm openssl + brew install cmake glm openssl tbb brew install highfidelity/formulas/qt5 brew link qt5 --force @@ -173,6 +174,9 @@ The recommended route for CMake to find the external dependencies is to place al -> bin -> include -> lib + -> tbb + -> include + -> lib -> zlib -> include -> lib @@ -202,6 +206,12 @@ To prevent these problems, install OpenSSL yourself. Download the following bina Install OpenSSL into the Windows system directory, to make sure that QT uses the version that you've just installed, and not some other version. +#### Intel Threading Building Blocks (TBB) + +Download the stable release for Windows from the [Intel Threading Building Blocks website](https://www.threadingbuildingblocks.org/). By default, TBB will install to Program Files. You may also choose to install it to %HIFI_LIB_DIR%\TBB. + +You must run `tbbvars.bat` so that the find module included with this project will be able to find TBB no matter where you installed it. `tbbvars.bat` is located in the 'bin' folder of your TBB install. For a default installation on a 64-bit architechture, tbbvars can be found at `C:/Program Files (x86)/Intel/TBB/bin/tbbvars.bat`. + #### Zlib Download the compiled DLL from the [zlib website](http://www.zlib.net/). Extract to %HIFI_LIB_DIR%\zlib. From ce6334535b3b0ce6206f80b05483aa8449398316 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 15 Dec 2014 10:08:48 -0800 Subject: [PATCH 31/62] add info for TBB to Linux section --- BUILD.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/BUILD.md b/BUILD.md index f676c29a9d..522e994ea4 100644 --- a/BUILD.md +++ b/BUILD.md @@ -63,6 +63,12 @@ Should you choose not to install Qt5 via a package manager that handles dependen libasound2 libxmu-dev libxi-dev freeglut3-dev libasound2-dev libjack-dev +##### Intel Threading Building Blocks (TBB) + +Install Intel TBB from your package manager of choice, or from source (available at the [TBB Website](https://www.threadingbuildingblocks.org/)). + +You must run `tbbvars` so that the find module included with this project will be able to find the correct version of TBB. `tbbvars` is located in the 'bin' folder of your TBB install. + ####OS X #####Package Managers [Homebrew](http://brew.sh/) is an excellent package manager for OS X. It makes install of all hifi dependencies very simple. From d65f435e2832bc044379266cdce5425e634732c4 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 15 Dec 2014 10:10:31 -0800 Subject: [PATCH 32/62] change Qt version referenced in build guide --- BUILD.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/BUILD.md b/BUILD.md index 522e994ea4..b884b5588e 100644 --- a/BUILD.md +++ b/BUILD.md @@ -1,7 +1,7 @@ Dependencies === * [cmake](http://www.cmake.org/cmake/resources/software.html) ~> 2.8.12.2 -* [Qt](http://qt-project.org/downloads) ~> 5.2.0 +* [Qt](http://qt-project.org/downloads) ~> 5.3.0 * [glm](http://glm.g-truc.net/0.9.5/index.html) ~> 0.9.5.2 * [OpenSSL](https://www.openssl.org/related/binaries.html) ~> 1.0.1g * IMPORTANT: OpenSSL 1.0.1g is critical to avoid a security vulnerability. @@ -80,7 +80,7 @@ You must run `tbbvars` so that the find module included with this project will b We have a [homebrew formulas repository](https://github.com/highfidelity/homebrew-formulas) that you can use/tap to install some of the dependencies. In the code block above qt5 is installed from a formula in this repository. -*Our [qt5 homebrew formula](https://raw.github.com/highfidelity/homebrew-formulas/master/qt5.rb) is for a patched version of Qt 5.2.0 stable that removes wireless network scanning that can reduce real-time audio performance. We recommended you use this formula to install Qt.* +*Our [qt5 homebrew formula](https://raw.github.com/highfidelity/homebrew-formulas/master/qt5.rb) is for a patched version of Qt 5.3.x stable that removes wireless network scanning that can reduce real-time audio performance. We recommended you use this formula to install Qt.* #####Xcode If Xcode is your editor of choice, you can ask CMake to generate Xcode project files instead of Unix Makefiles. From 5ad4a57e3dedd7ab8a72c15827fd23944ed994be Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 15 Dec 2014 10:19:06 -0800 Subject: [PATCH 33/62] add OS specific build files --- BUILD.md | 240 ++----------------------------------------------- BUILD_LINUX.md | 18 ++++ BUILD_OSX.md | 22 +++++ BUILD_WIN.md | 180 +++++++++++++++++++++++++++++++++++++ 4 files changed, 228 insertions(+), 232 deletions(-) create mode 100644 BUILD_LINUX.md create mode 100644 BUILD_OSX.md create mode 100644 BUILD_WIN.md diff --git a/BUILD.md b/BUILD.md index b884b5588e..867e515209 100644 --- a/BUILD.md +++ b/BUILD.md @@ -1,5 +1,5 @@ -Dependencies -=== +###Dependencies + * [cmake](http://www.cmake.org/cmake/resources/software.html) ~> 2.8.12.2 * [Qt](http://qt-project.org/downloads) ~> 5.3.0 * [glm](http://glm.g-truc.net/0.9.5/index.html) ~> 0.9.5.2 @@ -7,28 +7,18 @@ Dependencies * IMPORTANT: OpenSSL 1.0.1g is critical to avoid a security vulnerability. * [Intel Threading Building Blocks](https://www.threadingbuildingblocks.org/) ~> 4.3 -#####Linux only -* [freeglut](http://freeglut.sourceforge.net/) ~> 2.8.0 -* [zLib](http://www.zlib.net/) ~> 1.2.8 - -#####Windows only -* [GLEW](http://glew.sourceforge.net/) ~> 1.10.0 -* [freeglut MSVC](http://www.transmissionzero.co.uk/software/freeglut-devel/) ~> 2.8.1 -* [zLib](http://www.zlib.net/) ~> 1.2.8 - -CMake -=== +###CMake Hifi uses CMake to generate build files and project files for your platform. ####Qt In order for CMake to find the Qt5 find modules, you will need to set an ENV variable pointing to your Qt installation. -For example, a Qt5 5.2.0 installation to /usr/local/qt5 would require that QT_CMAKE_PREFIX_PATH be set with the following command. This can either be entered directly into your shell session before you build or in your shell profile (e.g.: ~/.bash_profile, ~/.bashrc, ~/.zshrc - this depends on your shell and environment). +For example, a Qt5 5.3.2 installation to /usr/local/qt5 would require that QT_CMAKE_PREFIX_PATH be set with the following command. This can either be entered directly into your shell session before you build or in your shell profile (e.g.: ~/.bash_profile, ~/.bashrc, ~/.zshrc - this depends on your shell and environment). The path it needs to be set to will depend on where and how Qt5 was installed. e.g. - export QT_CMAKE_PREFIX_PATH=/usr/local/qt/5.2.0/clang_64/lib/cmake/ - export QT_CMAKE_PREFIX_PATH=/usr/local/Cellar/qt5/5.2.1/lib/cmake + export QT_CMAKE_PREFIX_PATH=/usr/local/qt/5.3.2/clang_64/lib/cmake/ + export QT_CMAKE_PREFIX_PATH=/usr/local/Cellar/qt5/5.3.2/lib/cmake export QT_CMAKE_PREFIX_PATH=/usr/local/opt/qt5/lib/cmake ####Generating build files @@ -54,221 +44,7 @@ In the examples below the variable $NAME would be replaced by the name of the de * $NAME_ROOT_DIR - set this variable in your ENV * HIFI_LIB_DIR - set this variable in your ENV to your High Fidelity lib folder, should contain a folder '$name' -UNIX -=== -In general, as long as external dependencies are placed in OS standard locations, CMake will successfully find them during its run. When possible, you may choose to install depencies from your package manager of choice, or from source. - -####Linux -Should you choose not to install Qt5 via a package manager that handles dependencies for you, you may be missing some Qt5 dependencies. On Ubuntu, for example, the following additional packages are required: - - libasound2 libxmu-dev libxi-dev freeglut3-dev libasound2-dev libjack-dev - -##### Intel Threading Building Blocks (TBB) - -Install Intel TBB from your package manager of choice, or from source (available at the [TBB Website](https://www.threadingbuildingblocks.org/)). - -You must run `tbbvars` so that the find module included with this project will be able to find the correct version of TBB. `tbbvars` is located in the 'bin' folder of your TBB install. - -####OS X -#####Package Managers -[Homebrew](http://brew.sh/) is an excellent package manager for OS X. It makes install of all hifi dependencies very simple. - - brew tap highfidelity/homebrew-formulas - brew install cmake glm openssl tbb - brew install highfidelity/formulas/qt5 - brew link qt5 --force - -We have a [homebrew formulas repository](https://github.com/highfidelity/homebrew-formulas) that you can use/tap to install some of the dependencies. In the code block above qt5 is installed from a formula in this repository. - -*Our [qt5 homebrew formula](https://raw.github.com/highfidelity/homebrew-formulas/master/qt5.rb) is for a patched version of Qt 5.3.x stable that removes wireless network scanning that can reduce real-time audio performance. We recommended you use this formula to install Qt.* - -#####Xcode -If Xcode is your editor of choice, you can ask CMake to generate Xcode project files instead of Unix Makefiles. - - cmake .. -GXcode - -After running cmake, you will have the make files or Xcode project file necessary to build all of the components. Open the hifi.xcodeproj file, choose ALL_BUILD from the Product > Scheme menu (or target drop down), and click Run. - -If the build completes successfully, you will have built targets for all components located in the `build/${target_name}/Debug` directories. - -Windows -=== -####Visual Studio - -Currently building on Windows has been tested using the following compilers: -* Visual Studio C++ 2010 Express -* Visual Studio 2013 - -(If anyone can test using Visual Studio 2013 Express then please update this document) - -#####Windows SDK 7.1 - -If using Visual Studio 2010, or using Visual Studio 2013 but building as a Visual Studio 2010 project, you need [Microsoft Windows SDK for Windows 7 and .NET Framework 4](http://www.microsoft.com/en-us/download/details.aspx?id=8279). - -NOTE: If using Visual Studio C++ 2010 Express, you need to follow a specific install order. See below before installing the Windows SDK. - -######Windows SDK 8.1 - -If using Visual Studio 2013 and building as a Visual Studio 2013 project you need the Windows 8 SDK which you should already have as part of installing Visual Studio 2013. You should be able to see it at `C:\Program Files (x86)\Windows Kits\8.1\Lib\winv6.3\um\x86`. - -#####Visual Studio C++ 2010 Express - -Visual Studio C++ 2010 Express can be downloaded [here](http://www.visualstudio.com/en-us/downloads#d-2010-express). - -The following patches/service packs are also required: -* [VS2010 SP1](http://www.microsoft.com/en-us/download/details.aspx?id=23691) -* [VS2010 SP1 Compiler Update](http://www.microsoft.com/en-us/download/details.aspx?id=4422) - -IMPORTANT: Use the following install order: -Visual Studio C++ 2010 Express -Windows SDK 7.1 -VS2010 SP1 -VS2010 SP1 Compiler Update - -If you get an error while installing the VS2010 SP1 Compiler update saying that you don't have the Windows SDK installed, then uninstall all of the above and start again in the correct order. - -Some of the build instructions will ask you to start a Visual Studio Command Prompt. You should have a shortcut in your Start menu called "Open Visual Studio Command Prompt (2010)" which will do so. - -#####Visual Studio 2013 - -You can use the Community or Professional editions of Visual Studio 2013. - -You can start a Visual Studio 2013 command prompt using the shortcut provided in the Visual Studio Tools folder installed as part of Visual Studio 2013. - -Or you can start a regular command prompt and then run: - - "%VS120COMNTOOLS%\vsvars32.bat" - -If you experience issues building interface on Visual Studio 2013, try generating the build files with Visual Studio 2010 instead. To do so, download Visual Studio 2010 and run `cmake .. -G "Visual Studio 10"` (Assuming running from %HIFI_DIR%\build). - -####Qt -You can use the online installer or the offline installer. If you use the offline installer, be sure to select the "OpenGL" version. - -NOTE: Qt does not support 64-bit builds on Windows 7, so you must use the 32-bit version of libraries for interface.exe to run. The 32-bit version of the static library is the one linked by our CMake find modules. - -* Download the online installer [here](http://qt-project.org/downloads) - * When it asks you to select components, ONLY select the following: - * Qt > Qt 5.2.0 > **msvc2010 32-bit OpenGL** - -* Download the offline installer [here](http://download.qt-project.org/official_releases/qt/5.2/5.2.0/qt-windows-opensource-5.2.0-msvc2010_opengl-x86-offline.exe) - -Once Qt is installed, you need to manually configure the following: -* Make sure the Qt runtime DLLs are loadable. You must do this before you attempt to build because some tools for the build depend on Qt. E.g., add to the PATH: `Qt\5.2.0\msvc2010_opengl\bin\`. -* Set the QT_CMAKE_PREFIX_PATH environment variable to your `Qt\5.2.0\msvc2010_opengl` directory. - -If building as a Visual Studio 2013 project, download and configure the msvc2013 version of Qt instead. - -####External Libraries - -CMake will need to know where the headers and libraries for required external dependencies are. - -The recommended route for CMake to find the external dependencies is to place all of the dependencies in one folder and set one ENV variable - HIFI_LIB_DIR. That ENV variable should point to a directory with the following structure: - - root_lib_dir - -> freeglut - -> bin - -> include - -> lib - -> glew - -> bin - -> include - -> lib - -> glm - -> glm - -> glm.hpp - -> openssl - -> bin - -> include - -> lib - -> tbb - -> include - -> lib - -> zlib - -> include - -> lib - -> test - -For many of the external libraries where precompiled binaries are readily available you should be able to simply copy the extracted folder that you get from the download links provided at the top of the guide. Otherwise you may need to build from source and install the built product to this directory. The `root_lib_dir` in the above example can be wherever you choose on your system - as long as the environment variable HIFI_LIB_DIR is set to it. From here on, whenever you see %HIFI_LIB_DIR% you should substitute the directory that you chose. - -As with the Qt libraries, you will need to make sure that directories containing DLL'S are in your path. Where possible, you can use static builds of the external dependencies to avoid this requirement. - -#### OpenSSL - -QT will use OpenSSL if it's available, but it doesn't install it, so you must install it separately. - -Your system may already have several versions of the OpenSSL DLL's (ssleay32.dll, libeay32.dll) lying around, but they may be the wrong version. If these DLL's are in the PATH then QT will try to use them, and if they're the wrong version then you will see the following errors in the console: - - QSslSocket: cannot resolve TLSv1_1_client_method - QSslSocket: cannot resolve TLSv1_2_client_method - QSslSocket: cannot resolve TLSv1_1_server_method - QSslSocket: cannot resolve TLSv1_2_server_method - QSslSocket: cannot resolve SSL_select_next_proto - QSslSocket: cannot resolve SSL_CTX_set_next_proto_select_cb - QSslSocket: cannot resolve SSL_get0_next_proto_negotiated - -To prevent these problems, install OpenSSL yourself. Download the following binary packages [from this website](http://slproweb.com/products/Win32OpenSSL.html): -* Visual C++ 2008 Redistributables -* Win32 OpenSSL v1.0.1h - -Install OpenSSL into the Windows system directory, to make sure that QT uses the version that you've just installed, and not some other version. - -#### Intel Threading Building Blocks (TBB) - -Download the stable release for Windows from the [Intel Threading Building Blocks website](https://www.threadingbuildingblocks.org/). By default, TBB will install to Program Files. You may also choose to install it to %HIFI_LIB_DIR%\TBB. - -You must run `tbbvars.bat` so that the find module included with this project will be able to find TBB no matter where you installed it. `tbbvars.bat` is located in the 'bin' folder of your TBB install. For a default installation on a 64-bit architechture, tbbvars can be found at `C:/Program Files (x86)/Intel/TBB/bin/tbbvars.bat`. - -#### Zlib - -Download the compiled DLL from the [zlib website](http://www.zlib.net/). Extract to %HIFI_LIB_DIR%\zlib. - -Add the following environment variables (remember to substitute your own directory for %HIFI_LIB_DIR%): - - ZLIB_LIBRARY=%HIFI_LIB_DIR%\zlib\lib\zdll.lib - ZLIB_INCLUDE_DIR=%HIFI_LIB_DIR%\zlib\include - -Add to the PATH: `%HIFI_LIB_DIR%\zlib` - -Important! This should be added at the beginning of the path, not the end. That's because your -system likely has many copies of zlib1.dll, and you want High Fidelity to use the correct version. If High Fidelity picks up the wrong zlib1.dll then it might be unable to use it, and that would cause it to fail to start, showing only the cryptic error "The application was unable to start correctly: 0xc0000022". - -#### freeglut - -Download the binary package: `freeglut-MSVC-2.8.1-1.mp.zip`. Extract to %HIFI_LIB_DIR%\freeglut. - -Add to the PATH: `%HIFI_LIB_DIR%\freeglut\bin` - -#### GLEW - -Download the binary package: `glew-1.10.0-win32.zip`. Extract to %HIFI_LIB_DIR%\glew (you'll need to rename the default directory name). - -Add to the PATH: `%HIFI_LIB_DIR%\glew\bin\Release\Win32` - -#### GLM - -This package contains only headers, so there's nothing to add to the PATH. - -Be careful with glm. For the folder other libraries would normally call 'include', the folder containing the headers, glm opts to use 'glm'. You will have a glm folder nested inside the top-level glm folder. - -#### Build High Fidelity using Visual Studio -Follow the same build steps from the CMake section, but pass a different generator to CMake. - - cmake .. -DZLIB_LIBRARY=%ZLIB_LIBRARY% -DZLIB_INCLUDE_DIR=%ZLIB_INCLUDE_DIR% -G "Visual Studio 10" - -If you're using Visual Studio 2013 then pass "Visual Studio 12" instead of "Visual Studio 10" (yes, 12, not 13). - -Open %HIFI_DIR%\build\hifi.sln and compile. - -####Running Interface -If you need to debug Interface, you can run interface from within Visual Studio (see the section below). You can also run Interface by launching it from command line or File Explorer from %HIFI_DIR%\build\interface\Debug\interface.exe - -####Debugging Interface -* In the Solution Explorer, right click interface and click Set as StartUp Project -* Set the "Working Directory" for the Interface debugging sessions to the Debug output directory so that your application can load resources. Do this: right click interface and click Properties, choose Debugging from Configuration Properties, set Working Directory to .\Debug -* Now you can run and debug interface through Visual Studio - -Optional Components -=== +###Optional Components ####QXmpp @@ -276,7 +52,7 @@ You can find QXmpp [here](https://github.com/qxmpp-project/qxmpp). The inclusion OS X users who tap our [homebrew formulas repository](https://github.com/highfidelity/homebrew-formulas) can install QXmpp via homebrew - `brew install highfidelity/formulas/qxmpp`. -#### Devices +####Devices You can support external input/output devices such as Leap Motion, Faceplus, Faceshift, PrioVR, MIDI, Razr Hydra and more by adding each individual SDK in the visible building path. Refer to the readme file available in each device folder in [interface/external/](interface/external) for the detailed explanation of the requirements to use the device. diff --git a/BUILD_LINUX.md b/BUILD_LINUX.md new file mode 100644 index 0000000000..17f7268131 --- /dev/null +++ b/BUILD_LINUX.md @@ -0,0 +1,18 @@ +Please read the [general build guide](BUILD.md) for information on dependencies required for all platforms. Only Linux specific instructions are found in this file. + +####Linux Specific Dependencies +* [freeglut](http://freeglut.sourceforge.net/) ~> 2.8.0 +* [zLib](http://www.zlib.net/) ~> 1.2.8 + +In general, as long as external dependencies are placed in OS standard locations, CMake will successfully find them during its run. When possible, you may choose to install depencies from your package manager of choice, or from source. + +####Qt5 Dependencies +Should you choose not to install Qt5 via a package manager that handles dependencies for you, you may be missing some Qt5 dependencies. On Ubuntu, for example, the following additional packages are required: + + libasound2 libxmu-dev libxi-dev freeglut3-dev libasound2-dev libjack-dev + +#### Intel Threading Building Blocks (TBB) + +Install Intel TBB from your package manager of choice, or from source (available at the [TBB Website](https://www.threadingbuildingblocks.org/)). + +You must run `tbbvars` so that the find module included with this project will be able to find the correct version of TBB. `tbbvars` is located in the 'bin' folder of your TBB install. \ No newline at end of file diff --git a/BUILD_OSX.md b/BUILD_OSX.md new file mode 100644 index 0000000000..977a27a781 --- /dev/null +++ b/BUILD_OSX.md @@ -0,0 +1,22 @@ +Please read the [general build guide](BUILD.md) for information on dependencies required for all platforms. Only OS X specific instructions are found in this file. + +####Homebrew +[Homebrew](http://brew.sh/) is an excellent package manager for OS X. It makes install of all hifi dependencies very simple. + + brew tap highfidelity/homebrew-formulas + brew install cmake glm openssl tbb + brew install highfidelity/formulas/qt5 + brew link qt5 --force + +We have a [homebrew formulas repository](https://github.com/highfidelity/homebrew-formulas) that you can use/tap to install some of the dependencies. In the code block above qt5 is installed from a formula in this repository. + +*Our [qt5 homebrew formula](https://raw.github.com/highfidelity/homebrew-formulas/master/qt5.rb) is for a patched version of Qt 5.3.x stable that removes wireless network scanning that can reduce real-time audio performance. We recommended you use this formula to install Qt.* + +####Xcode +If Xcode is your editor of choice, you can ask CMake to generate Xcode project files instead of Unix Makefiles. + + cmake .. -GXcode + +After running cmake, you will have the make files or Xcode project file necessary to build all of the components. Open the hifi.xcodeproj file, choose ALL_BUILD from the Product > Scheme menu (or target drop down), and click Run. + +If the build completes successfully, you will have built targets for all components located in the `build/${target_name}/Debug` directories. diff --git a/BUILD_WIN.md b/BUILD_WIN.md new file mode 100644 index 0000000000..458aeca53a --- /dev/null +++ b/BUILD_WIN.md @@ -0,0 +1,180 @@ +Please read the [general build guide](BUILD.md) for information on dependencies required for all platforms. Only Windows specific instructions are found in this file. + +####Windows Dependencies +* [GLEW](http://glew.sourceforge.net/) ~> 1.10.0 +* [freeglut MSVC](http://www.transmissionzero.co.uk/software/freeglut-devel/) ~> 2.8.1 +* [zLib](http://www.zlib.net/) ~> 1.2.8 + +####Visual Studio + +Currently building on Windows has been tested using the following compilers: +* Visual Studio C++ 2010 Express +* Visual Studio 2013 + +(If anyone can test using Visual Studio 2013 Express then please update this document) + +#####Windows SDK 7.1 + +If using Visual Studio 2010, or using Visual Studio 2013 but building as a Visual Studio 2010 project, you need [Microsoft Windows SDK for Windows 7 and .NET Framework 4](http://www.microsoft.com/en-us/download/details.aspx?id=8279). + +NOTE: If using Visual Studio C++ 2010 Express, you need to follow a specific install order. See below before installing the Windows SDK. + +######Windows SDK 8.1 + +If using Visual Studio 2013 and building as a Visual Studio 2013 project you need the Windows 8 SDK which you should already have as part of installing Visual Studio 2013. You should be able to see it at `C:\Program Files (x86)\Windows Kits\8.1\Lib\winv6.3\um\x86`. + +#####Visual Studio C++ 2010 Express + +Visual Studio C++ 2010 Express can be downloaded [here](http://www.visualstudio.com/en-us/downloads#d-2010-express). + +The following patches/service packs are also required: +* [VS2010 SP1](http://www.microsoft.com/en-us/download/details.aspx?id=23691) +* [VS2010 SP1 Compiler Update](http://www.microsoft.com/en-us/download/details.aspx?id=4422) + +IMPORTANT: Use the following install order: +Visual Studio C++ 2010 Express +Windows SDK 7.1 +VS2010 SP1 +VS2010 SP1 Compiler Update + +If you get an error while installing the VS2010 SP1 Compiler update saying that you don't have the Windows SDK installed, then uninstall all of the above and start again in the correct order. + +Some of the build instructions will ask you to start a Visual Studio Command Prompt. You should have a shortcut in your Start menu called "Open Visual Studio Command Prompt (2010)" which will do so. + +#####Visual Studio 2013 + +You can use the Community or Professional editions of Visual Studio 2013. + +You can start a Visual Studio 2013 command prompt using the shortcut provided in the Visual Studio Tools folder installed as part of Visual Studio 2013. + +Or you can start a regular command prompt and then run: + + "%VS120COMNTOOLS%\vsvars32.bat" + +If you experience issues building interface on Visual Studio 2013, try generating the build files with Visual Studio 2010 instead. To do so, download Visual Studio 2010 and run `cmake .. -G "Visual Studio 10"` (Assuming running from %HIFI_DIR%\build). + +####Qt +You can use the online installer or the offline installer. If you use the offline installer, be sure to select the "OpenGL" version. + +NOTE: Qt does not support 64-bit builds on Windows 7, so you must use the 32-bit version of libraries for interface.exe to run. The 32-bit version of the static library is the one linked by our CMake find modules. + +* Download the online installer [here](http://qt-project.org/downloads) + * When it asks you to select components, ONLY select the following: + * Qt > Qt 5.2.0 > **msvc2010 32-bit OpenGL** + +* Download the offline installer [here](http://download.qt-project.org/official_releases/qt/5.2/5.2.0/qt-windows-opensource-5.2.0-msvc2010_opengl-x86-offline.exe) + +Once Qt is installed, you need to manually configure the following: +* Make sure the Qt runtime DLLs are loadable. You must do this before you attempt to build because some tools for the build depend on Qt. E.g., add to the PATH: `Qt\5.2.0\msvc2010_opengl\bin\`. +* Set the QT_CMAKE_PREFIX_PATH environment variable to your `Qt\5.2.0\msvc2010_opengl` directory. + +If building as a Visual Studio 2013 project, download and configure the msvc2013 version of Qt instead. + +####External Libraries + +CMake will need to know where the headers and libraries for required external dependencies are. + +The recommended route for CMake to find the external dependencies is to place all of the dependencies in one folder and set one ENV variable - HIFI_LIB_DIR. That ENV variable should point to a directory with the following structure: + + root_lib_dir + -> freeglut + -> bin + -> include + -> lib + -> glew + -> bin + -> include + -> lib + -> glm + -> glm + -> glm.hpp + -> openssl + -> bin + -> include + -> lib + -> tbb + -> include + -> lib + -> zlib + -> include + -> lib + -> test + +For many of the external libraries where precompiled binaries are readily available you should be able to simply copy the extracted folder that you get from the download links provided at the top of the guide. Otherwise you may need to build from source and install the built product to this directory. The `root_lib_dir` in the above example can be wherever you choose on your system - as long as the environment variable HIFI_LIB_DIR is set to it. From here on, whenever you see %HIFI_LIB_DIR% you should substitute the directory that you chose. + +As with the Qt libraries, you will need to make sure that directories containing DLL'S are in your path. Where possible, you can use static builds of the external dependencies to avoid this requirement. + +#### OpenSSL + +QT will use OpenSSL if it's available, but it doesn't install it, so you must install it separately. + +Your system may already have several versions of the OpenSSL DLL's (ssleay32.dll, libeay32.dll) lying around, but they may be the wrong version. If these DLL's are in the PATH then QT will try to use them, and if they're the wrong version then you will see the following errors in the console: + + QSslSocket: cannot resolve TLSv1_1_client_method + QSslSocket: cannot resolve TLSv1_2_client_method + QSslSocket: cannot resolve TLSv1_1_server_method + QSslSocket: cannot resolve TLSv1_2_server_method + QSslSocket: cannot resolve SSL_select_next_proto + QSslSocket: cannot resolve SSL_CTX_set_next_proto_select_cb + QSslSocket: cannot resolve SSL_get0_next_proto_negotiated + +To prevent these problems, install OpenSSL yourself. Download the following binary packages [from this website](http://slproweb.com/products/Win32OpenSSL.html): +* Visual C++ 2008 Redistributables +* Win32 OpenSSL v1.0.1h + +Install OpenSSL into the Windows system directory, to make sure that QT uses the version that you've just installed, and not some other version. + +#### Intel Threading Building Blocks (TBB) + +Download the stable release for Windows from the [Intel Threading Building Blocks website](https://www.threadingbuildingblocks.org/). By default, TBB will install to Program Files. You may also choose to install it to %HIFI_LIB_DIR%\TBB. + +You must run `tbbvars.bat` so that the find module included with this project will be able to find TBB no matter where you installed it. `tbbvars.bat` is located in the 'bin' folder of your TBB install. For a default installation on a 64-bit architechture, tbbvars can be found at `C:/Program Files (x86)/Intel/TBB/bin/tbbvars.bat`. + +#### Zlib + +Download the compiled DLL from the [zlib website](http://www.zlib.net/). Extract to %HIFI_LIB_DIR%\zlib. + +Add the following environment variables (remember to substitute your own directory for %HIFI_LIB_DIR%): + + ZLIB_LIBRARY=%HIFI_LIB_DIR%\zlib\lib\zdll.lib + ZLIB_INCLUDE_DIR=%HIFI_LIB_DIR%\zlib\include + +Add to the PATH: `%HIFI_LIB_DIR%\zlib` + +Important! This should be added at the beginning of the path, not the end. That's because your +system likely has many copies of zlib1.dll, and you want High Fidelity to use the correct version. If High Fidelity picks up the wrong zlib1.dll then it might be unable to use it, and that would cause it to fail to start, showing only the cryptic error "The application was unable to start correctly: 0xc0000022". + +#### freeglut + +Download the binary package: `freeglut-MSVC-2.8.1-1.mp.zip`. Extract to %HIFI_LIB_DIR%\freeglut. + +Add to the PATH: `%HIFI_LIB_DIR%\freeglut\bin` + +#### GLEW + +Download the binary package: `glew-1.10.0-win32.zip`. Extract to %HIFI_LIB_DIR%\glew (you'll need to rename the default directory name). + +Add to the PATH: `%HIFI_LIB_DIR%\glew\bin\Release\Win32` + +#### GLM + +This package contains only headers, so there's nothing to add to the PATH. + +Be careful with glm. For the folder other libraries would normally call 'include', the folder containing the headers, glm opts to use 'glm'. You will have a glm folder nested inside the top-level glm folder. + +#### Build High Fidelity using Visual Studio +Follow the same build steps from the CMake section, but pass a different generator to CMake. + + cmake .. -DZLIB_LIBRARY=%ZLIB_LIBRARY% -DZLIB_INCLUDE_DIR=%ZLIB_INCLUDE_DIR% -G "Visual Studio 10" + +If you're using Visual Studio 2013 then pass "Visual Studio 12" instead of "Visual Studio 10" (yes, 12, not 13). + +Open %HIFI_DIR%\build\hifi.sln and compile. + +####Running Interface +If you need to debug Interface, you can run interface from within Visual Studio (see the section below). You can also run Interface by launching it from command line or File Explorer from %HIFI_DIR%\build\interface\Debug\interface.exe + +####Debugging Interface +* In the Solution Explorer, right click interface and click Set as StartUp Project +* Set the "Working Directory" for the Interface debugging sessions to the Debug output directory so that your application can load resources. Do this: right click interface and click Properties, choose Debugging from Configuration Properties, set Working Directory to .\Debug +* Now you can run and debug interface through Visual Studio From a87fb0fe5e4906c7581ed2947ee2679ab00b0c61 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 15 Dec 2014 10:21:31 -0800 Subject: [PATCH 34/62] link to OS build guides from main guide --- BUILD.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/BUILD.md b/BUILD.md index 867e515209..0a897aa193 100644 --- a/BUILD.md +++ b/BUILD.md @@ -7,6 +7,11 @@ * IMPORTANT: OpenSSL 1.0.1g is critical to avoid a security vulnerability. * [Intel Threading Building Blocks](https://www.threadingbuildingblocks.org/) ~> 4.3 +### OS Specific Build Guides +* [BUILD_OSX.md](BUILD_OSX.md) - additional instructions for OS X. +* [BUILD_LINUX.md](BUILD_LINUX.md) - additional instructions for Linux. +* [BUILD_WIN.md](BUILD_WIN.md) - additional instructions for Windows. + ###CMake Hifi uses CMake to generate build files and project files for your platform. From bba48a61f99671ae7372e0d2542e095dad787ec0 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 15 Dec 2014 10:22:58 -0800 Subject: [PATCH 35/62] cleanup formatting of build guides --- BUILD_LINUX.md | 6 +++--- BUILD_OSX.md | 4 ++-- BUILD_WIN.md | 34 +++++++++++++++++----------------- 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/BUILD_LINUX.md b/BUILD_LINUX.md index 17f7268131..eb4dcd9255 100644 --- a/BUILD_LINUX.md +++ b/BUILD_LINUX.md @@ -1,17 +1,17 @@ Please read the [general build guide](BUILD.md) for information on dependencies required for all platforms. Only Linux specific instructions are found in this file. -####Linux Specific Dependencies +###Linux Specific Dependencies * [freeglut](http://freeglut.sourceforge.net/) ~> 2.8.0 * [zLib](http://www.zlib.net/) ~> 1.2.8 In general, as long as external dependencies are placed in OS standard locations, CMake will successfully find them during its run. When possible, you may choose to install depencies from your package manager of choice, or from source. -####Qt5 Dependencies +###Qt5 Dependencies Should you choose not to install Qt5 via a package manager that handles dependencies for you, you may be missing some Qt5 dependencies. On Ubuntu, for example, the following additional packages are required: libasound2 libxmu-dev libxi-dev freeglut3-dev libasound2-dev libjack-dev -#### Intel Threading Building Blocks (TBB) +###Intel Threading Building Blocks (TBB) Install Intel TBB from your package manager of choice, or from source (available at the [TBB Website](https://www.threadingbuildingblocks.org/)). diff --git a/BUILD_OSX.md b/BUILD_OSX.md index 977a27a781..1eeaed1c13 100644 --- a/BUILD_OSX.md +++ b/BUILD_OSX.md @@ -1,6 +1,6 @@ Please read the [general build guide](BUILD.md) for information on dependencies required for all platforms. Only OS X specific instructions are found in this file. -####Homebrew +###Homebrew [Homebrew](http://brew.sh/) is an excellent package manager for OS X. It makes install of all hifi dependencies very simple. brew tap highfidelity/homebrew-formulas @@ -12,7 +12,7 @@ We have a [homebrew formulas repository](https://github.com/highfidelity/homebre *Our [qt5 homebrew formula](https://raw.github.com/highfidelity/homebrew-formulas/master/qt5.rb) is for a patched version of Qt 5.3.x stable that removes wireless network scanning that can reduce real-time audio performance. We recommended you use this formula to install Qt.* -####Xcode +###Xcode If Xcode is your editor of choice, you can ask CMake to generate Xcode project files instead of Unix Makefiles. cmake .. -GXcode diff --git a/BUILD_WIN.md b/BUILD_WIN.md index 458aeca53a..5685370dc3 100644 --- a/BUILD_WIN.md +++ b/BUILD_WIN.md @@ -1,11 +1,11 @@ Please read the [general build guide](BUILD.md) for information on dependencies required for all platforms. Only Windows specific instructions are found in this file. -####Windows Dependencies +###Windows Dependencies * [GLEW](http://glew.sourceforge.net/) ~> 1.10.0 * [freeglut MSVC](http://www.transmissionzero.co.uk/software/freeglut-devel/) ~> 2.8.1 * [zLib](http://www.zlib.net/) ~> 1.2.8 -####Visual Studio +###Visual Studio Currently building on Windows has been tested using the following compilers: * Visual Studio C++ 2010 Express @@ -13,17 +13,17 @@ Currently building on Windows has been tested using the following compilers: (If anyone can test using Visual Studio 2013 Express then please update this document) -#####Windows SDK 7.1 +####Windows SDK 7.1 If using Visual Studio 2010, or using Visual Studio 2013 but building as a Visual Studio 2010 project, you need [Microsoft Windows SDK for Windows 7 and .NET Framework 4](http://www.microsoft.com/en-us/download/details.aspx?id=8279). NOTE: If using Visual Studio C++ 2010 Express, you need to follow a specific install order. See below before installing the Windows SDK. -######Windows SDK 8.1 +#####Windows SDK 8.1 If using Visual Studio 2013 and building as a Visual Studio 2013 project you need the Windows 8 SDK which you should already have as part of installing Visual Studio 2013. You should be able to see it at `C:\Program Files (x86)\Windows Kits\8.1\Lib\winv6.3\um\x86`. -#####Visual Studio C++ 2010 Express +####Visual Studio C++ 2010 Express Visual Studio C++ 2010 Express can be downloaded [here](http://www.visualstudio.com/en-us/downloads#d-2010-express). @@ -41,7 +41,7 @@ If you get an error while installing the VS2010 SP1 Compiler update saying that Some of the build instructions will ask you to start a Visual Studio Command Prompt. You should have a shortcut in your Start menu called "Open Visual Studio Command Prompt (2010)" which will do so. -#####Visual Studio 2013 +####Visual Studio 2013 You can use the Community or Professional editions of Visual Studio 2013. @@ -53,7 +53,7 @@ Or you can start a regular command prompt and then run: If you experience issues building interface on Visual Studio 2013, try generating the build files with Visual Studio 2010 instead. To do so, download Visual Studio 2010 and run `cmake .. -G "Visual Studio 10"` (Assuming running from %HIFI_DIR%\build). -####Qt +###Qt You can use the online installer or the offline installer. If you use the offline installer, be sure to select the "OpenGL" version. NOTE: Qt does not support 64-bit builds on Windows 7, so you must use the 32-bit version of libraries for interface.exe to run. The 32-bit version of the static library is the one linked by our CMake find modules. @@ -70,7 +70,7 @@ Once Qt is installed, you need to manually configure the following: If building as a Visual Studio 2013 project, download and configure the msvc2013 version of Qt instead. -####External Libraries +###External Libraries CMake will need to know where the headers and libraries for required external dependencies are. @@ -104,7 +104,7 @@ For many of the external libraries where precompiled binaries are readily availa As with the Qt libraries, you will need to make sure that directories containing DLL'S are in your path. Where possible, you can use static builds of the external dependencies to avoid this requirement. -#### OpenSSL +###OpenSSL QT will use OpenSSL if it's available, but it doesn't install it, so you must install it separately. @@ -124,13 +124,13 @@ To prevent these problems, install OpenSSL yourself. Download the following bina Install OpenSSL into the Windows system directory, to make sure that QT uses the version that you've just installed, and not some other version. -#### Intel Threading Building Blocks (TBB) +###Intel Threading Building Blocks (TBB) Download the stable release for Windows from the [Intel Threading Building Blocks website](https://www.threadingbuildingblocks.org/). By default, TBB will install to Program Files. You may also choose to install it to %HIFI_LIB_DIR%\TBB. You must run `tbbvars.bat` so that the find module included with this project will be able to find TBB no matter where you installed it. `tbbvars.bat` is located in the 'bin' folder of your TBB install. For a default installation on a 64-bit architechture, tbbvars can be found at `C:/Program Files (x86)/Intel/TBB/bin/tbbvars.bat`. -#### Zlib +###Zlib Download the compiled DLL from the [zlib website](http://www.zlib.net/). Extract to %HIFI_LIB_DIR%\zlib. @@ -144,25 +144,25 @@ Add to the PATH: `%HIFI_LIB_DIR%\zlib` Important! This should be added at the beginning of the path, not the end. That's because your system likely has many copies of zlib1.dll, and you want High Fidelity to use the correct version. If High Fidelity picks up the wrong zlib1.dll then it might be unable to use it, and that would cause it to fail to start, showing only the cryptic error "The application was unable to start correctly: 0xc0000022". -#### freeglut +###freeglut Download the binary package: `freeglut-MSVC-2.8.1-1.mp.zip`. Extract to %HIFI_LIB_DIR%\freeglut. Add to the PATH: `%HIFI_LIB_DIR%\freeglut\bin` -#### GLEW +###GLEW Download the binary package: `glew-1.10.0-win32.zip`. Extract to %HIFI_LIB_DIR%\glew (you'll need to rename the default directory name). Add to the PATH: `%HIFI_LIB_DIR%\glew\bin\Release\Win32` -#### GLM +###GLM This package contains only headers, so there's nothing to add to the PATH. Be careful with glm. For the folder other libraries would normally call 'include', the folder containing the headers, glm opts to use 'glm'. You will have a glm folder nested inside the top-level glm folder. -#### Build High Fidelity using Visual Studio +###Build High Fidelity using Visual Studio Follow the same build steps from the CMake section, but pass a different generator to CMake. cmake .. -DZLIB_LIBRARY=%ZLIB_LIBRARY% -DZLIB_INCLUDE_DIR=%ZLIB_INCLUDE_DIR% -G "Visual Studio 10" @@ -171,10 +171,10 @@ If you're using Visual Studio 2013 then pass "Visual Studio 12" instead of "Visu Open %HIFI_DIR%\build\hifi.sln and compile. -####Running Interface +###Running Interface If you need to debug Interface, you can run interface from within Visual Studio (see the section below). You can also run Interface by launching it from command line or File Explorer from %HIFI_DIR%\build\interface\Debug\interface.exe -####Debugging Interface +###Debugging Interface * In the Solution Explorer, right click interface and click Set as StartUp Project * Set the "Working Directory" for the Interface debugging sessions to the Debug output directory so that your application can load resources. Do this: right click interface and click Properties, choose Debugging from Configuration Properties, set Working Directory to .\Debug * Now you can run and debug interface through Visual Studio From 9b37967bedcfb6b9d714d6a5257b91dfb482c9d0 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 15 Dec 2014 11:23:25 -0800 Subject: [PATCH 36/62] changes to instructions for TBB, remove MSVC2010 --- BUILD_LINUX.md | 2 +- BUILD_WIN.md | 45 +++++++++------------------------------------ 2 files changed, 10 insertions(+), 37 deletions(-) diff --git a/BUILD_LINUX.md b/BUILD_LINUX.md index eb4dcd9255..7b6c8f2176 100644 --- a/BUILD_LINUX.md +++ b/BUILD_LINUX.md @@ -15,4 +15,4 @@ Should you choose not to install Qt5 via a package manager that handles dependen Install Intel TBB from your package manager of choice, or from source (available at the [TBB Website](https://www.threadingbuildingblocks.org/)). -You must run `tbbvars` so that the find module included with this project will be able to find the correct version of TBB. `tbbvars` is located in the 'bin' folder of your TBB install. \ No newline at end of file +You must run `tbbvars` before running cmake that the find module included with this project will be able to find the correct version of TBB. `tbbvars` is located in the 'bin' folder of your TBB install. \ No newline at end of file diff --git a/BUILD_WIN.md b/BUILD_WIN.md index 5685370dc3..4e773e3323 100644 --- a/BUILD_WIN.md +++ b/BUILD_WIN.md @@ -8,39 +8,10 @@ Please read the [general build guide](BUILD.md) for information on dependencies ###Visual Studio Currently building on Windows has been tested using the following compilers: -* Visual Studio C++ 2010 Express * Visual Studio 2013 (If anyone can test using Visual Studio 2013 Express then please update this document) -####Windows SDK 7.1 - -If using Visual Studio 2010, or using Visual Studio 2013 but building as a Visual Studio 2010 project, you need [Microsoft Windows SDK for Windows 7 and .NET Framework 4](http://www.microsoft.com/en-us/download/details.aspx?id=8279). - -NOTE: If using Visual Studio C++ 2010 Express, you need to follow a specific install order. See below before installing the Windows SDK. - -#####Windows SDK 8.1 - -If using Visual Studio 2013 and building as a Visual Studio 2013 project you need the Windows 8 SDK which you should already have as part of installing Visual Studio 2013. You should be able to see it at `C:\Program Files (x86)\Windows Kits\8.1\Lib\winv6.3\um\x86`. - -####Visual Studio C++ 2010 Express - -Visual Studio C++ 2010 Express can be downloaded [here](http://www.visualstudio.com/en-us/downloads#d-2010-express). - -The following patches/service packs are also required: -* [VS2010 SP1](http://www.microsoft.com/en-us/download/details.aspx?id=23691) -* [VS2010 SP1 Compiler Update](http://www.microsoft.com/en-us/download/details.aspx?id=4422) - -IMPORTANT: Use the following install order: -Visual Studio C++ 2010 Express -Windows SDK 7.1 -VS2010 SP1 -VS2010 SP1 Compiler Update - -If you get an error while installing the VS2010 SP1 Compiler update saying that you don't have the Windows SDK installed, then uninstall all of the above and start again in the correct order. - -Some of the build instructions will ask you to start a Visual Studio Command Prompt. You should have a shortcut in your Start menu called "Open Visual Studio Command Prompt (2010)" which will do so. - ####Visual Studio 2013 You can use the Community or Professional editions of Visual Studio 2013. @@ -53,6 +24,10 @@ Or you can start a regular command prompt and then run: If you experience issues building interface on Visual Studio 2013, try generating the build files with Visual Studio 2010 instead. To do so, download Visual Studio 2010 and run `cmake .. -G "Visual Studio 10"` (Assuming running from %HIFI_DIR%\build). +#####Windows SDK 8.1 + +If using Visual Studio 2013 and building as a Visual Studio 2013 project you need the Windows 8 SDK which you should already have as part of installing Visual Studio 2013. You should be able to see it at `C:\Program Files (x86)\Windows Kits\8.1\Lib\winv6.3\um\x86`. + ###Qt You can use the online installer or the offline installer. If you use the offline installer, be sure to select the "OpenGL" version. @@ -60,15 +35,13 @@ NOTE: Qt does not support 64-bit builds on Windows 7, so you must use the 32-bit * Download the online installer [here](http://qt-project.org/downloads) * When it asks you to select components, ONLY select the following: - * Qt > Qt 5.2.0 > **msvc2010 32-bit OpenGL** + * Qt > Qt 5.3.2 > **msvc2013 32-bit OpenGL** -* Download the offline installer [here](http://download.qt-project.org/official_releases/qt/5.2/5.2.0/qt-windows-opensource-5.2.0-msvc2010_opengl-x86-offline.exe) +* Download the offline installer [here](http://download.qt-project.org/official_releases/qt/5.3/5.3.2/qt-opensource-windows-x86-msvc2013_opengl-5.3.2.exe) Once Qt is installed, you need to manually configure the following: -* Make sure the Qt runtime DLLs are loadable. You must do this before you attempt to build because some tools for the build depend on Qt. E.g., add to the PATH: `Qt\5.2.0\msvc2010_opengl\bin\`. -* Set the QT_CMAKE_PREFIX_PATH environment variable to your `Qt\5.2.0\msvc2010_opengl` directory. - -If building as a Visual Studio 2013 project, download and configure the msvc2013 version of Qt instead. +* Make sure the Qt runtime DLLs are loadable. You must do this before you attempt to build because some tools for the build depend on Qt. E.g., add to the PATH: `Qt\5.3.2\msvc2013_opengl\bin\`. +* Set the QT_CMAKE_PREFIX_PATH environment variable to your `Qt\5.3.2\msvc2013_opengl` directory. ###External Libraries @@ -128,7 +101,7 @@ Install OpenSSL into the Windows system directory, to make sure that QT uses the Download the stable release for Windows from the [Intel Threading Building Blocks website](https://www.threadingbuildingblocks.org/). By default, TBB will install to Program Files. You may also choose to install it to %HIFI_LIB_DIR%\TBB. -You must run `tbbvars.bat` so that the find module included with this project will be able to find TBB no matter where you installed it. `tbbvars.bat` is located in the 'bin' folder of your TBB install. For a default installation on a 64-bit architechture, tbbvars can be found at `C:/Program Files (x86)/Intel/TBB/bin/tbbvars.bat`. +You must run `tbbvars.bat` before running cmake so that the find module included with this project will be able to find TBB no matter where you installed it. `tbbvars.bat` is located in the 'bin' folder of your TBB install. For a default installation on a 64-bit architechture, tbbvars can be found at `C:/Program Files (x86)/Intel/TBB/bin/tbbvars.bat`. ###Zlib From ee919643000130e573ed921a9f9c15f576687497 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 15 Dec 2014 11:25:17 -0800 Subject: [PATCH 37/62] clarify that TBB can be installed wherever --- BUILD_WIN.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BUILD_WIN.md b/BUILD_WIN.md index 4e773e3323..e84b2ad811 100644 --- a/BUILD_WIN.md +++ b/BUILD_WIN.md @@ -99,7 +99,7 @@ Install OpenSSL into the Windows system directory, to make sure that QT uses the ###Intel Threading Building Blocks (TBB) -Download the stable release for Windows from the [Intel Threading Building Blocks website](https://www.threadingbuildingblocks.org/). By default, TBB will install to Program Files. You may also choose to install it to %HIFI_LIB_DIR%\TBB. +Download the stable release for Windows from the [Intel Threading Building Blocks website](https://www.threadingbuildingblocks.org/). By default, TBB will install to Program Files. You can choose to install it wherever you like, including %HIFI_LIB_DIR%. You must run `tbbvars.bat` before running cmake so that the find module included with this project will be able to find TBB no matter where you installed it. `tbbvars.bat` is located in the 'bin' folder of your TBB install. For a default installation on a 64-bit architechture, tbbvars can be found at `C:/Program Files (x86)/Intel/TBB/bin/tbbvars.bat`. From 36f23fe4be78ad51a0fd41758ca8b9a9dac07501 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 15 Dec 2014 11:26:06 -0800 Subject: [PATCH 38/62] fix Qt path in Generating build files --- BUILD.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BUILD.md b/BUILD.md index 0a897aa193..0fdb822f25 100644 --- a/BUILD.md +++ b/BUILD.md @@ -38,7 +38,7 @@ Any variables that need to be set for CMake to find dependencies can be set as E For example, to pass the QT_CMAKE_PREFIX_PATH variable during build file generation: - cmake .. -DQT_CMAKE_PREFIX_PATH=/usr/local/qt/5.2.1/lib/cmake + cmake .. -DQT_CMAKE_PREFIX_PATH=/usr/local/qt/5.3.2/lib/cmake ####Finding Dependencies You can point our [Cmake find modules](cmake/modules/) to the correct version of dependencies by setting one of the three following variables to the location of the correct version of the dependency. From aac44953cbf0b3db0eb36509ccbcd17633f22369 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 15 Dec 2014 11:27:31 -0800 Subject: [PATCH 39/62] fix generator passed to cmake for windows build --- BUILD_WIN.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/BUILD_WIN.md b/BUILD_WIN.md index e84b2ad811..030c2f92a8 100644 --- a/BUILD_WIN.md +++ b/BUILD_WIN.md @@ -138,9 +138,7 @@ Be careful with glm. For the folder other libraries would normally call 'include ###Build High Fidelity using Visual Studio Follow the same build steps from the CMake section, but pass a different generator to CMake. - cmake .. -DZLIB_LIBRARY=%ZLIB_LIBRARY% -DZLIB_INCLUDE_DIR=%ZLIB_INCLUDE_DIR% -G "Visual Studio 10" - -If you're using Visual Studio 2013 then pass "Visual Studio 12" instead of "Visual Studio 10" (yes, 12, not 13). + cmake .. -DZLIB_LIBRARY=%ZLIB_LIBRARY% -DZLIB_INCLUDE_DIR=%ZLIB_INCLUDE_DIR% -G "Visual Studio 12" Open %HIFI_DIR%\build\hifi.sln and compile. From ea08d7bb2300560da764e1c53d6c659a5a775ccd Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 15 Dec 2014 11:28:43 -0800 Subject: [PATCH 40/62] remove block recommending VS2010 project file --- BUILD_WIN.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/BUILD_WIN.md b/BUILD_WIN.md index 030c2f92a8..bf7d421715 100644 --- a/BUILD_WIN.md +++ b/BUILD_WIN.md @@ -22,8 +22,6 @@ Or you can start a regular command prompt and then run: "%VS120COMNTOOLS%\vsvars32.bat" -If you experience issues building interface on Visual Studio 2013, try generating the build files with Visual Studio 2010 instead. To do so, download Visual Studio 2010 and run `cmake .. -G "Visual Studio 10"` (Assuming running from %HIFI_DIR%\build). - #####Windows SDK 8.1 If using Visual Studio 2013 and building as a Visual Studio 2013 project you need the Windows 8 SDK which you should already have as part of installing Visual Studio 2013. You should be able to see it at `C:\Program Files (x86)\Windows Kits\8.1\Lib\winv6.3\um\x86`. From c18c45a40152f5dd326a78323c8dfe7b1577dffb Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 15 Dec 2014 11:30:17 -0800 Subject: [PATCH 41/62] bump glm dependency version --- BUILD.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BUILD.md b/BUILD.md index 0fdb822f25..6613786903 100644 --- a/BUILD.md +++ b/BUILD.md @@ -2,7 +2,7 @@ * [cmake](http://www.cmake.org/cmake/resources/software.html) ~> 2.8.12.2 * [Qt](http://qt-project.org/downloads) ~> 5.3.0 -* [glm](http://glm.g-truc.net/0.9.5/index.html) ~> 0.9.5.2 +* [glm](http://glm.g-truc.net/0.9.5/index.html) ~> 0.9.5.4 * [OpenSSL](https://www.openssl.org/related/binaries.html) ~> 1.0.1g * IMPORTANT: OpenSSL 1.0.1g is critical to avoid a security vulnerability. * [Intel Threading Building Blocks](https://www.threadingbuildingblocks.org/) ~> 4.3 From fa8b7020b0ed48556a8cbc2100599c8326903e08 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 15 Dec 2014 11:48:24 -0800 Subject: [PATCH 42/62] repairs to MetavoxelSystem after reset to upstream --- interface/src/MetavoxelSystem.cpp | 349 +++++++++++++++--------------- 1 file changed, 175 insertions(+), 174 deletions(-) diff --git a/interface/src/MetavoxelSystem.cpp b/interface/src/MetavoxelSystem.cpp index c047b8591b..b15ea0b488 100644 --- a/interface/src/MetavoxelSystem.cpp +++ b/interface/src/MetavoxelSystem.cpp @@ -40,13 +40,13 @@ REGISTER_META_OBJECT(StaticModelRenderer) REGISTER_META_OBJECT(HeightfieldRenderer) MetavoxelSystem::NetworkSimulation::NetworkSimulation(float dropRate, float repeatRate, - int minimumDelay, int maximumDelay, int bandwidthLimit) : -dropRate(dropRate), -repeatRate(repeatRate), -minimumDelay(minimumDelay), -maximumDelay(maximumDelay), -bandwidthLimit(bandwidthLimit) { -} + int minimumDelay, int maximumDelay, int bandwidthLimit) : + dropRate(dropRate), + repeatRate(repeatRate), + minimumDelay(minimumDelay), + maximumDelay(maximumDelay), + bandwidthLimit(bandwidthLimit) { +} MetavoxelSystem::~MetavoxelSystem() { // kill the updater before we delete our network simulation objects @@ -59,14 +59,14 @@ void MetavoxelSystem::init() { MetavoxelClientManager::init(); _voxelBufferAttribute = AttributeRegistry::getInstance()->registerAttribute( - new BufferDataAttribute("voxelBuffer")); + new BufferDataAttribute("voxelBuffer")); _voxelBufferAttribute->setLODThresholdMultiplier( - AttributeRegistry::getInstance()->getVoxelColorAttribute()->getLODThresholdMultiplier()); - + AttributeRegistry::getInstance()->getVoxelColorAttribute()->getLODThresholdMultiplier()); + _baseHeightfieldProgram.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath() + - "shaders/metavoxel_heightfield_base.vert"); + "shaders/metavoxel_heightfield_base.vert"); _baseHeightfieldProgram.addShaderFromSourceFile(QGLShader::Fragment, Application::resourcesPath() + - "shaders/metavoxel_heightfield_base.frag"); + "shaders/metavoxel_heightfield_base.frag"); _baseHeightfieldProgram.link(); _baseHeightfieldProgram.bind(); @@ -79,9 +79,9 @@ void MetavoxelSystem::init() { loadSplatProgram("heightfield", _splatHeightfieldProgram, _splatHeightfieldLocations); _heightfieldCursorProgram.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath() + - "shaders/metavoxel_heightfield_cursor.vert"); + "shaders/metavoxel_heightfield_cursor.vert"); _heightfieldCursorProgram.addShaderFromSourceFile(QGLShader::Fragment, Application::resourcesPath() + - "shaders/metavoxel_cursor.frag"); + "shaders/metavoxel_cursor.frag"); _heightfieldCursorProgram.link(); _heightfieldCursorProgram.bind(); @@ -89,17 +89,17 @@ void MetavoxelSystem::init() { _heightfieldCursorProgram.release(); _baseVoxelProgram.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath() + - "shaders/metavoxel_voxel_base.vert"); + "shaders/metavoxel_voxel_base.vert"); _baseVoxelProgram.addShaderFromSourceFile(QGLShader::Fragment, Application::resourcesPath() + - "shaders/metavoxel_voxel_base.frag"); + "shaders/metavoxel_voxel_base.frag"); _baseVoxelProgram.link(); loadSplatProgram("voxel", _splatVoxelProgram, _splatVoxelLocations); _voxelCursorProgram.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath() + - "shaders/metavoxel_voxel_cursor.vert"); + "shaders/metavoxel_voxel_cursor.vert"); _voxelCursorProgram.addShaderFromSourceFile(QGLShader::Fragment, Application::resourcesPath() + - "shaders/metavoxel_cursor.frag"); + "shaders/metavoxel_cursor.frag"); _voxelCursorProgram.link(); } @@ -124,16 +124,16 @@ public: SimulateVisitor(float deltaTime, const MetavoxelLOD& lod); virtual int visit(MetavoxelInfo& info); - + private: float _deltaTime; }; SimulateVisitor::SimulateVisitor(float deltaTime, const MetavoxelLOD& lod) : -MetavoxelVisitor(QVector() << AttributeRegistry::getInstance()->getRendererAttribute(), - QVector(), lod), -_deltaTime(deltaTime) { + MetavoxelVisitor(QVector() << AttributeRegistry::getInstance()->getRendererAttribute(), + QVector(), lod), + _deltaTime(deltaTime) { } int SimulateVisitor::visit(MetavoxelInfo& info) { @@ -141,7 +141,7 @@ int SimulateVisitor::visit(MetavoxelInfo& info) { return DEFAULT_ORDER; } static_cast(info.inputValues.at(0).getInlineValue< - SharedObjectPointer>().data())->getImplementation()->simulate(*_data, _deltaTime, info, _lod); + SharedObjectPointer>().data())->getImplementation()->simulate(*_data, _deltaTime, info, _lod); return STOP_RECURSION; } @@ -152,7 +152,7 @@ void MetavoxelSystem::simulate(float deltaTime) { const float DEFAULT_LOD_THRESHOLD = 0.01f; _lod = MetavoxelLOD(Application::getInstance()->getCamera()->getPosition(), DEFAULT_LOD_THRESHOLD); } - + SimulateVisitor simulateVisitor(deltaTime, getLOD()); guideToAugmented(simulateVisitor); } @@ -166,8 +166,8 @@ public: }; RenderVisitor::RenderVisitor(const MetavoxelLOD& lod) : -MetavoxelVisitor(QVector() << AttributeRegistry::getInstance()->getRendererAttribute(), - QVector(), lod) { + MetavoxelVisitor(QVector() << AttributeRegistry::getInstance()->getRendererAttribute(), + QVector(), lod) { } int RenderVisitor::visit(MetavoxelInfo& info) { @@ -175,7 +175,7 @@ int RenderVisitor::visit(MetavoxelInfo& info) { return DEFAULT_ORDER; } static_cast(info.inputValues.at(0).getInlineValue< - SharedObjectPointer>().data())->getImplementation()->render(*_data, info, _lod); + SharedObjectPointer>().data())->getImplementation()->render(*_data, info, _lod); return STOP_RECURSION; } @@ -195,18 +195,18 @@ void MetavoxelSystem::render() { // update the frustum ViewFrustum* viewFrustum = Application::getInstance()->getDisplayViewFrustum(); _frustum.set(viewFrustum->getFarTopLeft(), viewFrustum->getFarTopRight(), viewFrustum->getFarBottomLeft(), - viewFrustum->getFarBottomRight(), viewFrustum->getNearTopLeft(), viewFrustum->getNearTopRight(), - viewFrustum->getNearBottomLeft(), viewFrustum->getNearBottomRight()); - + viewFrustum->getFarBottomRight(), viewFrustum->getNearTopLeft(), viewFrustum->getNearTopRight(), + viewFrustum->getNearBottomLeft(), viewFrustum->getNearBottomRight()); + RenderVisitor renderVisitor(getLOD()); guideToAugmented(renderVisitor, true); if (!_heightfieldBaseBatches.isEmpty()) { glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); - + Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true, true); - + glDisable(GL_BLEND); glEnable(GL_CULL_FACE); glEnable(GL_ALPHA_TEST); @@ -225,7 +225,7 @@ void MetavoxelSystem::render() { batch.vertexBuffer->bind(); batch.indexBuffer->bind(); - + HeightfieldPoint* point = 0; glVertexPointer(3, GL_FLOAT, sizeof(HeightfieldPoint), &point->vertex); glTexCoordPointer(2, GL_FLOAT, sizeof(HeightfieldPoint), &point->textureCoord); @@ -234,7 +234,7 @@ void MetavoxelSystem::render() { _baseHeightfieldProgram.setUniform(_baseHeightScaleLocation, batch.heightScale); _baseHeightfieldProgram.setUniform(_baseColorScaleLocation, batch.colorScale); - + glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, batch.colorTextureID); @@ -244,10 +244,10 @@ void MetavoxelSystem::render() { glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, 0); - + batch.vertexBuffer->release(); batch.indexBuffer->release(); - + glPopMatrix(); } @@ -275,7 +275,7 @@ void MetavoxelSystem::render() { batch.vertexBuffer->bind(); batch.indexBuffer->bind(); - + HeightfieldPoint* point = 0; glVertexPointer(3, GL_FLOAT, sizeof(HeightfieldPoint), &point->vertex); glTexCoordPointer(2, GL_FLOAT, sizeof(HeightfieldPoint), &point->textureCoord); @@ -283,7 +283,7 @@ void MetavoxelSystem::render() { glBindTexture(GL_TEXTURE_2D, batch.heightTextureID); _splatHeightfieldProgram.setUniformValue(_splatHeightfieldLocations.heightScale, - batch.heightScale.x, batch.heightScale.y); + batch.heightScale.x, batch.heightScale.y); _splatHeightfieldProgram.setUniform(_splatHeightfieldLocations.textureScale, batch.textureScale); _splatHeightfieldProgram.setUniform(_splatHeightfieldLocations.splatTextureOffset, batch.splatTextureOffset); @@ -291,18 +291,18 @@ void MetavoxelSystem::render() { _splatHeightfieldProgram.setUniform(_splatHeightfieldLocations.splatTextureScalesS, batch.splatTextureScalesS); _splatHeightfieldProgram.setUniform(_splatHeightfieldLocations.splatTextureScalesT, batch.splatTextureScalesT); _splatHeightfieldProgram.setUniformValue( - _splatHeightfieldLocations.textureValueMinima, - (batch.materialIndex + 1) * EIGHT_BIT_MAXIMUM_RECIPROCAL - QUARTER_STEP, - (batch.materialIndex + 2) * EIGHT_BIT_MAXIMUM_RECIPROCAL - QUARTER_STEP, - (batch.materialIndex + 3) * EIGHT_BIT_MAXIMUM_RECIPROCAL - QUARTER_STEP, - (batch.materialIndex + 4) * EIGHT_BIT_MAXIMUM_RECIPROCAL - QUARTER_STEP); + _splatHeightfieldLocations.textureValueMinima, + (batch.materialIndex + 1) * EIGHT_BIT_MAXIMUM_RECIPROCAL - QUARTER_STEP, + (batch.materialIndex + 2) * EIGHT_BIT_MAXIMUM_RECIPROCAL - QUARTER_STEP, + (batch.materialIndex + 3) * EIGHT_BIT_MAXIMUM_RECIPROCAL - QUARTER_STEP, + (batch.materialIndex + 4) * EIGHT_BIT_MAXIMUM_RECIPROCAL - QUARTER_STEP); _splatHeightfieldProgram.setUniformValue( - _splatHeightfieldLocations.textureValueMaxima, - (batch.materialIndex + 1) * EIGHT_BIT_MAXIMUM_RECIPROCAL + QUARTER_STEP, - (batch.materialIndex + 2) * EIGHT_BIT_MAXIMUM_RECIPROCAL + QUARTER_STEP, - (batch.materialIndex + 3) * EIGHT_BIT_MAXIMUM_RECIPROCAL + QUARTER_STEP, - (batch.materialIndex + 4) * EIGHT_BIT_MAXIMUM_RECIPROCAL + QUARTER_STEP); - + _splatHeightfieldLocations.textureValueMaxima, + (batch.materialIndex + 1) * EIGHT_BIT_MAXIMUM_RECIPROCAL + QUARTER_STEP, + (batch.materialIndex + 2) * EIGHT_BIT_MAXIMUM_RECIPROCAL + QUARTER_STEP, + (batch.materialIndex + 3) * EIGHT_BIT_MAXIMUM_RECIPROCAL + QUARTER_STEP, + (batch.materialIndex + 4) * EIGHT_BIT_MAXIMUM_RECIPROCAL + QUARTER_STEP); + glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, batch.materialTextureID); @@ -312,22 +312,22 @@ void MetavoxelSystem::render() { } glDrawRangeElements(GL_TRIANGLES, 0, batch.vertexCount - 1, batch.indexCount, GL_UNSIGNED_INT, 0); - + for (int i = 0; i < SPLAT_COUNT; i++) { glActiveTexture(GL_TEXTURE0 + SPLAT_TEXTURE_UNITS[i]); glBindTexture(GL_TEXTURE_2D, 0); } - + glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, 0); - + glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, 0); - + batch.vertexBuffer->release(); batch.indexBuffer->release(); - glPopMatrix(); + glPopMatrix(); } _splatHeightfieldProgram.release(); @@ -341,15 +341,15 @@ void MetavoxelSystem::render() { glDisable(GL_CULL_FACE); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_VERTEX_ARRAY); _heightfieldBaseBatches.clear(); } if (!_voxelBaseBatches.isEmpty()) { Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true, true); - + glEnableClientState(GL_VERTEX_ARRAY); glDisable(GL_BLEND); glEnable(GL_CULL_FACE); @@ -360,7 +360,7 @@ void MetavoxelSystem::render() { glEnableClientState(GL_COLOR_ARRAY); glEnableClientState(GL_NORMAL_ARRAY); - + _baseVoxelProgram.bind(); foreach (const VoxelBatch& batch, _voxelBaseBatches) { @@ -379,10 +379,10 @@ void MetavoxelSystem::render() { } _baseVoxelProgram.release(); - + glDisable(GL_ALPHA_TEST); glEnable(GL_BLEND); - + Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true, false); if (!_voxelSplatBatches.isEmpty()) { @@ -406,25 +406,25 @@ void MetavoxelSystem::render() { glNormalPointer(GL_BYTE, sizeof(VoxelPoint), &point->normal); _splatVoxelProgram.setAttributeBuffer(_splatVoxelLocations.materials, - GL_UNSIGNED_BYTE, (qint64)&point->materials, SPLAT_COUNT, sizeof(VoxelPoint)); + GL_UNSIGNED_BYTE, (qint64)&point->materials, SPLAT_COUNT, sizeof(VoxelPoint)); _splatVoxelProgram.setAttributeBuffer(_splatVoxelLocations.materialWeights, - GL_UNSIGNED_BYTE, (qint64)&point->materialWeights, SPLAT_COUNT, sizeof(VoxelPoint)); + GL_UNSIGNED_BYTE, (qint64)&point->materialWeights, SPLAT_COUNT, sizeof(VoxelPoint)); const float QUARTER_STEP = 0.25f * EIGHT_BIT_MAXIMUM_RECIPROCAL; _splatVoxelProgram.setUniform(_splatVoxelLocations.splatTextureScalesS, batch.splatTextureScalesS); _splatVoxelProgram.setUniform(_splatVoxelLocations.splatTextureScalesT, batch.splatTextureScalesT); _splatVoxelProgram.setUniformValue( - _splatVoxelLocations.textureValueMinima, - (batch.materialIndex + 1) * EIGHT_BIT_MAXIMUM_RECIPROCAL - QUARTER_STEP, - (batch.materialIndex + 2) * EIGHT_BIT_MAXIMUM_RECIPROCAL - QUARTER_STEP, - (batch.materialIndex + 3) * EIGHT_BIT_MAXIMUM_RECIPROCAL - QUARTER_STEP, - (batch.materialIndex + 4) * EIGHT_BIT_MAXIMUM_RECIPROCAL - QUARTER_STEP); + _splatVoxelLocations.textureValueMinima, + (batch.materialIndex + 1) * EIGHT_BIT_MAXIMUM_RECIPROCAL - QUARTER_STEP, + (batch.materialIndex + 2) * EIGHT_BIT_MAXIMUM_RECIPROCAL - QUARTER_STEP, + (batch.materialIndex + 3) * EIGHT_BIT_MAXIMUM_RECIPROCAL - QUARTER_STEP, + (batch.materialIndex + 4) * EIGHT_BIT_MAXIMUM_RECIPROCAL - QUARTER_STEP); _splatVoxelProgram.setUniformValue( - _splatVoxelLocations.textureValueMaxima, - (batch.materialIndex + 1) * EIGHT_BIT_MAXIMUM_RECIPROCAL + QUARTER_STEP, - (batch.materialIndex + 2) * EIGHT_BIT_MAXIMUM_RECIPROCAL + QUARTER_STEP, - (batch.materialIndex + 3) * EIGHT_BIT_MAXIMUM_RECIPROCAL + QUARTER_STEP, - (batch.materialIndex + 4) * EIGHT_BIT_MAXIMUM_RECIPROCAL + QUARTER_STEP); + _splatVoxelLocations.textureValueMaxima, + (batch.materialIndex + 1) * EIGHT_BIT_MAXIMUM_RECIPROCAL + QUARTER_STEP, + (batch.materialIndex + 2) * EIGHT_BIT_MAXIMUM_RECIPROCAL + QUARTER_STEP, + (batch.materialIndex + 3) * EIGHT_BIT_MAXIMUM_RECIPROCAL + QUARTER_STEP, + (batch.materialIndex + 4) * EIGHT_BIT_MAXIMUM_RECIPROCAL + QUARTER_STEP); for (int i = 0; i < SPLAT_COUNT; i++) { glActiveTexture(GL_TEXTURE0 + SPLAT_TEXTURE_UNITS[i]); @@ -437,9 +437,9 @@ void MetavoxelSystem::render() { glActiveTexture(GL_TEXTURE0 + SPLAT_TEXTURE_UNITS[i]); glBindTexture(GL_TEXTURE_2D, 0); } - + glActiveTexture(GL_TEXTURE0); - + batch.vertexBuffer->release(); batch.indexBuffer->release(); } @@ -517,10 +517,10 @@ public: }; RayVoxelIntersectionVisitor::RayVoxelIntersectionVisitor(const glm::vec3& origin, - const glm::vec3& direction, const MetavoxelLOD& lod) : -RayIntersectionVisitor(origin, direction, QVector() << - Application::getInstance()->getMetavoxels()->getVoxelBufferAttribute(), QVector(), lod), -intersectionDistance(FLT_MAX) { + const glm::vec3& direction, const MetavoxelLOD& lod) : + RayIntersectionVisitor(origin, direction, QVector() << + Application::getInstance()->getMetavoxels()->getVoxelBufferAttribute(), QVector(), lod), + intersectionDistance(FLT_MAX) { } int RayVoxelIntersectionVisitor::visit(MetavoxelInfo& info, float distance) { @@ -528,7 +528,7 @@ int RayVoxelIntersectionVisitor::visit(MetavoxelInfo& info, float distance) { return _order; } const VoxelBuffer* buffer = static_cast( - info.inputValues.at(0).getInlineValue().data()); + info.inputValues.at(0).getInlineValue().data()); if (!buffer) { return STOP_RECURSION; } @@ -630,7 +630,7 @@ public: virtual bool visit(Spanner* spanner); virtual int visit(MetavoxelInfo& info); - + private: Box _bounds; @@ -693,17 +693,17 @@ class BufferCursorRenderVisitor : public MetavoxelVisitor { public: BufferCursorRenderVisitor(const AttributePointer& attribute, const Box& bounds); - + virtual int visit(MetavoxelInfo& info); - + private: Box _bounds; }; BufferCursorRenderVisitor::BufferCursorRenderVisitor(const AttributePointer& attribute, const Box& bounds) : -MetavoxelVisitor(QVector() << attribute), -_bounds(bounds) { + MetavoxelVisitor(QVector() << attribute), + _bounds(bounds) { } int BufferCursorRenderVisitor::visit(MetavoxelInfo& info) { @@ -766,11 +766,11 @@ void MetavoxelSystem::renderVoxelCursor(const glm::vec3& position, float radius) class MaterialEditApplier : public SignalHandler { public: - + MaterialEditApplier(const MetavoxelEditMessage& message, const QSharedPointer texture); virtual void handle(); - + protected: MetavoxelEditMessage _message; @@ -778,8 +778,8 @@ protected: }; MaterialEditApplier::MaterialEditApplier(const MetavoxelEditMessage& message, const QSharedPointer texture) : -_message(message), -_texture(texture) { + _message(message), + _texture(texture) { } void MaterialEditApplier::handle() { @@ -794,16 +794,16 @@ void MetavoxelSystem::applyMaterialEdit(const MetavoxelEditMessage& message, boo if (material && material->getDiffuse().isValid()) { if (QThread::currentThread() != thread()) { QMetaObject::invokeMethod(this, "applyMaterialEdit", Q_ARG(const MetavoxelEditMessage&, message), - Q_ARG(bool, reliable)); + Q_ARG(bool, reliable)); return; } QSharedPointer texture = Application::getInstance()->getTextureCache()->getTexture( - material->getDiffuse(), SPLAT_TEXTURE); + material->getDiffuse(), SPLAT_TEXTURE); if (texture->isLoaded()) { MetavoxelEditMessage newMessage = message; static_cast(newMessage.edit.data())->averageColor = texture->getAverageColor(); - applyEdit(newMessage, true); - + applyEdit(newMessage, true); + } else { MaterialEditApplier* applier = new MaterialEditApplier(message, texture); connect(texture.data(), &Resource::loaded, applier, &SignalHandler::handle); @@ -818,7 +818,7 @@ MetavoxelClient* MetavoxelSystem::createClient(const SharedNodePointer& node) { } void MetavoxelSystem::guideToAugmented(MetavoxelVisitor& visitor, bool render) { - NodeList::getInstance()->eachNode([&visitor, &render](const SharedNodePointer& node) { + NodeList::getInstance()->eachNode([&visitor, &render](const SharedNodePointer& node){ if (node->getType() == NodeType::MetavoxelServer) { QMutexLocker locker(&node->getMutex()); MetavoxelSystemClient* client = static_cast(node->getLinkedData()); @@ -837,9 +837,9 @@ void MetavoxelSystem::guideToAugmented(MetavoxelVisitor& visitor, bool render) { void MetavoxelSystem::loadSplatProgram(const char* type, ProgramObject& program, SplatLocations& locations) { program.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath() + - "shaders/metavoxel_" + type + "_splat.vert"); + "shaders/metavoxel_" + type + "_splat.vert"); program.addShaderFromSourceFile(QGLShader::Fragment, Application::resourcesPath() + - "shaders/metavoxel_" + type + "_splat.frag"); + "shaders/metavoxel_" + type + "_splat.frag"); program.link(); program.bind(); @@ -859,8 +859,8 @@ void MetavoxelSystem::loadSplatProgram(const char* type, ProgramObject& program, } Throttle::Throttle() : -_limit(INT_MAX), -_total(0) { + _limit(INT_MAX), + _total(0) { } bool Throttle::shouldThrottle(int bytes) { @@ -881,7 +881,7 @@ bool Throttle::shouldThrottle(int bytes) { } MetavoxelSystemClient::MetavoxelSystemClient(const SharedNodePointer& node, MetavoxelUpdater* updater) : -MetavoxelClient(node, updater) { + MetavoxelClient(node, updater) { } void MetavoxelSystemClient::setAugmentedData(const MetavoxelData& data) { @@ -898,11 +898,11 @@ class ReceiveDelayer : public QObject { public: ReceiveDelayer(const SharedNodePointer& node, const QByteArray& packet); - + protected: - + virtual void timerEvent(QTimerEvent* event); - + private: SharedNodePointer _node; @@ -910,8 +910,8 @@ private: }; ReceiveDelayer::ReceiveDelayer(const SharedNodePointer& node, const QByteArray& packet) : -_node(node), -_packet(packet) { + _node(node), + _packet(packet) { } void ReceiveDelayer::timerEvent(QTimerEvent* event) { @@ -956,16 +956,16 @@ public: AugmentVisitor(const MetavoxelLOD& lod, const MetavoxelData& previousData); virtual int visit(MetavoxelInfo& info); - + private: const MetavoxelData& _previousData; }; AugmentVisitor::AugmentVisitor(const MetavoxelLOD& lod, const MetavoxelData& previousData) : -MetavoxelVisitor(QVector() << AttributeRegistry::getInstance()->getRendererAttribute(), - QVector(), lod), -_previousData(previousData) { + MetavoxelVisitor(QVector() << AttributeRegistry::getInstance()->getRendererAttribute(), + QVector(), lod), + _previousData(previousData) { } int AugmentVisitor::visit(MetavoxelInfo& info) { @@ -973,7 +973,7 @@ int AugmentVisitor::visit(MetavoxelInfo& info) { return DEFAULT_ORDER; } static_cast(info.inputValues.at(0).getInlineValue< - SharedObjectPointer>().data())->getImplementation()->augment(*_data, _previousData, info, _lod); + SharedObjectPointer>().data())->getImplementation()->augment(*_data, _previousData, info, _lod); return STOP_RECURSION; } @@ -981,10 +981,10 @@ class Augmenter : public QRunnable { public: Augmenter(const SharedNodePointer& node, const MetavoxelData& data, - const MetavoxelData& previousData, const MetavoxelLOD& lod); + const MetavoxelData& previousData, const MetavoxelLOD& lod); virtual void run(); - + private: QWeakPointer _node; @@ -994,11 +994,11 @@ private: }; Augmenter::Augmenter(const SharedNodePointer& node, const MetavoxelData& data, - const MetavoxelData& previousData, const MetavoxelLOD& lod) : -_node(node), -_data(data), -_previousData(previousData), -_lod(lod) { + const MetavoxelData& previousData, const MetavoxelLOD& lod) : + _node(node), + _data(data), + _previousData(previousData), + _lod(lod) { } void Augmenter::run() { @@ -1016,7 +1016,7 @@ void MetavoxelSystemClient::refreshVoxelData() { // make it look as if all the colors have changed MetavoxelData oldData = getAugmentedData(); oldData.touch(AttributeRegistry::getInstance()->getVoxelColorAttribute()); - + QThreadPool::globalInstance()->start(new Augmenter(_node, _data, oldData, _remoteDataLOD)); } @@ -1029,9 +1029,9 @@ class SendDelayer : public QObject { public: SendDelayer(const SharedNodePointer& node, const QByteArray& data); - + virtual void timerEvent(QTimerEvent* event); - + private: SharedNodePointer _node; @@ -1039,8 +1039,8 @@ private: }; SendDelayer::SendDelayer(const SharedNodePointer& node, const QByteArray& data) : -_node(node), -_data(data.constData(), data.size()) { + _node(node), + _data(data.constData(), data.size()) { } void SendDelayer::timerEvent(QTimerEvent* event) { @@ -1083,21 +1083,21 @@ void VoxelPoint::setNormal(const glm::vec3& normal) { } VoxelBuffer::VoxelBuffer(const QVector& vertices, const QVector& indices, const QVector& hermite, - const QMultiHash& quadIndices, int size, const QVector& materials) : -_vertices(vertices), -_indices(indices), -_hermite(hermite), -_quadIndices(quadIndices), -_size(size), -_vertexCount(vertices.size()), -_indexCount(indices.size()), -_hermiteCount(hermite.size()), -_indexBuffer(QOpenGLBuffer::IndexBuffer), -_materials(materials) { + const QMultiHash& quadIndices, int size, const QVector& materials) : + _vertices(vertices), + _indices(indices), + _hermite(hermite), + _quadIndices(quadIndices), + _size(size), + _vertexCount(vertices.size()), + _indexCount(indices.size()), + _hermiteCount(hermite.size()), + _indexBuffer(QOpenGLBuffer::IndexBuffer), + _materials(materials) { } bool VoxelBuffer::findFirstRayIntersection(const glm::vec3& entry, const glm::vec3& origin, - const glm::vec3& direction, float& distance) const { + const glm::vec3& direction, float& distance) const { float highest = _size - 1.0f; glm::vec3 position = entry * highest; glm::vec3 floors = glm::floor(position); @@ -1105,14 +1105,14 @@ bool VoxelBuffer::findFirstRayIntersection(const glm::vec3& entry, const glm::ve int x = qMin((int)floors.x, max), y = qMin((int)floors.y, max), z = qMin((int)floors.z, max); forever { for (QMultiHash::const_iterator it = _quadIndices.constFind(qRgb(x + 1, y + 1, z + 1)); - it != _quadIndices.constEnd(); it++) { + it != _quadIndices.constEnd(); it++) { const int* indices = _indices.constData() + *it; if (findRayTriangleIntersection(origin, direction, _vertices.at(indices[0]).vertex, - _vertices.at(indices[1]).vertex, _vertices.at(indices[2]).vertex, distance) || + _vertices.at(indices[1]).vertex, _vertices.at(indices[2]).vertex, distance) || findRayTriangleIntersection(origin, direction, _vertices.at(indices[0]).vertex, - _vertices.at(indices[2]).vertex, _vertices.at(indices[3]).vertex, distance)) { - return true; - } + _vertices.at(indices[2]).vertex, _vertices.at(indices[3]).vertex, distance)) { + return true; + } } float xDistance = FLT_MAX, yDistance = FLT_MAX, zDistance = FLT_MAX; if (direction.x > 0.0f) { @@ -1181,7 +1181,7 @@ void VoxelBuffer::render(bool cursor) { const SharedObjectPointer material = _materials.at(i); if (material) { _networkTextures[i] = Application::getInstance()->getTextureCache()->getTexture( - static_cast(material.data())->getDiffuse(), SPLAT_TEXTURE); + static_cast(material.data())->getDiffuse(), SPLAT_TEXTURE); } } } @@ -1216,7 +1216,7 @@ void VoxelBuffer::render(bool cursor) { splatBatch.indexBuffer = &_indexBuffer; splatBatch.vertexCount = _vertexCount; splatBatch.indexCount = _indexCount; - + for (int i = 0; i < _materials.size(); i += SPLAT_COUNT) { for (int j = 0; j < SPLAT_COUNT; j++) { int index = i + j; @@ -1227,7 +1227,7 @@ void VoxelBuffer::render(bool cursor) { splatBatch.splatTextureScalesS[j] = 1.0f / material->getScaleS(); splatBatch.splatTextureScalesT[j] = 1.0f / material->getScaleT(); splatBatch.splatTextureIDs[j] = texture->getID(); - + } else { splatBatch.splatTextureIDs[j] = 0; } @@ -1256,7 +1256,7 @@ void VoxelBuffer::render(bool cursor) { } BufferDataAttribute::BufferDataAttribute(const QString& name) : -InlineAttribute(name) { + InlineAttribute(name) { } bool BufferDataAttribute::merge(void*& parent, void* children[], bool postRead) const { @@ -1278,17 +1278,17 @@ DefaultMetavoxelRendererImplementation::DefaultMetavoxelRendererImplementation() class VoxelAugmentVisitor : public MetavoxelVisitor { public: - + VoxelAugmentVisitor(const MetavoxelLOD& lod); virtual int visit(MetavoxelInfo& info); }; VoxelAugmentVisitor::VoxelAugmentVisitor(const MetavoxelLOD& lod) : -MetavoxelVisitor(QVector() << AttributeRegistry::getInstance()->getVoxelColorAttribute() << - AttributeRegistry::getInstance()->getVoxelMaterialAttribute() << - AttributeRegistry::getInstance()->getVoxelHermiteAttribute(), QVector() << - Application::getInstance()->getMetavoxels()->getVoxelBufferAttribute(), lod) { + MetavoxelVisitor(QVector() << AttributeRegistry::getInstance()->getVoxelColorAttribute() << + AttributeRegistry::getInstance()->getVoxelMaterialAttribute() << + AttributeRegistry::getInstance()->getVoxelHermiteAttribute(), QVector() << + Application::getInstance()->getMetavoxels()->getVoxelBufferAttribute(), lod) { } class EdgeCrossing { @@ -1446,9 +1446,9 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { // its properties (color, material, normal) if one is present; as before, boundary edges are excluded int clampedX = qMax(x - 1, 0), clampedY = qMax(y - 1, 0), clampedZ = qMax(z - 1, 0); const QRgb* hermiteBase = hermiteData + clampedZ * hermiteArea + clampedY * hermiteStride + - clampedX * VoxelHermiteData::EDGE_COUNT; + clampedX * VoxelHermiteData::EDGE_COUNT; const char* materialBase = materialData ? - (materialData + clampedZ * area + clampedY * size + clampedX) : NULL; + (materialData + clampedZ * area + clampedY * size + clampedX) : NULL; int crossingCount = 0; if (middleX) { if (alpha0 != alpha1) { @@ -1650,7 +1650,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { if (displayHermite) { glm::vec3 start = info.minimum + (glm::vec3(clampedX, clampedY, clampedZ) + - crossing.point) * scale; + crossing.point) * scale; hermiteSegments.append(start); hermiteSegments.append(start + crossing.normal * scale); } @@ -1710,18 +1710,18 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { for (int i = 0; i < MAX_ITERATIONS; i++) { glm::vec3 offDiagonals = glm::abs(glm::vec3(d[1][0], d[2][0], d[2][1])); int largestIndex = (offDiagonals[0] > offDiagonals[1]) ? (offDiagonals[0] > offDiagonals[2] ? 0 : 2) : - (offDiagonals[1] > offDiagonals[2] ? 1 : 2); + (offDiagonals[1] > offDiagonals[2] ? 1 : 2); const float DESIRED_PRECISION = 0.00001f; if (offDiagonals[largestIndex] < DESIRED_PRECISION) { break; } int largestJ = (largestIndex == 2) ? 1 : 0; - int largestI = (largestIndex == 0) ? 1 : 2; + int largestI = (largestIndex == 0) ? 1 : 2; float sjj = d[largestJ][largestJ]; float sii = d[largestI][largestI]; float angle = glm::atan(2.0f * d[largestJ][largestI], sjj - sii) / 2.0f; glm::quat rotation = glm::angleAxis(angle, largestIndex == 0 ? glm::vec3(0.0f, 0.0f, -1.0f) : - (largestIndex == 1 ? glm::vec3(0.0f, 1.0f, 0.0f) : glm::vec3(-1.0f, 0.0f, 0.0f))); + (largestIndex == 1 ? glm::vec3(0.0f, 1.0f, 0.0f) : glm::vec3(-1.0f, 0.0f, 0.0f))); combinedRotation = glm::normalize(rotation * combinedRotation); glm::mat3 matrix = glm::mat3_cast(combinedRotation); d = matrix * ata * glm::transpose(matrix); @@ -1735,7 +1735,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { // compute the pseudo-inverse, ataplus, and use to find the minimizing solution glm::mat3 u = glm::mat3_cast(combinedRotation); - glm::mat3 ataplus = glm::transpose(u) * d * u; + glm::mat3 ataplus = glm::transpose(u) * d * u; glm::vec3 solution = (ataplus * atrans * b) + center; // make sure it doesn't fall beyond the cell boundaries @@ -1774,7 +1774,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { const glm::vec3& first = vertices.at(index.indices[0]).vertex; glm::vec3 normal = glm::cross(vertices.at(index1.indices[0]).vertex - first, - vertices.at(index3.indices[0]).vertex - first); + vertices.at(index3.indices[0]).vertex - first); if (alpha0 == 0) { // quad faces negative x indices.append(index3.getClosestIndex(normal = -normal, vertices)); @@ -1800,7 +1800,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { const glm::vec3& first = vertices.at(index.indices[0]).vertex; glm::vec3 normal = glm::cross(vertices.at(index3.indices[0]).vertex - first, - vertices.at(index1.indices[0]).vertex - first); + vertices.at(index1.indices[0]).vertex - first); if (alpha0 == 0) { // quad faces negative y indices.append(index1.getClosestIndex(normal = -normal, vertices)); @@ -1826,7 +1826,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { const glm::vec3& first = vertices.at(index.indices[0]).vertex; glm::vec3 normal = glm::cross(vertices.at(index1.indices[0]).vertex - first, - vertices.at(index3.indices[0]).vertex - first); + vertices.at(index3.indices[0]).vertex - first); if (alpha0 == 0) { // quad faces negative z indices.append(index3.getClosestIndex(normal = -normal, vertices)); @@ -1861,7 +1861,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { } } buffer = new VoxelBuffer(vertices, indices, hermiteSegments, quadIndices, size, - material ? material->getMaterials() : QVector()); + material ? material->getMaterials() : QVector()); } BufferDataPointer pointer(buffer); info.outputValues[0] = AttributeValue(_outputs.at(0), encodeInline(pointer)); @@ -1869,14 +1869,14 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { } void DefaultMetavoxelRendererImplementation::augment(MetavoxelData& data, const MetavoxelData& previous, - MetavoxelInfo& info, const MetavoxelLOD& lod) { + MetavoxelInfo& info, const MetavoxelLOD& lod) { // copy the previous buffers MetavoxelData expandedPrevious = previous; while (expandedPrevious.getSize() < data.getSize()) { expandedPrevious.expand(); } const AttributePointer& voxelBufferAttribute = - Application::getInstance()->getMetavoxels()->getVoxelBufferAttribute(); + Application::getInstance()->getMetavoxels()->getVoxelBufferAttribute(); MetavoxelNode* root = expandedPrevious.getRoot(voxelBufferAttribute); if (root) { data.setRoot(voxelBufferAttribute, root); @@ -1892,16 +1892,16 @@ public: SpannerSimulateVisitor(float deltaTime, const MetavoxelLOD& lod); virtual bool visit(Spanner* spanner); - + private: float _deltaTime; }; SpannerSimulateVisitor::SpannerSimulateVisitor(float deltaTime, const MetavoxelLOD& lod) : -SpannerVisitor(QVector() << AttributeRegistry::getInstance()->getSpannersAttribute(), - QVector(), QVector(), lod), -_deltaTime(deltaTime) { + SpannerVisitor(QVector() << AttributeRegistry::getInstance()->getSpannersAttribute(), + QVector(), QVector(), lod), + _deltaTime(deltaTime) { } bool SpannerSimulateVisitor::visit(Spanner* spanner) { @@ -1910,7 +1910,7 @@ bool SpannerSimulateVisitor::visit(Spanner* spanner) { } void DefaultMetavoxelRendererImplementation::simulate(MetavoxelData& data, float deltaTime, - MetavoxelInfo& info, const MetavoxelLOD& lod) { + MetavoxelInfo& info, const MetavoxelLOD& lod) { SpannerSimulateVisitor spannerSimulateVisitor(deltaTime, lod); data.guide(spannerSimulateVisitor); } @@ -1921,7 +1921,7 @@ public: BufferRenderVisitor(const AttributePointer& attribute); virtual int visit(MetavoxelInfo& info); - + private: int _order; @@ -1929,15 +1929,15 @@ private: }; BufferRenderVisitor::BufferRenderVisitor(const AttributePointer& attribute) : -MetavoxelVisitor(QVector() << attribute), -_order(encodeOrder(Application::getInstance()->getDisplayViewFrustum()->getDirection())), -_containmentDepth(INT_MAX) { + MetavoxelVisitor(QVector() << attribute), + _order(encodeOrder(Application::getInstance()->getDisplayViewFrustum()->getDirection())), + _containmentDepth(INT_MAX) { } int BufferRenderVisitor::visit(MetavoxelInfo& info) { if (_containmentDepth >= _depth) { Frustum::IntersectionType intersection = Application::getInstance()->getMetavoxels()->getFrustum().getIntersectionType( - info.getBounds()); + info.getBounds()); if (intersection == Frustum::NO_INTERSECTION) { return STOP_RECURSION; } @@ -2007,12 +2007,12 @@ void CuboidRenderer::render(const MetavoxelLOD& lod, bool contained, bool cursor } StaticModelRenderer::StaticModelRenderer() : -_model(new Model(this)) { + _model(new Model(this)) { } void StaticModelRenderer::init(Spanner* spanner) { SpannerRenderer::init(spanner); - + _model->init(); StaticModel* staticModel = static_cast(spanner); @@ -2035,7 +2035,7 @@ void StaticModelRenderer::simulate(float deltaTime) { bounds = Box(extents.minimum, extents.maximum); } static_cast(_spanner)->setBounds(glm::translate(_model->getTranslation()) * - glm::mat4_cast(_model->getRotation()) * glm::scale(_model->getScale()) * bounds); + glm::mat4_cast(_model->getRotation()) * glm::scale(_model->getScale()) * bounds); _model->simulate(deltaTime); } @@ -2251,7 +2251,7 @@ void HeightfieldNodeRenderer::render(const HeightfieldNodePointer& node, const g if (cursor) { bufferPair.first.bind(); bufferPair.second.bind(); - + glPushMatrix(); glTranslatef(translation.x, translation.y, translation.z); glm::vec3 axis = glm::axis(rotation); @@ -2286,7 +2286,7 @@ void HeightfieldNodeRenderer::render(const HeightfieldNodePointer& node, const g baseBatch.heightScale = glm::vec4(1.0f / width, 1.0f / height, (innerWidth - 1) / -2.0f, (innerHeight - 1) / -2.0f); baseBatch.colorTextureID = _colorTextureID; baseBatch.colorScale = glm::vec2((float)width / innerWidth, (float)height / innerHeight); - Application::getInstance()->getMetavoxels()->addHeightfieldBaseBatch(baseBatch); + Application::getInstance()->getMetavoxels()->addHeightfieldBaseBatch(baseBatch); if (!_networkTextures.isEmpty()) { HeightfieldSplatBatch splatBatch; @@ -2331,3 +2331,4 @@ void HeightfieldNodeRenderer::render(const HeightfieldNodePointer& node, const g } QHash HeightfieldNodeRenderer::_bufferPairs; + From bf5147cd918bb9392cd57452c8e52fb58ab4fc88 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 15 Dec 2014 12:56:32 -0800 Subject: [PATCH 43/62] fix qt modules to link in LinkSharedDependencies --- cmake/macros/LinkSharedDependencies.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/macros/LinkSharedDependencies.cmake b/cmake/macros/LinkSharedDependencies.cmake index a73f57dc1d..afd25db0d7 100644 --- a/cmake/macros/LinkSharedDependencies.cmake +++ b/cmake/macros/LinkSharedDependencies.cmake @@ -25,7 +25,7 @@ macro(LINK_SHARED_DEPENDENCIES) endif () # we've already linked our Qt modules, but we need to bubble them up to parents - list(APPEND ${TARGET_NAME}_LIBRARIES_TO_LINK "${${TARGET}_QT_MODULES_TO_LINK}") + list(APPEND ${TARGET_NAME}_LIBRARIES_TO_LINK "${${TARGET_NAME}_QT_MODULES_TO_LINK}") # set the property on this target so it can be retreived by targets linking to us set_target_properties(${TARGET_NAME} PROPERTIES DEPENDENCY_LIBRARIES "${${TARGET_NAME}_LIBRARIES_TO_LINK}") From 4d8d6d602a269679aae5bf73e41103f8986c58b4 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 15 Dec 2014 13:56:21 -0800 Subject: [PATCH 44/62] simplify the FindTBB module for set envs --- BUILD_LINUX.md | 8 +- BUILD_OSX.md | 2 +- BUILD_WIN.md | 6 - cmake/modules/FindTBB.cmake | 328 +++++++----------------------------- 4 files changed, 62 insertions(+), 282 deletions(-) diff --git a/BUILD_LINUX.md b/BUILD_LINUX.md index 7b6c8f2176..08945716ae 100644 --- a/BUILD_LINUX.md +++ b/BUILD_LINUX.md @@ -9,10 +9,4 @@ In general, as long as external dependencies are placed in OS standard locations ###Qt5 Dependencies Should you choose not to install Qt5 via a package manager that handles dependencies for you, you may be missing some Qt5 dependencies. On Ubuntu, for example, the following additional packages are required: - libasound2 libxmu-dev libxi-dev freeglut3-dev libasound2-dev libjack-dev - -###Intel Threading Building Blocks (TBB) - -Install Intel TBB from your package manager of choice, or from source (available at the [TBB Website](https://www.threadingbuildingblocks.org/)). - -You must run `tbbvars` before running cmake that the find module included with this project will be able to find the correct version of TBB. `tbbvars` is located in the 'bin' folder of your TBB install. \ No newline at end of file + libasound2 libxmu-dev libxi-dev freeglut3-dev libasound2-dev libjack-dev \ No newline at end of file diff --git a/BUILD_OSX.md b/BUILD_OSX.md index 1eeaed1c13..cd947f2af4 100644 --- a/BUILD_OSX.md +++ b/BUILD_OSX.md @@ -19,4 +19,4 @@ If Xcode is your editor of choice, you can ask CMake to generate Xcode project f After running cmake, you will have the make files or Xcode project file necessary to build all of the components. Open the hifi.xcodeproj file, choose ALL_BUILD from the Product > Scheme menu (or target drop down), and click Run. -If the build completes successfully, you will have built targets for all components located in the `build/${target_name}/Debug` directories. +If the build completes successfully, you will have built targets for all components located in the `build/${target_name}/Debug` directories. \ No newline at end of file diff --git a/BUILD_WIN.md b/BUILD_WIN.md index bf7d421715..b90396b757 100644 --- a/BUILD_WIN.md +++ b/BUILD_WIN.md @@ -95,12 +95,6 @@ To prevent these problems, install OpenSSL yourself. Download the following bina Install OpenSSL into the Windows system directory, to make sure that QT uses the version that you've just installed, and not some other version. -###Intel Threading Building Blocks (TBB) - -Download the stable release for Windows from the [Intel Threading Building Blocks website](https://www.threadingbuildingblocks.org/). By default, TBB will install to Program Files. You can choose to install it wherever you like, including %HIFI_LIB_DIR%. - -You must run `tbbvars.bat` before running cmake so that the find module included with this project will be able to find TBB no matter where you installed it. `tbbvars.bat` is located in the 'bin' folder of your TBB install. For a default installation on a 64-bit architechture, tbbvars can be found at `C:/Program Files (x86)/Intel/TBB/bin/tbbvars.bat`. - ###Zlib Download the compiled DLL from the [zlib website](http://www.zlib.net/). Extract to %HIFI_LIB_DIR%\zlib. diff --git a/cmake/modules/FindTBB.cmake b/cmake/modules/FindTBB.cmake index e5ca100391..c6c1890a09 100644 --- a/cmake/modules/FindTBB.cmake +++ b/cmake/modules/FindTBB.cmake @@ -1,283 +1,75 @@ -# Locate Intel Threading Building Blocks include paths and libraries -# FindTBB.cmake can be found at https://code.google.com/p/findtbb/ -# Written by Hannes Hofmann -# Improvements by Gino van den Bergen , -# Florian Uhlig , -# Jiri Marsik - -# The MIT License +# +# FindTBB.cmake +# +# Try to find the Intel Threading Building Blocks library # -# Copyright (c) 2011 Hannes Hofmann +# You can provide a TBB_ROOT_DIR which contains lib and include directories # -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: +# Once done this will define # -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. +# TBB_FOUND - system was able to find TBB +# TBB_INCLUDE_DIRS - the TBB include directory +# TBB_LIBRARIES - link this to use TBB # -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -# GvdB: This module uses the environment variable TBB_ARCH_PLATFORM which defines architecture and compiler. -# e.g. "ia32/vc8" or "em64t/cc4.1.0_libc2.4_kernel2.6.16.21" -# TBB_ARCH_PLATFORM is set by the build script tbbvars[.bat|.sh|.csh], which can be found -# in the TBB installation directory (TBB_INSTALL_DIR). +# Created on 12/14/2014 by Stephen Birarda +# Copyright 2014 High Fidelity, Inc. # -# GvdB: Mac OS X distribution places libraries directly in lib directory. -# -# For backwards compatibility, you may explicitely set the CMake variables TBB_ARCHITECTURE and TBB_COMPILER. -# TBB_ARCHITECTURE [ ia32 | em64t | itanium ] -# which architecture to use -# TBB_COMPILER e.g. vc9 or cc3.2.3_libc2.3.2_kernel2.4.21 or cc4.0.1_os10.4.9 -# which compiler to use (detected automatically on Windows) +# Distributed under the Apache License, Version 2.0. +# See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +# -# This module respects -# TBB_INSTALL_DIR or $ENV{TBB21_INSTALL_DIR} or $ENV{TBB_INSTALL_DIR} +include("${MACRO_DIR}/HifiLibrarySearchHints.cmake") +hifi_library_search_hints("tbb") -# This module defines -# TBB_INCLUDE_DIRS, where to find task_scheduler_init.h, etc. -# TBB_LIBRARY_DIRS, where to find libtbb, libtbbmalloc -# TBB_DEBUG_LIBRARY_DIRS, where to find libtbb_debug, libtbbmalloc_debug -# TBB_INSTALL_DIR, the base TBB install directory -# TBB_LIBRARIES, the libraries to link against to use TBB. -# TBB_DEBUG_LIBRARIES, the libraries to link against to use TBB with debug symbols. -# TBB_FOUND, If false, don't try to use TBB. -# TBB_INTERFACE_VERSION, as defined in tbb/tbb_stddef.h +find_path(TBB_INCLUDE_DIRS tbb/tbb.h PATH_SUFFIXES include HINTS ${TBB_SEARCH_DIRS}) +set(_TBB_LIB_NAME "tbb") +set(_TBB_LIB_MALLOC_NAME "${_TBB_LIB_NAME}malloc") -if (WIN32) - # has em64t/vc8 em64t/vc9 - # has ia32/vc7.1 ia32/vc8 ia32/vc9 - set(_TBB_DEFAULT_INSTALL_DIR "C:/Program Files/Intel/TBB" "C:/Program Files (x86)/Intel/TBB") - set(_TBB_LIB_NAME "tbb") - set(_TBB_LIB_MALLOC_NAME "${_TBB_LIB_NAME}malloc") - set(_TBB_LIB_DEBUG_NAME "${_TBB_LIB_NAME}_debug") - set(_TBB_LIB_MALLOC_DEBUG_NAME "${_TBB_LIB_MALLOC_NAME}_debug") - if (MSVC71) - set (_TBB_COMPILER "vc7.1") - endif(MSVC71) - if (MSVC80) - set(_TBB_COMPILER "vc8") - endif(MSVC80) - if (MSVC90) - set(_TBB_COMPILER "vc9") - endif(MSVC90) - if(MSVC10) - set(_TBB_COMPILER "vc10") - endif(MSVC10) - # Todo: add other Windows compilers such as ICL. - set(_TBB_ARCHITECTURE ${TBB_ARCHITECTURE}) -endif (WIN32) +if (APPLE) + set(_TBB_LIB_DIR "lib/libc++") +elseif (UNIX) + if(CMAKE_SIZEOF_VOID_P EQUAL 8) + set(_TBB_ARCH_DIR "intel64") + else() + set(_TBB_ARCH_DIR "ia32") + endif() + + execute_process( + COMMAND ${CMAKE_C_COMPILER} -dumpversion + OUTPUT_VARIABLE GCC_VERSION + ) + + if (GCC_VERSION VERSION_GREATER 4.4 OR GCC_VERSION VERSION_EQUAL 4.4) + set(_TBB_LIB_DIR "${_TBB_ARCH_DIR}/gcc4.4") + elseif (GCC_VERSION VERSION_GREATER 4.1 OR GCC_VERSION VERSION_EQUAL 4.1) + set(_TBB_LIB_DIR "${_TBB_ARCH_DIR}/gcc4.1") + else () + message(FATAL_ERROR "Could not find a compatible version of Threading Building Blocks library for your compiler.") + endif () + +elseif (WIN32) + if (CMAKE_CL_64) + set(_TBB_ARCH_DIR "intel64") + else() + set(_TBB_ARCH_DIR "ia32") + endif() + + set(_TBB_LIB_DIR "${_TBB_ARCH_DIR}/vc12") +endif () -if (UNIX) - if (APPLE) - # MAC - set(_TBB_DEFAULT_INSTALL_DIR "/Library/Frameworks/Intel_TBB.framework/Versions") - # libs: libtbb.dylib, libtbbmalloc.dylib, *_debug - set(_TBB_LIB_NAME "tbb") - set(_TBB_LIB_MALLOC_NAME "${_TBB_LIB_NAME}malloc") - set(_TBB_LIB_DEBUG_NAME "${_TBB_LIB_NAME}_debug") - set(_TBB_LIB_MALLOC_DEBUG_NAME "${_TBB_LIB_MALLOC_NAME}_debug") - # default flavor on apple: ia32/cc4.0.1_os10.4.9 - # Jiri: There is no reason to presume there is only one flavor and - # that user's setting of variables should be ignored. - if(NOT TBB_COMPILER) - set(_TBB_COMPILER "cc4.0.1_os10.4.9") - elseif (NOT TBB_COMPILER) - set(_TBB_COMPILER ${TBB_COMPILER}) - endif(NOT TBB_COMPILER) - if(NOT TBB_ARCHITECTURE) - set(_TBB_ARCHITECTURE "ia32") - elseif(NOT TBB_ARCHITECTURE) - set(_TBB_ARCHITECTURE ${TBB_ARCHITECTURE}) - endif(NOT TBB_ARCHITECTURE) - else (APPLE) - # LINUX - set(_TBB_DEFAULT_INSTALL_DIR "/opt/intel/tbb" "/usr/local/include" "/usr/include") - set(_TBB_LIB_NAME "tbb") - set(_TBB_LIB_MALLOC_NAME "${_TBB_LIB_NAME}malloc") - set(_TBB_LIB_DEBUG_NAME "${_TBB_LIB_NAME}_debug") - set(_TBB_LIB_MALLOC_DEBUG_NAME "${_TBB_LIB_MALLOC_NAME}_debug") - # has em64t/cc3.2.3_libc2.3.2_kernel2.4.21 em64t/cc3.3.3_libc2.3.3_kernel2.6.5 em64t/cc3.4.3_libc2.3.4_kernel2.6.9 em64t/cc4.1.0_libc2.4_kernel2.6.16.21 - # has ia32/* - # has itanium/* - set(_TBB_COMPILER ${TBB_COMPILER}) - set(_TBB_ARCHITECTURE ${TBB_ARCHITECTURE}) - endif (APPLE) -endif (UNIX) +find_library(TBB_LIBRARY_DEBUG NAMES ${_TBB_LIB_NAME}_debug PATH_SUFFIXES ${_TBB_LIB_DIR} HINTS ${TBB_SEARCH_DIRS}) +find_library(TBB_LIBRARY_RELEASE NAMES ${_TBB_LIB_NAME} PATH_SUFFIXES ${_TBB_LIB_DIR} HINTS ${TBB_SEARCH_DIRS}) -if (CMAKE_SYSTEM MATCHES "SunOS.*") -# SUN -# not yet supported -# has em64t/cc3.4.3_kernel5.10 -# has ia32/* -endif (CMAKE_SYSTEM MATCHES "SunOS.*") +find_library(TBB_MALLOC_LIBRARY_DEBUG NAMES ${_TBB_LIB_MALLOC_NAME}_debug PATH_SUFFIXES ${_TBB_LIB_DIR} HINTS ${TBB_SEARCH_DIRS}) +find_library(TBB_MALLOC_LIBRARY_RELEASE NAMES ${_TBB_LIB_MALLOC_NAME} PATH_SUFFIXES ${_TBB_LIB_DIR} HINTS ${TBB_SEARCH_DIRS}) +include(SelectLibraryConfigurations) +include(FindPackageHandleStandardArgs) -#-- Clear the public variables -set (TBB_FOUND "NO") +select_library_configurations(TBB) +select_library_configurations(TBB_MALLOC) +find_package_handle_standard_args(TBB DEFAULT_MSG TBB_LIBRARY TBB_MALLOC_LIBRARY TBB_INCLUDE_DIRS) -#-- Find TBB install dir and set ${_TBB_INSTALL_DIR} and cached ${TBB_INSTALL_DIR} -# first: use CMake variable TBB_INSTALL_DIR -if (TBB_INSTALL_DIR) - set (_TBB_INSTALL_DIR ${TBB_INSTALL_DIR}) -endif (TBB_INSTALL_DIR) -# second: use environment variable -if (NOT _TBB_INSTALL_DIR) - if (NOT "$ENV{TBB_INSTALL_DIR}" STREQUAL "") - set (_TBB_INSTALL_DIR $ENV{TBB_INSTALL_DIR}) - endif (NOT "$ENV{TBB_INSTALL_DIR}" STREQUAL "") - # Intel recommends setting TBB21_INSTALL_DIR - if (NOT "$ENV{TBB21_INSTALL_DIR}" STREQUAL "") - set (_TBB_INSTALL_DIR $ENV{TBB21_INSTALL_DIR}) - endif (NOT "$ENV{TBB21_INSTALL_DIR}" STREQUAL "") - if (NOT "$ENV{TBB22_INSTALL_DIR}" STREQUAL "") - set (_TBB_INSTALL_DIR $ENV{TBB22_INSTALL_DIR}) - endif (NOT "$ENV{TBB22_INSTALL_DIR}" STREQUAL "") - if (NOT "$ENV{TBB30_INSTALL_DIR}" STREQUAL "") - set (_TBB_INSTALL_DIR $ENV{TBB30_INSTALL_DIR}) - endif (NOT "$ENV{TBB30_INSTALL_DIR}" STREQUAL "") -endif (NOT _TBB_INSTALL_DIR) -# third: try to find path automatically -if (NOT _TBB_INSTALL_DIR) - if (_TBB_DEFAULT_INSTALL_DIR) - set (_TBB_INSTALL_DIR ${_TBB_DEFAULT_INSTALL_DIR}) - endif (_TBB_DEFAULT_INSTALL_DIR) -endif (NOT _TBB_INSTALL_DIR) -# sanity check -if (NOT _TBB_INSTALL_DIR) - message ("ERROR: Unable to find Intel TBB install directory. ${_TBB_INSTALL_DIR}") -else (NOT _TBB_INSTALL_DIR) -# finally: set the cached CMake variable TBB_INSTALL_DIR -if (NOT TBB_INSTALL_DIR) - set (TBB_INSTALL_DIR ${_TBB_INSTALL_DIR} CACHE PATH "Intel TBB install directory") - mark_as_advanced(TBB_INSTALL_DIR) -endif (NOT TBB_INSTALL_DIR) - - -#-- A macro to rewrite the paths of the library. This is necessary, because -# find_library() always found the em64t/vc9 version of the TBB libs -macro(TBB_CORRECT_LIB_DIR var_name) -# if (NOT "${_TBB_ARCHITECTURE}" STREQUAL "em64t") - string(REPLACE em64t "${_TBB_ARCHITECTURE}" ${var_name} ${${var_name}}) -# endif (NOT "${_TBB_ARCHITECTURE}" STREQUAL "em64t") - string(REPLACE ia32 "${_TBB_ARCHITECTURE}" ${var_name} ${${var_name}}) - string(REPLACE vc7.1 "${_TBB_COMPILER}" ${var_name} ${${var_name}}) - string(REPLACE vc8 "${_TBB_COMPILER}" ${var_name} ${${var_name}}) - string(REPLACE vc9 "${_TBB_COMPILER}" ${var_name} ${${var_name}}) - string(REPLACE vc10 "${_TBB_COMPILER}" ${var_name} ${${var_name}}) -endmacro(TBB_CORRECT_LIB_DIR var_content) - - -#-- Look for include directory and set ${TBB_INCLUDE_DIR} -set (TBB_INC_SEARCH_DIR ${_TBB_INSTALL_DIR}/include) -# Jiri: tbbvars now sets the CPATH environment variable to the directory -# containing the headers. -find_path(TBB_INCLUDE_DIR - tbb/task_scheduler_init.h - PATHS ${TBB_INC_SEARCH_DIR} ENV CPATH -) -mark_as_advanced(TBB_INCLUDE_DIR) - - -#-- Look for libraries -# GvdB: $ENV{TBB_ARCH_PLATFORM} is set by the build script tbbvars[.bat|.sh|.csh] -if (NOT $ENV{TBB_ARCH_PLATFORM} STREQUAL "") - set (_TBB_LIBRARY_DIR - ${_TBB_INSTALL_DIR}/lib/$ENV{TBB_ARCH_PLATFORM} - ${_TBB_INSTALL_DIR}/$ENV{TBB_ARCH_PLATFORM}/lib - ) -endif (NOT $ENV{TBB_ARCH_PLATFORM} STREQUAL "") -# Jiri: This block isn't mutually exclusive with the previous one -# (hence no else), instead I test if the user really specified -# the variables in question. -if ((NOT ${TBB_ARCHITECTURE} STREQUAL "") AND (NOT ${TBB_COMPILER} STREQUAL "")) - # HH: deprecated - message(STATUS "[Warning] FindTBB.cmake: The use of TBB_ARCHITECTURE and TBB_COMPILER is deprecated and may not be supported in future versions. Please set \$ENV{TBB_ARCH_PLATFORM} (using tbbvars.[bat|csh|sh]).") - # Jiri: It doesn't hurt to look in more places, so I store the hints from - # ENV{TBB_ARCH_PLATFORM} and the TBB_ARCHITECTURE and TBB_COMPILER - # variables and search them both. - set (_TBB_LIBRARY_DIR "${_TBB_INSTALL_DIR}/${_TBB_ARCHITECTURE}/${_TBB_COMPILER}/lib" ${_TBB_LIBRARY_DIR}) -endif ((NOT ${TBB_ARCHITECTURE} STREQUAL "") AND (NOT ${TBB_COMPILER} STREQUAL "")) - -# GvdB: Mac OS X distribution places libraries directly in lib directory. -list(APPEND _TBB_LIBRARY_DIR ${_TBB_INSTALL_DIR}/lib) - -# Jiri: No reason not to check the default paths. From recent versions, -# tbbvars has started exporting the LIBRARY_PATH and LD_LIBRARY_PATH -# variables, which now point to the directories of the lib files. -# It all makes more sense to use the ${_TBB_LIBRARY_DIR} as a HINTS -# argument instead of the implicit PATHS as it isn't hard-coded -# but computed by system introspection. Searching the LIBRARY_PATH -# and LD_LIBRARY_PATH environment variables is now even more important -# that tbbvars doesn't export TBB_ARCH_PLATFORM and it facilitates -# the use of TBB built from sources. -find_library(TBB_LIBRARY ${_TBB_LIB_NAME} HINTS ${_TBB_LIBRARY_DIR} - PATHS ENV LIBRARY_PATH ENV LD_LIBRARY_PATH) -find_library(TBB_MALLOC_LIBRARY ${_TBB_LIB_MALLOC_NAME} HINTS ${_TBB_LIBRARY_DIR} - PATHS ENV LIBRARY_PATH ENV LD_LIBRARY_PATH) - -#Extract path from TBB_LIBRARY name -get_filename_component(TBB_LIBRARY_DIR ${TBB_LIBRARY} PATH) - -#TBB_CORRECT_LIB_DIR(TBB_LIBRARY) -#TBB_CORRECT_LIB_DIR(TBB_MALLOC_LIBRARY) -mark_as_advanced(TBB_LIBRARY TBB_MALLOC_LIBRARY) - -#-- Look for debug libraries -# Jiri: Changed the same way as for the release libraries. -find_library(TBB_LIBRARY_DEBUG ${_TBB_LIB_DEBUG_NAME} HINTS ${_TBB_LIBRARY_DIR} - PATHS ENV LIBRARY_PATH ENV LD_LIBRARY_PATH) -find_library(TBB_MALLOC_LIBRARY_DEBUG ${_TBB_LIB_MALLOC_DEBUG_NAME} HINTS ${_TBB_LIBRARY_DIR} - PATHS ENV LIBRARY_PATH ENV LD_LIBRARY_PATH) - -# Jiri: Self-built TBB stores the debug libraries in a separate directory. -# Extract path from TBB_LIBRARY_DEBUG name -get_filename_component(TBB_LIBRARY_DEBUG_DIR ${TBB_LIBRARY_DEBUG} PATH) - -#TBB_CORRECT_LIB_DIR(TBB_LIBRARY_DEBUG) -#TBB_CORRECT_LIB_DIR(TBB_MALLOC_LIBRARY_DEBUG) -mark_as_advanced(TBB_LIBRARY_DEBUG TBB_MALLOC_LIBRARY_DEBUG) - - -if (TBB_INCLUDE_DIR) - if (TBB_LIBRARY) - set (TBB_FOUND "YES") - set (TBB_LIBRARIES ${TBB_LIBRARY} ${TBB_MALLOC_LIBRARY} ${TBB_LIBRARIES}) - set (TBB_DEBUG_LIBRARIES ${TBB_LIBRARY_DEBUG} ${TBB_MALLOC_LIBRARY_DEBUG} ${TBB_DEBUG_LIBRARIES}) - set (TBB_INCLUDE_DIRS ${TBB_INCLUDE_DIR} CACHE PATH "TBB include directory" FORCE) - set (TBB_LIBRARY_DIRS ${TBB_LIBRARY_DIR} CACHE PATH "TBB library directory" FORCE) - # Jiri: Self-built TBB stores the debug libraries in a separate directory. - set (TBB_DEBUG_LIBRARY_DIRS ${TBB_LIBRARY_DEBUG_DIR} CACHE PATH "TBB debug library directory" FORCE) - mark_as_advanced(TBB_INCLUDE_DIRS TBB_LIBRARY_DIRS TBB_DEBUG_LIBRARY_DIRS TBB_LIBRARIES TBB_DEBUG_LIBRARIES) - message(STATUS "Found Intel TBB") - endif (TBB_LIBRARY) -endif (TBB_INCLUDE_DIR) - -if (NOT TBB_FOUND) - message("ERROR: Intel TBB NOT found!") - message(STATUS "Looked for Threading Building Blocks in ${_TBB_INSTALL_DIR}") - # do only throw fatal, if this pkg is REQUIRED - if (TBB_FIND_REQUIRED) - message(FATAL_ERROR "Could NOT find TBB library.") - endif (TBB_FIND_REQUIRED) -endif (NOT TBB_FOUND) - -endif (NOT _TBB_INSTALL_DIR) - -if (TBB_FOUND) - set(TBB_INTERFACE_VERSION 0) - FILE(READ "${TBB_INCLUDE_DIRS}/tbb/tbb_stddef.h" _TBB_VERSION_CONTENTS) - STRING(REGEX REPLACE ".*#define TBB_INTERFACE_VERSION ([0-9]+).*" "\\1" TBB_INTERFACE_VERSION "${_TBB_VERSION_CONTENTS}") - set(TBB_INTERFACE_VERSION "${TBB_INTERFACE_VERSION}") -endif (TBB_FOUND) +set(TBB_LIBRARIES ${TBB_LIBRARY} ${TBB_MALLOC_LIBRARY}) From e8ea45efdef2820f32c775a3b7caf3848a76639a Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 15 Dec 2014 13:59:51 -0800 Subject: [PATCH 45/62] clarify TBB find for windows --- BUILD_WIN.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/BUILD_WIN.md b/BUILD_WIN.md index b90396b757..ad143ef56a 100644 --- a/BUILD_WIN.md +++ b/BUILD_WIN.md @@ -95,6 +95,12 @@ To prevent these problems, install OpenSSL yourself. Download the following bina Install OpenSSL into the Windows system directory, to make sure that QT uses the version that you've just installed, and not some other version. +###Intel Threading Building Blocks (TBB) + +Download the zip from the [TBB website](https://www.threadingbuildingblocks.org/). + +We recommend you extract it to %HIFI_LIB_DIR%\tbb. This will help our FindTBB cmake module find what it needs. You can place it wherever you like on your machine if you specify TBB_ROOT_DIR as an environment variable or a variable passed when cmake is run. + ###Zlib Download the compiled DLL from the [zlib website](http://www.zlib.net/). Extract to %HIFI_LIB_DIR%\zlib. From f63aa44d019ab38866192625a92fb4a2c952970c Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 15 Dec 2014 14:02:55 -0800 Subject: [PATCH 46/62] add lib to lib dirs for win and linux --- cmake/modules/FindTBB.cmake | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cmake/modules/FindTBB.cmake b/cmake/modules/FindTBB.cmake index c6c1890a09..bce667b7d4 100644 --- a/cmake/modules/FindTBB.cmake +++ b/cmake/modules/FindTBB.cmake @@ -41,9 +41,9 @@ elseif (UNIX) ) if (GCC_VERSION VERSION_GREATER 4.4 OR GCC_VERSION VERSION_EQUAL 4.4) - set(_TBB_LIB_DIR "${_TBB_ARCH_DIR}/gcc4.4") + set(_TBB_LIB_DIR "lib/${_TBB_ARCH_DIR}/gcc4.4") elseif (GCC_VERSION VERSION_GREATER 4.1 OR GCC_VERSION VERSION_EQUAL 4.1) - set(_TBB_LIB_DIR "${_TBB_ARCH_DIR}/gcc4.1") + set(_TBB_LIB_DIR "lib/${_TBB_ARCH_DIR}/gcc4.1") else () message(FATAL_ERROR "Could not find a compatible version of Threading Building Blocks library for your compiler.") endif () @@ -55,7 +55,7 @@ elseif (WIN32) set(_TBB_ARCH_DIR "ia32") endif() - set(_TBB_LIB_DIR "${_TBB_ARCH_DIR}/vc12") + set(_TBB_LIB_DIR "lib/${_TBB_ARCH_DIR}/vc12") endif () find_library(TBB_LIBRARY_DEBUG NAMES ${_TBB_LIB_NAME}_debug PATH_SUFFIXES ${_TBB_LIB_DIR} HINTS ${TBB_SEARCH_DIRS}) From a3cc578fd15cd752689aab985c8141c137e20220 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 15 Dec 2014 14:08:23 -0800 Subject: [PATCH 47/62] use libc++ for C++11 in APPLE builds --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index f6e3f5c42c..7a6118bb87 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -49,6 +49,7 @@ endif() if (APPLE) set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LANGUAGE_STANDARD "c++0x") set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "libc++") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --stdlib=libc++") endif () if (NOT QT_CMAKE_PREFIX_PATH) From 2ee33cef9f1bbe53b2a8ed1f4bc8aa7f7c224463 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 17 Dec 2014 10:21:27 -0800 Subject: [PATCH 48/62] have targets bubble up their Qt modules --- cmake/macros/LinkHifiLibraries.cmake | 4 ++++ cmake/macros/LinkSharedDependencies.cmake | 15 +++++++++++++++ cmake/macros/SetupHifiLibrary.cmake | 13 ++----------- cmake/macros/SetupHifiProject.cmake | 15 ++------------- 4 files changed, 23 insertions(+), 24 deletions(-) diff --git a/cmake/macros/LinkHifiLibraries.cmake b/cmake/macros/LinkHifiLibraries.cmake index a46023fe9a..464af76553 100644 --- a/cmake/macros/LinkHifiLibraries.cmake +++ b/cmake/macros/LinkHifiLibraries.cmake @@ -33,6 +33,10 @@ macro(LINK_HIFI_LIBRARIES) get_target_property(LINKED_TARGET_DEPENDENCY_INCLUDES ${HIFI_LIBRARY} DEPENDENCY_INCLUDES) list(APPEND ${TARGET_NAME}_DEPENDENCY_INCLUDES ${LINKED_TARGET_DEPENDENCY_INCLUDES}) + # ask the library what its qt module dependencies are and link them + get_target_property(LINKED_TARGET_DEPENDENCY_QT_MODULES ${HIFI_LIBRARY} DEPENDENCY_QT_MODULES) + list(APPEND ${TARGET_NAME}_DEPENDENCY_QT_MODULES ${LINKED_TARGET_DEPENDENCY_QT_MODULES}) + endforeach() endmacro(LINK_HIFI_LIBRARIES) \ No newline at end of file diff --git a/cmake/macros/LinkSharedDependencies.cmake b/cmake/macros/LinkSharedDependencies.cmake index afd25db0d7..890736d806 100644 --- a/cmake/macros/LinkSharedDependencies.cmake +++ b/cmake/macros/LinkSharedDependencies.cmake @@ -24,10 +24,25 @@ macro(LINK_SHARED_DEPENDENCIES) include_directories(SYSTEM ${${TARGET_NAME}_DEPENDENCY_INCLUDES}) endif () + if (${TARGET_NAME}_DEPENDENCY_QT_MODULES) + list(REMOVE_DUPLICATES ${TARGET_NAME}_DEPENDENCY_QT_MODULES) + + message(${TARGET_NAME}) + message(${${TARGET_NAME}_DEPENDENCY_QT_MODULES}) + + # find these Qt modules and link them to our own target + find_package(Qt5 COMPONENTS ${${TARGET_NAME}_DEPENDENCY_QT_MODULES} REQUIRED) + + foreach(QT_MODULE ${QT_MODULES_TO_LINK}) + target_link_libraries(${TARGET_NAME} Qt5::${QT_MODULE}) + endforeach() + endif () + # we've already linked our Qt modules, but we need to bubble them up to parents list(APPEND ${TARGET_NAME}_LIBRARIES_TO_LINK "${${TARGET_NAME}_QT_MODULES_TO_LINK}") # set the property on this target so it can be retreived by targets linking to us set_target_properties(${TARGET_NAME} PROPERTIES DEPENDENCY_LIBRARIES "${${TARGET_NAME}_LIBRARIES_TO_LINK}") set_target_properties(${TARGET_NAME} PROPERTIES DEPENDENCY_INCLUDES "${${TARGET_NAME}_DEPENDENCY_INCLUDES}") + set_target_properties(${TARGET_NAME} PROPERTIES DEPENDENCY_QT_MODULES "${${TARGET_NAME}_DEPENDENCY_QT_MODULES}") endmacro(LINK_SHARED_DEPENDENCIES) \ No newline at end of file diff --git a/cmake/macros/SetupHifiLibrary.cmake b/cmake/macros/SetupHifiLibrary.cmake index 950286ce45..de9f9b9d1e 100644 --- a/cmake/macros/SetupHifiLibrary.cmake +++ b/cmake/macros/SetupHifiLibrary.cmake @@ -18,16 +18,7 @@ macro(SETUP_HIFI_LIBRARY) # create a library and set the property so it can be referenced later add_library(${TARGET_NAME} ${LIB_SRCS} ${AUTOMTC_SRC}) - set(QT_MODULES_TO_LINK ${ARGN}) - list(APPEND QT_MODULES_TO_LINK Core) + set(${TARGET_NAME}_DEPENDENCY_QT_MODULES ${ARGN}) + list(APPEND ${TARGET_NAME}_DEPENDENCY_QT_MODULES Core) - find_package(Qt5 COMPONENTS ${QT_MODULES_TO_LINK} REQUIRED) - - foreach(QT_MODULE ${QT_MODULES_TO_LINK}) - get_target_property(QT_LIBRARY_LOCATION Qt5::${QT_MODULE} LOCATION) - - # add the actual path to the Qt module to our LIBRARIES_TO_LINK variable - target_link_libraries(${TARGET_NAME} Qt5::${QT_MODULE}) - list(APPEND ${TARGET_NAME}_QT_MODULES_TO_LINK ${QT_LIBRARY_LOCATION}) - endforeach() endmacro(SETUP_HIFI_LIBRARY) \ No newline at end of file diff --git a/cmake/macros/SetupHifiProject.cmake b/cmake/macros/SetupHifiProject.cmake index d21e2c11bb..157c22ea79 100644 --- a/cmake/macros/SetupHifiProject.cmake +++ b/cmake/macros/SetupHifiProject.cmake @@ -25,17 +25,6 @@ macro(SETUP_HIFI_PROJECT) # add the executable, include additional optional sources add_executable(${TARGET_NAME} ${TARGET_SRCS} "${AUTOMTC_SRC}") - set(QT_MODULES_TO_LINK ${ARGN}) - list(APPEND QT_MODULES_TO_LINK Core) - - find_package(Qt5 COMPONENTS ${QT_MODULES_TO_LINK} REQUIRED) - - foreach(QT_MODULE ${QT_MODULES_TO_LINK}) - target_link_libraries(${TARGET_NAME} Qt5::${QT_MODULE}) - - # add the actual path to the Qt module to our LIBRARIES_TO_LINK variable - get_target_property(QT_LIBRARY_LOCATION Qt5::${QT_MODULE} LOCATION) - list(APPEND ${TARGET_NAME}_QT_MODULES_TO_LINK ${QT_LIBRARY_LOCATION}) - endforeach() - + set(${TARGET_NAME}_DEPENDENCY_QT_MODULES ${ARGN}) + list(APPEND ${TARGET_NAME}_DEPENDENCY_QT_MODULES Core) endmacro() \ No newline at end of file From 421680696756cf75bed30742d9514cdd3e13443c Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 17 Dec 2014 10:21:53 -0800 Subject: [PATCH 49/62] remove extra debugging in LinkSharedDependencies --- cmake/macros/LinkSharedDependencies.cmake | 3 --- 1 file changed, 3 deletions(-) diff --git a/cmake/macros/LinkSharedDependencies.cmake b/cmake/macros/LinkSharedDependencies.cmake index 890736d806..c5049cf842 100644 --- a/cmake/macros/LinkSharedDependencies.cmake +++ b/cmake/macros/LinkSharedDependencies.cmake @@ -27,9 +27,6 @@ macro(LINK_SHARED_DEPENDENCIES) if (${TARGET_NAME}_DEPENDENCY_QT_MODULES) list(REMOVE_DUPLICATES ${TARGET_NAME}_DEPENDENCY_QT_MODULES) - message(${TARGET_NAME}) - message(${${TARGET_NAME}_DEPENDENCY_QT_MODULES}) - # find these Qt modules and link them to our own target find_package(Qt5 COMPONENTS ${${TARGET_NAME}_DEPENDENCY_QT_MODULES} REQUIRED) From 33d50c6eb62beab46a52da27f1b3e4b2a8f15766 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 17 Dec 2014 10:26:51 -0800 Subject: [PATCH 50/62] fix dependency qt module linking in LinkSharedDependencies --- cmake/macros/LinkSharedDependencies.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/macros/LinkSharedDependencies.cmake b/cmake/macros/LinkSharedDependencies.cmake index c5049cf842..fd5461c288 100644 --- a/cmake/macros/LinkSharedDependencies.cmake +++ b/cmake/macros/LinkSharedDependencies.cmake @@ -30,7 +30,7 @@ macro(LINK_SHARED_DEPENDENCIES) # find these Qt modules and link them to our own target find_package(Qt5 COMPONENTS ${${TARGET_NAME}_DEPENDENCY_QT_MODULES} REQUIRED) - foreach(QT_MODULE ${QT_MODULES_TO_LINK}) + foreach(QT_MODULE ${${TARGET_NAME}_DEPENDENCY_QT_MODULES}) target_link_libraries(${TARGET_NAME} Qt5::${QT_MODULE}) endforeach() endif () From adf51bfeb82df214c6b5e76899cbee63ec104e3a Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 17 Dec 2014 16:41:28 -0800 Subject: [PATCH 51/62] temp disable visage to get to C++11 support --- cmake/modules/FindVisage.cmake | 13 +++++++------ interface/CMakeLists.txt | 3 +-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/cmake/modules/FindVisage.cmake b/cmake/modules/FindVisage.cmake index 96176a2648..2b288f4681 100644 --- a/cmake/modules/FindVisage.cmake +++ b/cmake/modules/FindVisage.cmake @@ -32,9 +32,10 @@ if (APPLE) find_library(VISAGE_VISION_LIBRARY NAME vsvision PATH_SUFFIXES lib HINTS ${VISAGE_SEARCH_DIRS}) find_library(VISAGE_OPENCV_LIBRARY NAME OpenCV PATH_SUFFIXES dependencies/OpenCV_MacOSX/lib HINTS ${VISAGE_SEARCH_DIRS}) - find_library(AppKit AppKit) - find_library(QuartzCore QuartzCore) + find_library(CoreVideo CoreVideo) find_library(QTKit QTKit) + find_library(IOKit IOKit) + elseif (WIN32) find_path(VISAGE_XML_INCLUDE_DIR libxml/xmlreader.h PATH_SUFFIXES dependencies/libxml2/include HINTS ${VISAGE_SEARCH_DIRS}) find_path(VISAGE_OPENCV_INCLUDE_DIR opencv/cv.h PATH_SUFFIXES dependencies/OpenCV/include HINTS ${VISAGE_SEARCH_DIRS}) @@ -49,19 +50,19 @@ include(FindPackageHandleStandardArgs) list(APPEND VISAGE_ARGS_LIST VISAGE_BASE_INCLUDE_DIR VISAGE_XML_INCLUDE_DIR VISAGE_OPENCV_INCLUDE_DIR VISAGE_OPENCV2_INCLUDE_DIR - VISAGE_CORE_LIBRARY VISAGE_VISION_LIBRARY VISAGE_OPENCV_LIBRARY) + VISAGE_CORE_LIBRARY VISAGE_VISION_LIBRARY) if (APPLE) - list(APPEND VISAGE_ARGS_LIST QuartzCore AppKit QTKit) + list(APPEND VISAGE_ARGS_LIST CoreVideo QTKit IOKit) endif () find_package_handle_standard_args(Visage DEFAULT_MSG ${VISAGE_ARGS_LIST}) set(VISAGE_INCLUDE_DIRS "${VISAGE_XML_INCLUDE_DIR}" "${VISAGE_OPENCV_INCLUDE_DIR}" "${VISAGE_OPENCV2_INCLUDE_DIR}" "${VISAGE_BASE_INCLUDE_DIR}") -set(VISAGE_LIBRARIES "${VISAGE_CORE_LIBRARY}" "${VISAGE_VISION_LIBRARY}" "${VISAGE_OPENCV_LIBRARY}") +set(VISAGE_LIBRARIES "${VISAGE_CORE_LIBRARY}" "${VISAGE_VISION_LIBRARY}") if (APPLE) - list(APPEND VISAGE_LIBRARIES ${QuartzCore} ${AppKit} ${QTKit}) + list(APPEND VISAGE_LIBRARIES "${CoreVideo}" "${QTKit}" "${IOKit}") endif () mark_as_advanced(VISAGE_INCLUDE_DIRS VISAGE_LIBRARIES) diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt index ffc401ba63..78f4cbd6a6 100644 --- a/interface/CMakeLists.txt +++ b/interface/CMakeLists.txt @@ -2,7 +2,7 @@ set(TARGET_NAME interface) project(${TARGET_NAME}) # set a default root dir for each of our optional externals if it was not passed -set(OPTIONAL_EXTERNALS "Faceshift" "LibOVR" "PrioVR" "Sixense" "Visage" "LeapMotion" "RtMidi" "Qxmpp" "SDL2" "Gverb") +set(OPTIONAL_EXTERNALS "Faceshift" "LibOVR" "PrioVR" "Sixense" "LeapMotion" "RtMidi" "Qxmpp" "SDL2" "Gverb") foreach(EXTERNAL ${OPTIONAL_EXTERNALS}) string(TOUPPER ${EXTERNAL} ${EXTERNAL}_UPPERCASE) if (NOT ${${EXTERNAL}_UPPERCASE}_ROOT_DIR) @@ -156,7 +156,6 @@ if (VISAGE_FOUND AND NOT DISABLE_VISAGE AND APPLE) SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-comment") find_library(AVFoundation AVFoundation) find_library(CoreMedia CoreMedia) - find_library(NEW_STD_LIBRARY libc++.dylib /usr/lib/) target_link_libraries(${TARGET_NAME} ${AVFoundation} ${CoreMedia} ${NEW_STD_LIBRARY}) endif () From b202eb7dae01b9a878f3e7c87d349ac9b5db63b6 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 18 Dec 2014 09:14:44 -0800 Subject: [PATCH 52/62] DRY up gpu library/header linking --- libraries/entities-renderer/CMakeLists.txt | 28 +------------- libraries/gpu/CMakeLists.txt | 44 +++++++++++----------- libraries/render-utils/CMakeLists.txt | 26 ------------- 3 files changed, 24 insertions(+), 74 deletions(-) diff --git a/libraries/entities-renderer/CMakeLists.txt b/libraries/entities-renderer/CMakeLists.txt index 5744ea0b7b..1e77afe544 100644 --- a/libraries/entities-renderer/CMakeLists.txt +++ b/libraries/entities-renderer/CMakeLists.txt @@ -5,33 +5,7 @@ setup_hifi_library(Widgets OpenGL Network Script) include_glm() -link_hifi_libraries(shared gpu) -if (APPLE) - # link in required OS X frameworks and include the right GL headers - find_library(OpenGL OpenGL) - - #target_link_libraries(${TARGET_NAME} ${OpenGL}) - -else (APPLE) - find_package(OpenGL REQUIRED) - - if (${OPENGL_INCLUDE_DIR}) - include_directories(SYSTEM "${OPENGL_INCLUDE_DIR}") - endif () - - # link target to external libraries - if (WIN32) - find_package(GLEW REQUIRED) - include_directories(${GLEW_INCLUDE_DIRS}) - - find_package(GLUT REQUIRED) - include_directories(SYSTEM "${GLUT_INCLUDE_DIRS}") - - # we're using static GLEW, so define GLEW_STATIC - add_definitions(-DGLEW_STATIC) - target_link_libraries(${TARGET_NAME} "${GLEW_LIBRARIES}") - endif() -endif (APPLE) +link_hifi_libraries(shared gpu script-engine) # call macro to link our dependencies and bubble them up via a property on our target link_shared_dependencies() diff --git a/libraries/gpu/CMakeLists.txt b/libraries/gpu/CMakeLists.txt index 577f9f7a58..340adcc9e6 100644 --- a/libraries/gpu/CMakeLists.txt +++ b/libraries/gpu/CMakeLists.txt @@ -6,13 +6,32 @@ setup_hifi_library() include_glm() link_hifi_libraries(shared) + if (APPLE) # link in required OS X frameworks and include the right GL headers find_library(OpenGL OpenGL) target_link_libraries(${TARGET_NAME} ${OpenGL}) - -else (APPLE) +elseif (WIN32) + find_package(GLEW REQUIRED) + include_directories(${GLEW_INCLUDE_DIRS}) + + # we're using static GLEW, so define GLEW_STATIC + add_definitions(-DGLEW_STATIC) + + target_link_libraries(${TARGET_NAME} "${GLEW_LIBRARIES}" opengl32.lib) + + # need to bubble up the GLEW_INCLUDE_DIRS + list(APPEND ${TARGET_NAME}_DEPENDENCY_INCLUDES "${GLEW_INCLUDE_DIRS}") + + # try to find the Nsight package and add it to the build if we find it + find_package(NSIGHT) + if (NSIGHT_FOUND) + include_directories(${NSIGHT_INCLUDE_DIRS}) + add_definitions(-DNSIGHT_FOUND) + target_link_libraries(${TARGET_NAME} "${NSIGHT_LIBRARIES}") + endif () +else () find_package(OpenGL REQUIRED) if (${OPENGL_INCLUDE_DIR}) @@ -21,25 +40,8 @@ else (APPLE) target_link_libraries(${TARGET_NAME} "${OPENGL_LIBRARY}") - # link target to external libraries - if (WIN32) - find_package(GLEW REQUIRED) - include_directories(${GLEW_INCLUDE_DIRS}) - - # we're using static GLEW, so define GLEW_STATIC - add_definitions(-DGLEW_STATIC) - - target_link_libraries(${TARGET_NAME} "${GLEW_LIBRARIES}" "${NSIGHT_LIBRARIES}" opengl32.lib) - - # try to find the Nsight package and add it to the build if we find it - find_package(NSIGHT) - if (NSIGHT_FOUND) - include_directories(${NSIGHT_INCLUDE_DIRS}) - add_definitions(-DNSIGHT_FOUND) - target_link_libraries(${TARGET_NAME} "${NSIGHT_LIBRARIES}") - endif () - - endif() + # need to bubble up the OPENGL_INCLUDE_DIR + list(APPEND ${TARGET_NAME}_DEPENDENCY_INCLUDES "${OPENGL_INCLUDE_DIR}") endif (APPLE) # call macro to link our dependencies and bubble them up via a property on our target diff --git a/libraries/render-utils/CMakeLists.txt b/libraries/render-utils/CMakeLists.txt index 0244fa91a6..8d4f85a2ac 100644 --- a/libraries/render-utils/CMakeLists.txt +++ b/libraries/render-utils/CMakeLists.txt @@ -6,32 +6,6 @@ setup_hifi_library(Widgets OpenGL Network Script) include_glm() link_hifi_libraries(shared gpu) -if (APPLE) - # link in required OS X frameworks and include the right GL headers - find_library(OpenGL OpenGL) - - #target_link_libraries(${TARGET_NAME} ${OpenGL}) - -else (APPLE) - find_package(OpenGL REQUIRED) - - if (${OPENGL_INCLUDE_DIR}) - include_directories(SYSTEM "${OPENGL_INCLUDE_DIR}") - endif () - - # link target to external libraries - if (WIN32) - find_package(GLEW REQUIRED) - include_directories(${GLEW_INCLUDE_DIRS}) - - find_package(GLUT REQUIRED) - include_directories(SYSTEM "${GLUT_INCLUDE_DIRS}") - - # we're using static GLEW, so define GLEW_STATIC - add_definitions(-DGLEW_STATIC) - target_link_libraries(${TARGET_NAME} "${GLEW_LIBRARIES}") - endif() -endif (APPLE) # call macro to link our dependencies and bubble them up via a property on our target link_shared_dependencies() From d38c78f2c31f42e22c0ab84feac15e4bbbe1a4c5 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 18 Dec 2014 09:34:04 -0800 Subject: [PATCH 53/62] remove bubbling of linked libraries, cmake does it --- assignment-client/CMakeLists.txt | 2 +- cmake/macros/LinkHifiLibraries.cmake | 9 -------- cmake/macros/LinkSharedDependencies.cmake | 25 +---------------------- cmake/macros/SetupHifiLibrary.cmake | 7 +++++++ cmake/macros/SetupHifiProject.cmake | 7 +++++++ domain-server/CMakeLists.txt | 2 +- libraries/fbx/CMakeLists.txt | 2 +- libraries/networking/CMakeLists.txt | 2 +- libraries/octree/CMakeLists.txt | 2 +- libraries/voxels/CMakeLists.txt | 2 +- 10 files changed, 21 insertions(+), 39 deletions(-) diff --git a/assignment-client/CMakeLists.txt b/assignment-client/CMakeLists.txt index 69ad1cd815..6e31182f0d 100644 --- a/assignment-client/CMakeLists.txt +++ b/assignment-client/CMakeLists.txt @@ -12,7 +12,7 @@ link_hifi_libraries( ) if (UNIX) - list(APPEND ${TARGET_NAME}_LIBRARIES_TO_LINK ${CMAKE_DL_LIBS}) + target_link_libraries(${TARGET_NAME} ${CMAKE_DL_LIBS}) endif (UNIX) link_shared_dependencies() diff --git a/cmake/macros/LinkHifiLibraries.cmake b/cmake/macros/LinkHifiLibraries.cmake index 464af76553..646b680f27 100644 --- a/cmake/macros/LinkHifiLibraries.cmake +++ b/cmake/macros/LinkHifiLibraries.cmake @@ -25,18 +25,9 @@ macro(LINK_HIFI_LIBRARIES) # link the actual library - it is static so don't bubble it up target_link_libraries(${TARGET_NAME} ${HIFI_LIBRARY}) - # ask the library what its dynamic dependencies are and link them - get_target_property(LINKED_TARGET_DEPENDENCY_LIBRARIES ${HIFI_LIBRARY} DEPENDENCY_LIBRARIES) - list(APPEND ${TARGET_NAME}_LIBRARIES_TO_LINK ${LINKED_TARGET_DEPENDENCY_LIBRARIES}) - # ask the library what its include dependencies are and link them get_target_property(LINKED_TARGET_DEPENDENCY_INCLUDES ${HIFI_LIBRARY} DEPENDENCY_INCLUDES) list(APPEND ${TARGET_NAME}_DEPENDENCY_INCLUDES ${LINKED_TARGET_DEPENDENCY_INCLUDES}) - - # ask the library what its qt module dependencies are and link them - get_target_property(LINKED_TARGET_DEPENDENCY_QT_MODULES ${HIFI_LIBRARY} DEPENDENCY_QT_MODULES) - list(APPEND ${TARGET_NAME}_DEPENDENCY_QT_MODULES ${LINKED_TARGET_DEPENDENCY_QT_MODULES}) - endforeach() endmacro(LINK_HIFI_LIBRARIES) \ No newline at end of file diff --git a/cmake/macros/LinkSharedDependencies.cmake b/cmake/macros/LinkSharedDependencies.cmake index fd5461c288..9168c5a921 100644 --- a/cmake/macros/LinkSharedDependencies.cmake +++ b/cmake/macros/LinkSharedDependencies.cmake @@ -9,14 +9,7 @@ # See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html # -macro(LINK_SHARED_DEPENDENCIES) - if (${TARGET_NAME}_LIBRARIES_TO_LINK) - list(REMOVE_DUPLICATES ${TARGET_NAME}_LIBRARIES_TO_LINK) - - # link these libraries to our target - target_link_libraries(${TARGET_NAME} ${${TARGET_NAME}_LIBRARIES_TO_LINK}) - endif () - +macro(LINK_SHARED_DEPENDENCIES) if (${TARGET_NAME}_DEPENDENCY_INCLUDES) list(REMOVE_DUPLICATES ${TARGET_NAME}_DEPENDENCY_INCLUDES) @@ -24,22 +17,6 @@ macro(LINK_SHARED_DEPENDENCIES) include_directories(SYSTEM ${${TARGET_NAME}_DEPENDENCY_INCLUDES}) endif () - if (${TARGET_NAME}_DEPENDENCY_QT_MODULES) - list(REMOVE_DUPLICATES ${TARGET_NAME}_DEPENDENCY_QT_MODULES) - - # find these Qt modules and link them to our own target - find_package(Qt5 COMPONENTS ${${TARGET_NAME}_DEPENDENCY_QT_MODULES} REQUIRED) - - foreach(QT_MODULE ${${TARGET_NAME}_DEPENDENCY_QT_MODULES}) - target_link_libraries(${TARGET_NAME} Qt5::${QT_MODULE}) - endforeach() - endif () - - # we've already linked our Qt modules, but we need to bubble them up to parents - list(APPEND ${TARGET_NAME}_LIBRARIES_TO_LINK "${${TARGET_NAME}_QT_MODULES_TO_LINK}") - # set the property on this target so it can be retreived by targets linking to us - set_target_properties(${TARGET_NAME} PROPERTIES DEPENDENCY_LIBRARIES "${${TARGET_NAME}_LIBRARIES_TO_LINK}") set_target_properties(${TARGET_NAME} PROPERTIES DEPENDENCY_INCLUDES "${${TARGET_NAME}_DEPENDENCY_INCLUDES}") - set_target_properties(${TARGET_NAME} PROPERTIES DEPENDENCY_QT_MODULES "${${TARGET_NAME}_DEPENDENCY_QT_MODULES}") endmacro(LINK_SHARED_DEPENDENCIES) \ No newline at end of file diff --git a/cmake/macros/SetupHifiLibrary.cmake b/cmake/macros/SetupHifiLibrary.cmake index de9f9b9d1e..362a833862 100644 --- a/cmake/macros/SetupHifiLibrary.cmake +++ b/cmake/macros/SetupHifiLibrary.cmake @@ -21,4 +21,11 @@ macro(SETUP_HIFI_LIBRARY) set(${TARGET_NAME}_DEPENDENCY_QT_MODULES ${ARGN}) list(APPEND ${TARGET_NAME}_DEPENDENCY_QT_MODULES Core) + # find these Qt modules and link them to our own target + find_package(Qt5 COMPONENTS ${${TARGET_NAME}_DEPENDENCY_QT_MODULES} REQUIRED) + + foreach(QT_MODULE ${${TARGET_NAME}_DEPENDENCY_QT_MODULES}) + target_link_libraries(${TARGET_NAME} Qt5::${QT_MODULE}) + endforeach() + endmacro(SETUP_HIFI_LIBRARY) \ No newline at end of file diff --git a/cmake/macros/SetupHifiProject.cmake b/cmake/macros/SetupHifiProject.cmake index 157c22ea79..3f9787faa1 100644 --- a/cmake/macros/SetupHifiProject.cmake +++ b/cmake/macros/SetupHifiProject.cmake @@ -27,4 +27,11 @@ macro(SETUP_HIFI_PROJECT) set(${TARGET_NAME}_DEPENDENCY_QT_MODULES ${ARGN}) list(APPEND ${TARGET_NAME}_DEPENDENCY_QT_MODULES Core) + + # find these Qt modules and link them to our own target + find_package(Qt5 COMPONENTS ${${TARGET_NAME}_DEPENDENCY_QT_MODULES} REQUIRED) + + foreach(QT_MODULE ${${TARGET_NAME}_DEPENDENCY_QT_MODULES}) + target_link_libraries(${TARGET_NAME} Qt5::${QT_MODULE}) + endforeach() endmacro() \ No newline at end of file diff --git a/domain-server/CMakeLists.txt b/domain-server/CMakeLists.txt index b804ff27d3..b9f730baaf 100644 --- a/domain-server/CMakeLists.txt +++ b/domain-server/CMakeLists.txt @@ -50,6 +50,6 @@ endif () include_directories(SYSTEM "${OPENSSL_INCLUDE_DIR}") # append OpenSSL to our list of libraries to link -list(APPEND ${TARGET_NAME}_LIBRARIES_TO_LINK "${OPENSSL_LIBRARIES}") +target_link_libraries(${TARGET_NAME} "${OPENSSL_LIBRARIES}") link_shared_dependencies() \ No newline at end of file diff --git a/libraries/fbx/CMakeLists.txt b/libraries/fbx/CMakeLists.txt index 894fa14c33..2e58645b56 100644 --- a/libraries/fbx/CMakeLists.txt +++ b/libraries/fbx/CMakeLists.txt @@ -9,7 +9,7 @@ link_hifi_libraries(shared networking octree voxels) find_package(ZLIB REQUIRED) include_directories(SYSTEM "${ZLIB_INCLUDE_DIRS}") -list(APPEND ${TARGET_NAME}_LIBRARIES_TO_LINK "${ZLIB_LIBRARIES}") +target_link_libraries(${TARGET_NAME} "${ZLIB_LIBRARIES}") # call macro to link our dependencies and bubble them up via a property on our target link_shared_dependencies() diff --git a/libraries/networking/CMakeLists.txt b/libraries/networking/CMakeLists.txt index 7c8b628183..90e06bc13e 100644 --- a/libraries/networking/CMakeLists.txt +++ b/libraries/networking/CMakeLists.txt @@ -23,7 +23,7 @@ endif () include_directories(SYSTEM "${OPENSSL_INCLUDE_DIR}") # append OpenSSL to our list of libraries to link -list(APPEND ${TARGET_NAME}_LIBRARIES_TO_LINK "${OPENSSL_LIBRARIES}" "${TBB_LIBRARIES}") +target_link_libraries(${TARGET_NAME} "${OPENSSL_LIBRARIES}" "${TBB_LIBRARIES}") # append libcuckoo includes to our list of includes to bubble list(APPEND ${TARGET_NAME}_DEPENDENCY_INCLUDES "${TBB_INCLUDE_DIRS}") diff --git a/libraries/octree/CMakeLists.txt b/libraries/octree/CMakeLists.txt index 9aea2fdea1..f1a30f3724 100644 --- a/libraries/octree/CMakeLists.txt +++ b/libraries/octree/CMakeLists.txt @@ -13,7 +13,7 @@ find_package(ZLIB REQUIRED) include_directories(SYSTEM "${ZLIB_INCLUDE_DIRS}") # append ZLIB and OpenSSL to our list of libraries to link -list(APPEND ${TARGET_NAME}_LIBRARIES_TO_LINK "${ZLIB_LIBRARIES}") +target_link_libraries(${TARGET_NAME} "${ZLIB_LIBRARIES}") # call macro to link our dependencies and bubble them up via a property on our target link_shared_dependencies() diff --git a/libraries/voxels/CMakeLists.txt b/libraries/voxels/CMakeLists.txt index 3214978a2a..874a74ee95 100644 --- a/libraries/voxels/CMakeLists.txt +++ b/libraries/voxels/CMakeLists.txt @@ -12,7 +12,7 @@ find_package(ZLIB REQUIRED) include_directories(SYSTEM "${ZLIB_INCLUDE_DIRS}") # add it to our list of libraries to link -list(APPEND ${TARGET}_LIBRARIES_TO_LINK "${ZLIB_LIBRARIES}") +target_link_libraries(${TARGET_NAME} "${ZLIB_LIBRARIES}") # call macro to link our dependencies and bubble them up via a property on our target link_shared_dependencies() \ No newline at end of file From b326ab9839e4411927594799303cffb0ecf34393 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 18 Dec 2014 09:38:48 -0800 Subject: [PATCH 54/62] remove quotes from library links for debug/optimized --- domain-server/CMakeLists.txt | 2 +- libraries/fbx/CMakeLists.txt | 2 +- libraries/networking/CMakeLists.txt | 2 +- libraries/octree/CMakeLists.txt | 2 +- libraries/voxels/CMakeLists.txt | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/domain-server/CMakeLists.txt b/domain-server/CMakeLists.txt index b9f730baaf..482c397b14 100644 --- a/domain-server/CMakeLists.txt +++ b/domain-server/CMakeLists.txt @@ -50,6 +50,6 @@ endif () include_directories(SYSTEM "${OPENSSL_INCLUDE_DIR}") # append OpenSSL to our list of libraries to link -target_link_libraries(${TARGET_NAME} "${OPENSSL_LIBRARIES}") +target_link_libraries(${TARGET_NAME} ${OPENSSL_LIBRARIES}) link_shared_dependencies() \ No newline at end of file diff --git a/libraries/fbx/CMakeLists.txt b/libraries/fbx/CMakeLists.txt index 2e58645b56..5a151deb8b 100644 --- a/libraries/fbx/CMakeLists.txt +++ b/libraries/fbx/CMakeLists.txt @@ -9,7 +9,7 @@ link_hifi_libraries(shared networking octree voxels) find_package(ZLIB REQUIRED) include_directories(SYSTEM "${ZLIB_INCLUDE_DIRS}") -target_link_libraries(${TARGET_NAME} "${ZLIB_LIBRARIES}") +target_link_libraries(${TARGET_NAME} ${ZLIB_LIBRARIES}) # call macro to link our dependencies and bubble them up via a property on our target link_shared_dependencies() diff --git a/libraries/networking/CMakeLists.txt b/libraries/networking/CMakeLists.txt index 90e06bc13e..934e3e69b9 100644 --- a/libraries/networking/CMakeLists.txt +++ b/libraries/networking/CMakeLists.txt @@ -23,7 +23,7 @@ endif () include_directories(SYSTEM "${OPENSSL_INCLUDE_DIR}") # append OpenSSL to our list of libraries to link -target_link_libraries(${TARGET_NAME} "${OPENSSL_LIBRARIES}" "${TBB_LIBRARIES}") +target_link_libraries(${TARGET_NAME} ${OPENSSL_LIBRARIES} ${TBB_LIBRARIES}) # append libcuckoo includes to our list of includes to bubble list(APPEND ${TARGET_NAME}_DEPENDENCY_INCLUDES "${TBB_INCLUDE_DIRS}") diff --git a/libraries/octree/CMakeLists.txt b/libraries/octree/CMakeLists.txt index f1a30f3724..e8c6554ff4 100644 --- a/libraries/octree/CMakeLists.txt +++ b/libraries/octree/CMakeLists.txt @@ -13,7 +13,7 @@ find_package(ZLIB REQUIRED) include_directories(SYSTEM "${ZLIB_INCLUDE_DIRS}") # append ZLIB and OpenSSL to our list of libraries to link -target_link_libraries(${TARGET_NAME} "${ZLIB_LIBRARIES}") +target_link_libraries(${TARGET_NAME} ${ZLIB_LIBRARIES}) # call macro to link our dependencies and bubble them up via a property on our target link_shared_dependencies() diff --git a/libraries/voxels/CMakeLists.txt b/libraries/voxels/CMakeLists.txt index 874a74ee95..7980094884 100644 --- a/libraries/voxels/CMakeLists.txt +++ b/libraries/voxels/CMakeLists.txt @@ -12,7 +12,7 @@ find_package(ZLIB REQUIRED) include_directories(SYSTEM "${ZLIB_INCLUDE_DIRS}") # add it to our list of libraries to link -target_link_libraries(${TARGET_NAME} "${ZLIB_LIBRARIES}") +target_link_libraries(${TARGET_NAME} ${ZLIB_LIBRARIES}) # call macro to link our dependencies and bubble them up via a property on our target link_shared_dependencies() \ No newline at end of file From e6d3278b59c3d4a0530b054ee9e36ec2890f7668 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 18 Dec 2014 09:47:20 -0800 Subject: [PATCH 55/62] add back include of GLUT in render-utils --- libraries/render-utils/CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libraries/render-utils/CMakeLists.txt b/libraries/render-utils/CMakeLists.txt index 8d4f85a2ac..4be4d93a9a 100644 --- a/libraries/render-utils/CMakeLists.txt +++ b/libraries/render-utils/CMakeLists.txt @@ -7,5 +7,8 @@ include_glm() link_hifi_libraries(shared gpu) +find_package(GLUT REQUIRED) +include_directories(SYSTEM "${GLUT_INCLUDE_DIRS}") + # call macro to link our dependencies and bubble them up via a property on our target link_shared_dependencies() From 4042b8b17ac6525e77ed61d139fb0cbf18e1bbd3 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 18 Dec 2014 09:50:10 -0800 Subject: [PATCH 56/62] duh, glut only required on win --- libraries/render-utils/CMakeLists.txt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libraries/render-utils/CMakeLists.txt b/libraries/render-utils/CMakeLists.txt index 4be4d93a9a..a6943addcc 100644 --- a/libraries/render-utils/CMakeLists.txt +++ b/libraries/render-utils/CMakeLists.txt @@ -7,8 +7,10 @@ include_glm() link_hifi_libraries(shared gpu) -find_package(GLUT REQUIRED) -include_directories(SYSTEM "${GLUT_INCLUDE_DIRS}") +if (WIN32) + find_package(GLUT REQUIRED) + include_directories(SYSTEM "${GLUT_INCLUDE_DIRS}") +endif () # call macro to link our dependencies and bubble them up via a property on our target link_shared_dependencies() From 011b313b681c4ac8767e51dbd3afa2d06b6f412d Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 18 Dec 2014 11:30:57 -0800 Subject: [PATCH 57/62] fix indentation in MetavoxelClientManager --- libraries/metavoxels/src/MetavoxelClientManager.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libraries/metavoxels/src/MetavoxelClientManager.cpp b/libraries/metavoxels/src/MetavoxelClientManager.cpp index dfc736edc9..e0489b4bd0 100644 --- a/libraries/metavoxels/src/MetavoxelClientManager.cpp +++ b/libraries/metavoxels/src/MetavoxelClientManager.cpp @@ -50,7 +50,8 @@ SharedObjectPointer MetavoxelClientManager::findFirstRaySpannerIntersection(cons if (client) { float clientDistance; SharedObjectPointer clientSpanner = client->getDataCopy().findFirstRaySpannerIntersection( - origin, direction, attribute, clientDistance); + origin, direction, attribute, clientDistance + ); if (clientSpanner && clientDistance < closestDistance) { closestSpanner = clientSpanner; closestDistance = clientDistance; From 587df1178dfc19dc31e261466bd54ffa138fe646 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 18 Dec 2014 13:57:19 -0800 Subject: [PATCH 58/62] use constant for MSEC to USEC conversion --- libraries/networking/src/LimitedNodeList.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index c6e79cc18f..de533ec7be 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -504,7 +504,7 @@ void LimitedNodeList::removeSilentNodes() { SharedNodePointer node = it->second; node->getMutex().lock(); - if ((usecTimestampNow() - node->getLastHeardMicrostamp()) > (NODE_SILENCE_THRESHOLD_MSECS * 1000)) { + if ((usecTimestampNow() - node->getLastHeardMicrostamp()) > (NODE_SILENCE_THRESHOLD_MSECS * USECS_PER_MSEC)) { // call the NodeHash erase to get rid of this node it = _nodeHash.unsafe_erase(it); From df3eca5aca594a6f8b6108c09f9fa72945076ea7 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 18 Dec 2014 14:01:22 -0800 Subject: [PATCH 59/62] add a comment for the UUID hasher --- libraries/networking/src/UUIDHasher.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libraries/networking/src/UUIDHasher.h b/libraries/networking/src/UUIDHasher.h index d5d16e21e9..02f7e3685a 100644 --- a/libraries/networking/src/UUIDHasher.h +++ b/libraries/networking/src/UUIDHasher.h @@ -14,6 +14,9 @@ #include "UUID.h" +// uses the same hashing performed by Qt +// https://qt.gitorious.org/qt/qtbase/source/73ef64fb5fabb60101a3cac6e43f0c5bb2298000:src/corelib/plugin/quuid.cpp + class UUIDHasher { public: size_t operator()(const QUuid& uuid) const { From 07f95c597cde73fa127c72085e443f65cb2c68f5 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 18 Dec 2014 14:08:55 -0800 Subject: [PATCH 60/62] add read locks for find on tbb hash --- libraries/networking/src/LimitedNodeList.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index de533ec7be..907ac86704 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -352,6 +352,8 @@ int LimitedNodeList::findNodeAndUpdateWithDataFromPacket(const QByteArray& packe } SharedNodePointer LimitedNodeList::nodeWithUUID(const QUuid& nodeUUID) { + QReadLocker readLocker(&_nodeMutex); + NodeHash::const_iterator it = _nodeHash.find(nodeUUID); return it == _nodeHash.cend() ? SharedNodePointer() : it->second; } @@ -386,10 +388,14 @@ void LimitedNodeList::reset() { } void LimitedNodeList::killNodeWithUUID(const QUuid& nodeUUID) { + _nodeMutex.lockForRead(); + NodeHash::iterator it = _nodeHash.find(nodeUUID); if (it != _nodeHash.end()) { SharedNodePointer matchingNode = it->second; + _nodeMutex.unlock(); + QWriteLocker writeLocker(&_nodeMutex); _nodeHash.unsafe_erase(it); From e13e9febdc69178a13e29e3e993b5f339bcfb0be Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 18 Dec 2014 14:16:22 -0800 Subject: [PATCH 61/62] unlock the node mutex if node not found --- libraries/networking/src/LimitedNodeList.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index 907ac86704..5e13f6bbc9 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -400,6 +400,8 @@ void LimitedNodeList::killNodeWithUUID(const QUuid& nodeUUID) { _nodeHash.unsafe_erase(it); handleNodeKill(matchingNode); + } else { + _nodeMutex.unlock(); } } From 325d0dbce1daac75a9a6eda26df62616142d3fd2 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 18 Dec 2014 14:31:34 -0800 Subject: [PATCH 62/62] include QUuid instead of UUID in UUIDHasher --- libraries/networking/src/UUIDHasher.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/networking/src/UUIDHasher.h b/libraries/networking/src/UUIDHasher.h index 02f7e3685a..5429e151c7 100644 --- a/libraries/networking/src/UUIDHasher.h +++ b/libraries/networking/src/UUIDHasher.h @@ -12,7 +12,7 @@ #ifndef hifi_UUIDHasher_h #define hifi_UUIDHasher_h -#include "UUID.h" +#include // uses the same hashing performed by Qt // https://qt.gitorious.org/qt/qtbase/source/73ef64fb5fabb60101a3cac6e43f0c5bb2298000:src/corelib/plugin/quuid.cpp