Showing the changes to interface/src/Application.cpp (1 of 70 files). Show all
Unified · Split
| @@ -2125,19 +2125,19 @@ void Application::updateMyAvatar(float deltaTime) { · 2124 unmodified lines | ||
| 2125 | 2125 | const quint64 TOO_LONG_SINCE_LAST_NACK = 1 * USECS_PER_SECOND; |
| 2126 | 2126 | if (sinceLastNack > TOO_LONG_SINCE_LAST_NACK) { |
| 2127 | 2127 | _lastNackTime = now; |
| 2128 | − sendNack(); | |
| 2128 | + sendNackPackets(); | |
| 2129 | 2129 | } |
| 2130 | 2130 | } |
| 2131 | 2131 | } |
| 2132 | 2132 | |
| 2133 | −void Application::sendNack() { | |
| 2133 | +int Application::sendNackPackets() { | |
| 2134 | 2134 | |
| 2135 | 2135 | if (Menu::getInstance()->isOptionChecked(MenuOption::DisableNackPackets)) { |
| 2136 | − return; | |
| 2136 | + return 0; | |
| 2137 | 2137 | } |
| 2138 | 2138 | |
| 2139 | + int packetsSent = 0; | |
| 2139 | 2140 | char packet[MAX_PACKET_SIZE]; |
| 2140 | − NodeList* nodeList = NodeList::getInstance(); | |
| 2141 | 2141 | |
| 2142 | 2142 | // iterates thru all nodes in NodeList |
| 2143 | 2143 | foreach(const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) { |
| @@ -2148,14 +2148,14 @@ void Application::sendNack() { · 4 unmodified lines | ||
| 2148 | 2148 | || node->getType() == NodeType::ModelServer) |
| 2149 | 2149 | ) { |
| 2150 | 2150 | |
| 2151 | + QUuid nodeUUID = node->getUUID(); | |
| 2152 | + | |
| 2151 | 2153 | // if there are octree packets from this node that are waiting to be processed, |
| 2152 | 2154 | // don't send a NACK since the missing packets may be among those waiting packets. |
| 2153 | − if (_octreeProcessor.hasPacketsToProcessFrom(node)) { | |
| 2155 | + if (_octreeProcessor.hasPacketsToProcessFrom(nodeUUID)) { | |
| 2154 | 2156 | continue; |
| 2155 | 2157 | } |
| 2156 | − | |
| 2157 | − QUuid nodeUUID = node->getUUID(); | |
| 2158 | − | |
| 2158 | + | |
| 2159 | 2159 | _octreeSceneStatsLock.lockForRead(); |
| 2160 | 2160 | |
| 2161 | 2161 | // retreive octree scene stats of this node |
| @@ -2165,40 +2165,48 @@ void Application::sendNack() { · 3 unmodified lines | ||
| 2165 | 2165 | } |
| 2166 | 2166 | OctreeSceneStats& stats = _octreeServerSceneStats[nodeUUID]; |
| 2167 | 2167 | |
| 2168 | − // check if there are any sequence numbers that need to be nacked | |
| 2169 | − int numSequenceNumbersAvailable = stats.getNumSequenceNumbersToNack(); | |
| 2170 | − if (numSequenceNumbersAvailable == 0) { | |
| 2171 | − _octreeSceneStatsLock.unlock(); | |
| 2172 | − continue; | |
| 2173 | − } | |
| 2168 | + // make copy of missing sequence numbers from stats | |
| 2169 | + const QSet<OCTREE_PACKET_SEQUENCE> missingSequenceNumbers = stats.getMissingSequenceNumbers(); | |
| 2174 | 2170 | |
| 2175 | − char* dataAt = packet; | |
| 2176 | − int bytesRemaining = MAX_PACKET_SIZE; | |
| 2177 | − | |
| 2178 | − // pack header | |
| 2179 | − int numBytesPacketHeader = populatePacketHeader(packet, PacketTypeOctreeDataNack); | |
| 2180 | − dataAt += numBytesPacketHeader; | |
| 2181 | − bytesRemaining -= numBytesPacketHeader; | |
| 2182 | − int numSequenceNumbersRoomFor = (bytesRemaining - sizeof(uint16_t)) / sizeof(OCTREE_PACKET_SEQUENCE); | |
| 2183 | − | |
| 2184 | − // calculate and pack the number of sequence numbers | |
| 2185 | − uint16_t numSequenceNumbers = min(numSequenceNumbersAvailable, numSequenceNumbersRoomFor); | |
| 2186 | − uint16_t* numSequenceNumbersAt = (uint16_t*)dataAt; | |
| 2187 | − *numSequenceNumbersAt = numSequenceNumbers; | |
| 2188 | − dataAt += sizeof(uint16_t); | |
| 2189 | − | |
| 2190 | − // pack sequence numbers | |
| 2191 | − for (int i = 0; i < numSequenceNumbers; i++) { | |
| 2192 | − OCTREE_PACKET_SEQUENCE* sequenceNumberAt = (OCTREE_PACKET_SEQUENCE*)dataAt; | |
| 2193 | − *sequenceNumberAt = stats.getNextSequenceNumberToNack(); | |
| 2194 | − dataAt += sizeof(OCTREE_PACKET_SEQUENCE); | |
| 2195 | − } | |
| 2196 | − | |
| 2197 | 2171 | _octreeSceneStatsLock.unlock(); |
| 2198 | 2172 | |
| 2199 | − nodeList->writeUnverifiedDatagram(packet, dataAt - packet, node); | |
| 2173 | + // construct nack packet(s) for this node | |
| 2174 | + int numSequenceNumbersAvailable = missingSequenceNumbers.size(); | |
| 2175 | + QSet<OCTREE_PACKET_SEQUENCE>::const_iterator missingSequenceNumbersIterator = missingSequenceNumbers.constBegin(); | |
| 2176 | + while (numSequenceNumbersAvailable > 0) { | |
| 2177 | + | |
| 2178 | + char* dataAt = packet; | |
| 2179 | + int bytesRemaining = MAX_PACKET_SIZE; | |
| 2180 | + | |
| 2181 | + // pack header | |
| 2182 | + int numBytesPacketHeader = populatePacketHeader(packet, PacketTypeOctreeDataNack); | |
| 2183 | + dataAt += numBytesPacketHeader; | |
| 2184 | + bytesRemaining -= numBytesPacketHeader; | |
| 2185 | + | |
| 2186 | + // calculate and pack the number of sequence numbers | |
| 2187 | + int numSequenceNumbersRoomFor = (bytesRemaining - sizeof(uint16_t)) / sizeof(OCTREE_PACKET_SEQUENCE); | |
| 2188 | + uint16_t numSequenceNumbers = min(numSequenceNumbersAvailable, numSequenceNumbersRoomFor); | |
| 2189 | + uint16_t* numSequenceNumbersAt = (uint16_t*)dataAt; | |
| 2190 | + *numSequenceNumbersAt = numSequenceNumbers; | |
| 2191 | + dataAt += sizeof(uint16_t); | |
| 2192 | + | |
| 2193 | + // pack sequence numbers | |
| 2194 | + for (int i = 0; i < numSequenceNumbers; i++) { | |
| 2195 | + OCTREE_PACKET_SEQUENCE* sequenceNumberAt = (OCTREE_PACKET_SEQUENCE*)dataAt; | |
| 2196 | + *sequenceNumberAt = *missingSequenceNumbersIterator; | |
| 2197 | + dataAt += sizeof(OCTREE_PACKET_SEQUENCE); | |
| 2198 | + | |
| 2199 | + missingSequenceNumbersIterator++; | |
| 2200 | + } | |
| 2201 | + numSequenceNumbersAvailable -= numSequenceNumbers; | |
| 2202 | + | |
| 2203 | + // send it | |
| 2204 | + NodeList::getInstance()->writeUnverifiedDatagram(packet, dataAt - packet, node); | |
| 2205 | + packetsSent++; | |
| 2206 | + } | |
| 2200 | 2207 | } |
| 2201 | 2208 | } |
| 2209 | + return packetsSent; | |
| 2202 | 2210 | } |
| 2203 | 2211 | |
| 2204 | 2212 | void Application::queryOctree(NodeType_t serverType, PacketType packetType, NodeToJurisdictionMap& jurisdictions) { |
| @@ -3183,7 +3191,7 @@ void Application::updateWindowTitle(){ · 978 unmodified lines | ||
| 3183 | 3191 | float creditBalance = accountManager.getAccountInfo().getBalance() / SATOSHIS_PER_CREDIT; |
| 3184 | 3192 | |
| 3185 | 3193 | QString creditBalanceString; |
| 3186 | − creditBalanceString.sprintf("%.8f", creditBalance); | |
| 3194 | + creditBalanceString.sprintf("%.8f", floor(creditBalance + 0.5)); | |
| 3187 | 3195 | |
| 3188 | 3196 | title += " - ₵" + creditBalanceString; |
| 3189 | 3197 | } |
| @@ -3272,10 +3280,16 @@ void Application::nodeAdded(SharedNodePointer node) { · 82 unmodified lines | ||
| 3272 | 3280 | |
| 3273 | 3281 | void Application::nodeKilled(SharedNodePointer node) { |
| 3274 | 3282 | |
| 3275 | − // this is here because connecting NodeList::nodeKilled to OctreePacketProcessor::nodeKilled doesn't work: | |
| 3276 | − // OctreePacketProcessor::nodeKilled is not called when NodeList::nodeKilled is emitted for some reason. | |
| 3283 | + // These are here because connecting NodeList::nodeKilled to OctreePacketProcessor::nodeKilled doesn't work: | |
| 3284 | + // OctreePacketProcessor::nodeKilled is not being called when NodeList::nodeKilled is emitted. | |
| 3285 | + // This may have to do with GenericThread::threadRoutine() blocking the QThread event loop | |
| 3286 | + | |
| 3277 | 3287 | _octreeProcessor.nodeKilled(node); |
| 3278 | 3288 | |
| 3289 | + _voxelEditSender.nodeKilled(node); | |
| 3290 | + _particleEditSender.nodeKilled(node); | |
| 3291 | + _modelEditSender.nodeKilled(node); | |
| 3292 | + | |
| 3279 | 3293 | if (node->getType() == NodeType::VoxelServer) { |
| 3280 | 3294 | QUuid nodeUUID = node->getUUID(); |
| 3281 | 3295 | // see if this is the first we've heard of this node... |