Merge branch 'master' of github.com:highfidelity/hifi into yellow

This commit is contained in:
Sam Gateau 2019-06-25 09:34:18 -07:00
commit 962a3c2502
19 changed files with 231 additions and 63 deletions

View file

@ -136,7 +136,8 @@ void DomainGatekeeper::processConnectRequestPacket(QSharedPointer<ReceivedMessag
} else { } else {
qDebug() << "Refusing connection from node at" << message->getSenderSockAddr() qDebug() << "Refusing connection from node at" << message->getSenderSockAddr()
<< "with hardware address" << nodeConnection.hardwareAddress << "with hardware address" << nodeConnection.hardwareAddress
<< "and machine fingerprint" << nodeConnection.machineFingerprint; << "and machine fingerprint" << nodeConnection.machineFingerprint
<< "sysinfo" << nodeConnection.SystemInfo;
} }
} }

View file

@ -37,7 +37,11 @@ NodeConnectionData NodeConnectionData::fromDataStream(QDataStream& dataStream, c
dataStream >> newHeader.machineFingerprint; dataStream >> newHeader.machineFingerprint;
// and the operating system type // and the operating system type
dataStream >> newHeader.SystemInfo; QByteArray compressedSystemInfo;
dataStream >> compressedSystemInfo;
if (!compressedSystemInfo.isEmpty()) {
newHeader.SystemInfo = qUncompress(compressedSystemInfo);
}
dataStream >> newHeader.connectReason; dataStream >> newHeader.connectReason;

View file

@ -1,4 +1,5 @@
cmake_minimum_required(VERSION 3.0) cmake_minimum_required(VERSION 3.0)
set(ENV{MACOSX_DEPLOYMENT_TARGET} 10.9)
project(HQLauncher) project(HQLauncher)
set (CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules/") set (CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules/")
set(src_files set(src_files
@ -26,6 +27,8 @@ set(src_files
src/LatestBuildRequest.m src/LatestBuildRequest.m
src/OrganizationRequest.m src/OrganizationRequest.m
src/OrganizationRequest.h src/OrganizationRequest.h
src/Interface.h
src/Interface.m
src/ErrorViewController.h src/ErrorViewController.h
src/ErrorViewController.m src/ErrorViewController.m
src/Settings.h src/Settings.h
@ -67,7 +70,7 @@ add_executable(${PROJECT_NAME} MACOSX_BUNDLE ${src_files})
set_target_properties(${PROJECT_NAME} PROPERTIES OUTPUT_NAME ${APP_NAME} set_target_properties(${PROJECT_NAME} PROPERTIES OUTPUT_NAME ${APP_NAME}
MACOSX_BUNDLE_BUNDLE_NAME ${APP_NAME}) MACOSX_BUNDLE_BUNDLE_NAME ${APP_NAME})
set_from_env(LAUNCHER_HMAC_SECRET LAUNCHER_HMAC_SECRET "") set_from_env(LAUNCHER_HMAC_SECRET LAUNCHER_HMAC_SECRET "")
if (LAUNCHER_HMAC_SECRET STREQUAL "") if ("${LAUNCHER_HMAC_SECRET}" STREQUAL "")
message(FATAL_ERROR "LAUNCHER_HMAC_SECRET is not set") message(FATAL_ERROR "LAUNCHER_HMAC_SECRET is not set")
endif() endif()

View file

@ -32,6 +32,6 @@
<key>CFBundleName</key> <key>CFBundleName</key>
<string>${MACOSX_BUNDLE_BUNDLE_NAME}</string> <string>${MACOSX_BUNDLE_BUNDLE_NAME}</string>
<key>CFBundleDisplayName</key> <key>CFBundleDisplayName</key>
<string>CFBundleName</string> <string>${MACOSX_BUNDLE_BUNDLE_NAME}</string>
</dict> </dict>
</plist> </plist>

View file

@ -69,8 +69,17 @@
<action selector="hyperLink:" target="YVh-OH-vU8" id="JfS-ot-wAP"/> <action selector="hyperLink:" target="YVh-OH-vU8" id="JfS-ot-wAP"/>
</connections> </connections>
</textField> </textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="0CN-kS-xZ5">
<rect key="frame" x="66" y="68" width="266" height="17"/>
<autoresizingMask key="autoresizingMask"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="center" title="By signing in, you agree to the High Fidelity" id="zSf-YA-osu">
<font key="font" metaFont="system"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="xeX-qc-ccB" customClass="HFButton"> <button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="xeX-qc-ccB" customClass="HFButton">
<rect key="frame" x="205" y="84" width="104" height="42"/> <rect key="frame" x="205" y="111" width="104" height="42"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="square" title="LOG IN" bezelStyle="shadowlessSquare" alignment="center" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="6Ba-S9-5qW"> <buttonCell key="cell" type="square" title="LOG IN" bezelStyle="shadowlessSquare" alignment="center" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="6Ba-S9-5qW">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/> <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
@ -81,6 +90,18 @@
<action selector="login:" target="YVh-OH-vU8" id="uzF-yC-tu1"/> <action selector="login:" target="YVh-OH-vU8" id="uzF-yC-tu1"/>
</connections> </connections>
</button> </button>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="QtF-Xs-rht" customClass="Hyperlink">
<rect key="frame" x="336" y="68" width="115" height="17"/>
<autoresizingMask key="autoresizingMask"/>
<textFieldCell key="cell" lineBreakMode="clipping" title="Terms of Service" id="O5x-BW-FLk">
<font key="font" metaFont="system"/>
<color key="textColor" name="linkColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="linkColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<connections>
<action selector="termsOfService:" target="YVh-OH-vU8" id="bgc-08-8Lj"/>
</connections>
</textField>
</subviews> </subviews>
<point key="canvasLocation" x="138.5" y="154"/> <point key="canvasLocation" x="138.5" y="154"/>
</customView> </customView>
@ -91,5 +112,14 @@
<outlet property="smallLogo" destination="j8K-TD-h7e" id="OVd-p3-nu6"/> <outlet property="smallLogo" destination="j8K-TD-h7e" id="OVd-p3-nu6"/>
</connections> </connections>
</customObject> </customObject>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" id="wWT-mi-6An">
<rect key="frame" x="0.0" y="0.0" width="37" height="17"/>
<autoresizingMask key="autoresizingMask"/>
<textFieldCell key="cell" lineBreakMode="clipping" title="Label" id="1Uh-1I-CcU">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</objects> </objects>
</document> </document>

View file

@ -31,4 +31,9 @@
{ {
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"https://www.highfidelity.com/hq-support"]]; [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"https://www.highfidelity.com/hq-support"]];
} }
- (IBAction)termsOfService:(id)sender
{
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"https://www.highfidelity.com/termsofservice"]];
}
@end @end

View file

@ -0,0 +1,8 @@
#import <Foundation/Foundation.h>
@interface Interface : NSObject
-(id _Nonnull) initWith:(NSString * _Nonnull) aPathToInterface;
-(NSInteger) getVersion:(out NSError * _Nullable * _Nonnull) anError;
@end

View file

@ -0,0 +1,90 @@
#import "Interface.h"
@implementation Interface
{
NSString *pathTo;
}
-(id) initWith:(NSString*)aPathToInterface
{
[self init];
self->pathTo = [NSString stringWithFormat:@"%@/Contents/MacOS/interface", aPathToInterface];
return self;
}
-(NSInteger) getVersion:(out NSError * _Nullable *) outError
{
NSTask * interface = [[NSTask alloc] init];
NSPipe * standardOut = [NSPipe pipe];
interface.launchPath = self->pathTo;
interface.arguments = @[ @"--version" ];
interface.standardOutput = standardOut;
NSLog(@"calling interface at %@", self->pathTo);
NSError *error = nil;
[interface launch];
[interface waitUntilExit];
if (0 != [interface terminationStatus]) {
*outError = [NSError errorWithDomain:@"interface"
code:-1
userInfo:@{NSUnderlyingErrorKey: error}];
return 0;
}
NSFileHandle * fh = [standardOut fileHandleForReading];
NSData * data = [fh readDataToEndOfFile];
NSString * output = [NSString stringWithUTF8String:[data bytes]];
if (output == nil) {
NSDictionary * userInfo = @{
NSLocalizedDescriptionKey: NSLocalizedString(@"Couldn't start interface", nil)
};
*outError = [NSError errorWithDomain:@"interface"
code:-1
userInfo:userInfo];
return 0;
}
// Interface returns the build version as a string like this:
// "Interface 33333-DEADBEEF". This code grabs the substring
// between "Interface " and the hyphon ("-")
NSRange start = [output rangeOfString:@"Interface "];
if (start.length == 0) {
NSDictionary * userInfo = @{
NSLocalizedDescriptionKey: NSLocalizedString(@"Couldn't read interface's version", nil)
};
*outError = [NSError errorWithDomain:@"interface"
code:-2
userInfo:userInfo];
return 0;
}
NSRange end = [output rangeOfString:@"-"];
if (end.length == 0) {
NSDictionary * userInfo = @{
NSLocalizedDescriptionKey: NSLocalizedString(@"Couldn't read interface's version", nil)
};
*outError = [NSError errorWithDomain:@"interface"
code:-2
userInfo:userInfo];
return 0;
}
NSRange subRange = {start.length, end.location - start.length};
NSString * versionStr;
@try {
versionStr = [output substringWithRange:subRange];
}
@catch (NSException *) {
NSDictionary * userInfo = @{
NSLocalizedDescriptionKey: NSLocalizedString(@"Couldn't read interface's version", nil)
};
*outError = [NSError errorWithDomain:@"interface"
code:-2
userInfo:userInfo];
return 0;
}
return versionStr.integerValue;
}
@end

View file

@ -1,17 +1,30 @@
#import "LatestBuildRequest.h" #import "LatestBuildRequest.h"
#import "Launcher.h" #import "Launcher.h"
#import "Settings.h" #import "Settings.h"
#import "Interface.h"
@implementation LatestBuildRequest @implementation LatestBuildRequest
- (NSInteger) getCurrentVersion {
NSString* interfaceAppPath = [[Launcher.sharedLauncher getAppPath] stringByAppendingString:@"interface.app"];
NSError * error = nil;
Interface * interface = [[Interface alloc] initWith:interfaceAppPath];
NSInteger currentVersion = [interface getVersion:&error];
if (currentVersion == 0 && error != nil) {
NSLog(@"can't get version from interface, falling back to settings: %@", error);
currentVersion = [Settings.sharedSettings latestBuildVersion];
}
return currentVersion;
}
- (void) requestLatestBuildInfo { - (void) requestLatestBuildInfo {
NSMutableURLRequest *request = [NSMutableURLRequest new]; NSMutableURLRequest *request = [NSMutableURLRequest new];
[request setURL:[NSURL URLWithString:@"https://thunder.highfidelity.com/builds/api/tags/latest?format=json"]]; [request setURL:[NSURL URLWithString:@"https://thunder.highfidelity.com/builds/api/tags/latest?format=json"]];
[request setHTTPMethod:@"GET"]; [request setHTTPMethod:@"GET"];
[request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"]; [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
// We're using an ephermeral session here to ensure the tags api response is never cached.
NSURLSession* session = [NSURLSession sharedSession]; NSURLSession * session = [NSURLSession sessionWithConfiguration:NSURLSessionConfiguration.ephemeralSessionConfiguration];
NSURLSessionDataTask* dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { NSURLSessionDataTask* dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
@ -45,8 +58,7 @@
BOOL appDirectoryExist = [fileManager fileExistsAtPath:[[sharedLauncher getAppPath] stringByAppendingString:@"interface.app"]]; BOOL appDirectoryExist = [fileManager fileExistsAtPath:[[sharedLauncher getAppPath] stringByAppendingString:@"interface.app"]];
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
Settings* settings = [Settings sharedSettings]; NSInteger currentVersion = [self getCurrentVersion];
NSInteger currentVersion = [settings latestBuildVersion];
NSLog(@"Latest Build Request -> does build directory exist: %@", appDirectoryExist ? @"TRUE" : @"FALSE"); NSLog(@"Latest Build Request -> does build directory exist: %@", appDirectoryExist ? @"TRUE" : @"FALSE");
NSLog(@"Latest Build Request -> current version: %ld", currentVersion); NSLog(@"Latest Build Request -> current version: %ld", currentVersion);
NSLog(@"Latest Build Request -> latest version: %ld", buildNumber.integerValue); NSLog(@"Latest Build Request -> latest version: %ld", buildNumber.integerValue);
@ -105,11 +117,10 @@
NSDictionary* macInstallerObject = [installers objectForKey:@"mac"]; NSDictionary* macInstallerObject = [installers objectForKey:@"mac"];
NSString* macInstallerUrl = [macInstallerObject valueForKey:@"zip_url"]; NSString* macInstallerUrl = [macInstallerObject valueForKey:@"zip_url"];
BOOL appDirectoryExist = [fileManager fileExistsAtPath:[[sharedLauncher getAppPath] stringByAppendingString:@"interface.app"]]; NSString* interfaceAppPath = [[sharedLauncher getAppPath] stringByAppendingString:@"interface.app"];
BOOL appDirectoryExist = [fileManager fileExistsAtPath:interfaceAppPath];
Settings* settings = [Settings sharedSettings];
NSInteger currentVersion = [settings latestBuildVersion]; BOOL latestVersionAvailable = ([self getCurrentVersion] != buildNumber.integerValue);
BOOL latestVersionAvailable = (currentVersion != buildNumber.integerValue);
[[Settings sharedSettings] buildVersion:buildNumber.integerValue]; [[Settings sharedSettings] buildVersion:buildNumber.integerValue];
BOOL shouldDownloadInterface = (latestVersionAvailable || !appDirectoryExist); BOOL shouldDownloadInterface = (latestVersionAvailable || !appDirectoryExist);

View file

@ -207,7 +207,7 @@ void EntityTreeRenderer::stopDomainAndNonOwnedEntities() {
if (entityItem && !entityItem->getScript().isEmpty()) { if (entityItem && !entityItem->getScript().isEmpty()) {
if (!(entityItem->isLocalEntity() || (entityItem->isAvatarEntity() && entityItem->getOwningAvatarID() == getTree()->getMyAvatarSessionUUID()))) { if (!(entityItem->isLocalEntity() || (entityItem->isAvatarEntity() && entityItem->getOwningAvatarID() == getTree()->getMyAvatarSessionUUID()))) {
if (entityItem->contains(_avatarPosition)) { if (_currentEntitiesInside.contains(entityID)) {
_entitiesScriptEngine->callEntityScriptMethod(entityID, "leaveEntity"); _entitiesScriptEngine->callEntityScriptMethod(entityID, "leaveEntity");
} }
_entitiesScriptEngine->unloadEntityScript(entityID, true); _entitiesScriptEngine->unloadEntityScript(entityID, true);
@ -222,6 +222,7 @@ void EntityTreeRenderer::clearDomainAndNonOwnedEntities() {
auto sessionUUID = getTree()->getMyAvatarSessionUUID(); auto sessionUUID = getTree()->getMyAvatarSessionUUID();
std::unordered_map<EntityItemID, EntityRendererPointer> savedEntities; std::unordered_map<EntityItemID, EntityRendererPointer> savedEntities;
std::unordered_set<EntityRendererPointer> savedRenderables;
// remove all entities from the scene // remove all entities from the scene
auto scene = _viewState->getMain3DScene(); auto scene = _viewState->getMain3DScene();
if (scene) { if (scene) {
@ -232,11 +233,12 @@ void EntityTreeRenderer::clearDomainAndNonOwnedEntities() {
fadeOutRenderable(renderer); fadeOutRenderable(renderer);
} else { } else {
savedEntities[entry.first] = entry.second; savedEntities[entry.first] = entry.second;
savedRenderables.insert(entry.second);
} }
} }
} }
_renderablesToUpdate = savedEntities; _renderablesToUpdate = savedRenderables;
_entitiesInScene = savedEntities; _entitiesInScene = savedEntities;
if (_layeredZones.clearDomainAndNonOwnedZones(sessionUUID)) { if (_layeredZones.clearDomainAndNonOwnedZones(sessionUUID)) {
@ -389,13 +391,7 @@ void EntityTreeRenderer::updateChangedEntities(const render::ScenePointer& scene
PerformanceTimer pt("change"); PerformanceTimer pt("change");
std::unordered_set<EntityItemID> changedEntities; std::unordered_set<EntityItemID> changedEntities;
_changedEntitiesGuard.withWriteLock([&] { _changedEntitiesGuard.withWriteLock([&] {
#if 0
// FIXME Weird build failure in latest VC update that fails to compile when using std::swap
changedEntities.swap(_changedEntities); changedEntities.swap(_changedEntities);
#else
changedEntities.insert(_changedEntities.begin(), _changedEntities.end());
_changedEntities.clear();
#endif
}); });
{ {
@ -404,7 +400,7 @@ void EntityTreeRenderer::updateChangedEntities(const render::ScenePointer& scene
auto renderable = renderableForEntityId(entityId); auto renderable = renderableForEntityId(entityId);
if (renderable) { if (renderable) {
// only add valid renderables _renderablesToUpdate // only add valid renderables _renderablesToUpdate
_renderablesToUpdate.insert({ entityId, renderable }); _renderablesToUpdate.insert(renderable);
} }
} }
} }
@ -414,8 +410,7 @@ void EntityTreeRenderer::updateChangedEntities(const render::ScenePointer& scene
// we expect to update all renderables within available time budget // we expect to update all renderables within available time budget
PROFILE_RANGE_EX(simulation_physics, "UpdateRenderables", 0xffff00ff, (uint64_t)_renderablesToUpdate.size()); PROFILE_RANGE_EX(simulation_physics, "UpdateRenderables", 0xffff00ff, (uint64_t)_renderablesToUpdate.size());
uint64_t updateStart = usecTimestampNow(); uint64_t updateStart = usecTimestampNow();
for (const auto& entry : _renderablesToUpdate) { for (const auto& renderable : _renderablesToUpdate) {
const auto& renderable = entry.second;
assert(renderable); // only valid renderables are added to _renderablesToUpdate assert(renderable); // only valid renderables are added to _renderablesToUpdate
renderable->updateInScene(scene, transaction); renderable->updateInScene(scene, transaction);
} }
@ -424,8 +419,8 @@ void EntityTreeRenderer::updateChangedEntities(const render::ScenePointer& scene
// compute average per-renderable update cost // compute average per-renderable update cost
float cost = (float)(usecTimestampNow() - updateStart) / (float)(numRenderables); float cost = (float)(usecTimestampNow() - updateStart) / (float)(numRenderables);
const float blend = 0.1f; const float BLEND = 0.1f;
_avgRenderableUpdateCost = (1.0f - blend) * _avgRenderableUpdateCost + blend * cost; _avgRenderableUpdateCost = (1.0f - BLEND) * _avgRenderableUpdateCost + BLEND * cost;
} else { } else {
// we expect the cost to updating all renderables to exceed available time budget // we expect the cost to updating all renderables to exceed available time budget
// so we first sort by priority and update in order until out of time // so we first sort by priority and update in order until out of time
@ -450,43 +445,40 @@ void EntityTreeRenderer::updateChangedEntities(const render::ScenePointer& scene
PrioritySortUtil::PriorityQueue<SortableRenderer> sortedRenderables(views); PrioritySortUtil::PriorityQueue<SortableRenderer> sortedRenderables(views);
sortedRenderables.reserve(_renderablesToUpdate.size()); sortedRenderables.reserve(_renderablesToUpdate.size());
{ {
PROFILE_RANGE_EX(simulation_physics, "SortRenderables", 0xffff00ff, (uint64_t)_renderablesToUpdate.size()); PROFILE_RANGE_EX(simulation_physics, "BuildSortedRenderables", 0xffff00ff, (uint64_t)_renderablesToUpdate.size());
std::unordered_map<EntityItemID, EntityRendererPointer>::iterator itr = _renderablesToUpdate.begin(); for (const auto& renderable : _renderablesToUpdate) {
while (itr != _renderablesToUpdate.end()) { assert(renderable); // only valid renderables are added to _renderablesToUpdate
assert(itr->second); // only valid renderables are added to _renderablesToUpdate sortedRenderables.push(SortableRenderer(renderable));
sortedRenderables.push(SortableRenderer(itr->second));
++itr;
} }
} }
{ {
PROFILE_RANGE_EX(simulation_physics, "UpdateRenderables", 0xffff00ff, sortedRenderables.size()); PROFILE_RANGE_EX(simulation_physics, "SortAndUpdateRenderables", 0xffff00ff, sortedRenderables.size());
// compute remaining time budget // compute remaining time budget
const auto& sortedRenderablesVector = sortedRenderables.getSortedVector();
uint64_t updateStart = usecTimestampNow(); uint64_t updateStart = usecTimestampNow();
uint64_t timeBudget = MIN_SORTED_UPDATE_RENDERABLES_TIME_BUDGET;
uint64_t sortCost = updateStart - sortStart; uint64_t sortCost = updateStart - sortStart;
uint64_t timeBudget = MIN_SORTED_UPDATE_RENDERABLES_TIME_BUDGET;
if (sortCost < MAX_UPDATE_RENDERABLES_TIME_BUDGET - MIN_SORTED_UPDATE_RENDERABLES_TIME_BUDGET) { if (sortCost < MAX_UPDATE_RENDERABLES_TIME_BUDGET - MIN_SORTED_UPDATE_RENDERABLES_TIME_BUDGET) {
timeBudget = MAX_UPDATE_RENDERABLES_TIME_BUDGET - sortCost; timeBudget = MAX_UPDATE_RENDERABLES_TIME_BUDGET - sortCost;
} }
uint64_t expiry = updateStart + timeBudget; uint64_t expiry = updateStart + timeBudget;
// process the sorted renderables // process the sorted renderables
size_t numSorted = sortedRenderables.size();
const auto& sortedRenderablesVector = sortedRenderables.getSortedVector();
for (const auto& sortedRenderable : sortedRenderablesVector) { for (const auto& sortedRenderable : sortedRenderablesVector) {
if (usecTimestampNow() > expiry) { if (usecTimestampNow() > expiry) {
break; break;
} }
const auto& renderable = sortedRenderable.getRenderer(); const auto& renderable = sortedRenderable.getRenderer();
renderable->updateInScene(scene, transaction); renderable->updateInScene(scene, transaction);
_renderablesToUpdate.erase(renderable->getEntity()->getID()); _renderablesToUpdate.erase(renderable);
} }
// compute average per-renderable update cost // compute average per-renderable update cost
size_t numUpdated = numSorted - sortedRenderables.size() + 1; // add one to avoid divide by zero size_t numUpdated = sortedRenderables.size() - _renderablesToUpdate.size() + 1; // add one to avoid divide by zero
float cost = (float)(usecTimestampNow() - updateStart) / (float)(numUpdated); float cost = (float)(usecTimestampNow() - updateStart) / (float)(numUpdated);
const float blend = 0.1f; const float BLEND = 0.1f;
_avgRenderableUpdateCost = (1.0f - blend) * _avgRenderableUpdateCost + blend * cost; _avgRenderableUpdateCost = (1.0f - BLEND) * _avgRenderableUpdateCost + BLEND * cost;
} }
} }
} }
@ -990,7 +982,6 @@ void EntityTreeRenderer::mouseMoveEvent(QMouseEvent* event) {
void EntityTreeRenderer::deletingEntity(const EntityItemID& entityID) { void EntityTreeRenderer::deletingEntity(const EntityItemID& entityID) {
// If it's in a pending queue, remove it // If it's in a pending queue, remove it
_renderablesToUpdate.erase(entityID);
_entitiesToAdd.erase(entityID); _entitiesToAdd.erase(entityID);
auto itr = _entitiesInScene.find(entityID); auto itr = _entitiesInScene.find(entityID);
@ -1000,7 +991,7 @@ void EntityTreeRenderer::deletingEntity(const EntityItemID& entityID) {
} }
if (_tree && !_shuttingDown && _entitiesScriptEngine && !itr->second->getEntity()->getScript().isEmpty()) { if (_tree && !_shuttingDown && _entitiesScriptEngine && !itr->second->getEntity()->getScript().isEmpty()) {
if (itr->second->getEntity()->contains(_avatarPosition)) { if (_currentEntitiesInside.contains(entityID)) {
_entitiesScriptEngine->callEntityScriptMethod(entityID, "leaveEntity"); _entitiesScriptEngine->callEntityScriptMethod(entityID, "leaveEntity");
} }
_entitiesScriptEngine->unloadEntityScript(entityID, true); _entitiesScriptEngine->unloadEntityScript(entityID, true);
@ -1013,6 +1004,7 @@ void EntityTreeRenderer::deletingEntity(const EntityItemID& entityID) {
} }
auto renderable = itr->second; auto renderable = itr->second;
_renderablesToUpdate.erase(renderable);
_entitiesInScene.erase(itr); _entitiesInScene.erase(itr);
if (!renderable) { if (!renderable) {
@ -1047,7 +1039,7 @@ void EntityTreeRenderer::checkAndCallPreload(const EntityItemID& entityID, bool
QString scriptUrl = entity->getScript(); QString scriptUrl = entity->getScript();
if ((shouldLoad && unloadFirst) || scriptUrl.isEmpty()) { if ((shouldLoad && unloadFirst) || scriptUrl.isEmpty()) {
if (_entitiesScriptEngine) { if (_entitiesScriptEngine) {
if (entity->contains(_avatarPosition)) { if (_currentEntitiesInside.contains(entityID)) {
_entitiesScriptEngine->callEntityScriptMethod(entityID, "leaveEntity"); _entitiesScriptEngine->callEntityScriptMethod(entityID, "leaveEntity");
} }
_entitiesScriptEngine->unloadEntityScript(entityID); _entitiesScriptEngine->unloadEntityScript(entityID);

View file

@ -246,7 +246,7 @@ private:
ReadWriteLockable _changedEntitiesGuard; ReadWriteLockable _changedEntitiesGuard;
std::unordered_set<EntityItemID> _changedEntities; std::unordered_set<EntityItemID> _changedEntities;
std::unordered_map<EntityItemID, EntityRendererPointer> _renderablesToUpdate; std::unordered_set<EntityRendererPointer> _renderablesToUpdate;
std::unordered_map<EntityItemID, EntityRendererPointer> _entitiesInScene; std::unordered_map<EntityItemID, EntityRendererPointer> _entitiesInScene;
std::unordered_map<EntityItemID, EntityItemWeakPointer> _entitiesToAdd; std::unordered_map<EntityItemID, EntityItemWeakPointer> _entitiesToAdd;

View file

@ -1,6 +1,6 @@
set(TARGET_NAME networking) set(TARGET_NAME networking)
setup_hifi_library(Network) setup_hifi_library(Network)
link_hifi_libraries(shared) link_hifi_libraries(shared platform)
target_openssl() target_openssl()
target_tbb() target_tbb()

View file

@ -26,6 +26,8 @@
#include <ThreadHelpers.h> #include <ThreadHelpers.h>
#include <LogHandler.h> #include <LogHandler.h>
#include <UUID.h> #include <UUID.h>
#include <platform/Platform.h>
#include <platform/PlatformKeys.h>
#include "AccountManager.h" #include "AccountManager.h"
#include "AddressManager.h" #include "AddressManager.h"
@ -42,6 +44,7 @@
using namespace std::chrono; using namespace std::chrono;
const int KEEPALIVE_PING_INTERVAL_MS = 1000; const int KEEPALIVE_PING_INTERVAL_MS = 1000;
const int MAX_SYSTEM_INFO_SIZE = 1000;
NodeList::NodeList(char newOwnerType, int socketListenPort, int dtlsListenPort) : NodeList::NodeList(char newOwnerType, int socketListenPort, int dtlsListenPort) :
LimitedNodeList(socketListenPort, dtlsListenPort), LimitedNodeList(socketListenPort, dtlsListenPort),
@ -418,19 +421,20 @@ void NodeList::sendDomainServerCheckIn() {
auto accountManager = DependencyManager::get<AccountManager>(); auto accountManager = DependencyManager::get<AccountManager>();
packetStream << FingerprintUtils::getMachineFingerprint(); packetStream << FingerprintUtils::getMachineFingerprint();
QString systemInfo; auto desc = platform::getAll();
#if defined Q_OS_WIN
systemInfo = "OS:Windows"; QByteArray systemInfo(desc.dump().c_str());
#elif defined Q_OS_OSX QByteArray compressedSystemInfo = qCompress(systemInfo);
systemInfo = "OS:OSX";
#elif defined Q_OS_LINUX if (compressedSystemInfo.size() > MAX_SYSTEM_INFO_SIZE) {
systemInfo = "OS:Linux"; // Highly unlikely, as not even unreasonable machines will
#elif defined Q_OS_ANDROID // overflow the max size, but prevent MTU overflow anyway.
systemInfo = "OS:Android"; // We could do something sophisticated like clearing specific
#else // values if they're too big, but we'll save that for later.
systemInfo = "OS:Unknown"; compressedSystemInfo.clear();
#endif }
packetStream << systemInfo;
packetStream << compressedSystemInfo;
packetStream << _connectReason; packetStream << _connectReason;

View file

@ -20,6 +20,7 @@
#include <LogHandler.h> #include <LogHandler.h>
#include <shared/QtHelpers.h> #include <shared/QtHelpers.h>
#include <platform/Platform.h>
#include "NetworkLogging.h" #include "NetworkLogging.h"
ThreadedAssignment::ThreadedAssignment(ReceivedMessage& message) : ThreadedAssignment::ThreadedAssignment(ReceivedMessage& message) :
@ -38,6 +39,16 @@ ThreadedAssignment::ThreadedAssignment(ReceivedMessage& message) :
// if the NL tells us we got a DS response, clear our member variable of queued check-ins // if the NL tells us we got a DS response, clear our member variable of queued check-ins
auto nodeList = DependencyManager::get<NodeList>(); auto nodeList = DependencyManager::get<NodeList>();
connect(nodeList.data(), &NodeList::receivedDomainServerList, this, &ThreadedAssignment::clearQueuedCheckIns); connect(nodeList.data(), &NodeList::receivedDomainServerList, this, &ThreadedAssignment::clearQueuedCheckIns);
platform::create();
if (!platform::enumeratePlatform()) {
qCDebug(networking) << "Failed to enumerate platform.";
}
}
ThreadedAssignment::~ThreadedAssignment() {
stop();
platform::destroy();
} }
void ThreadedAssignment::setFinished(bool isFinished) { void ThreadedAssignment::setFinished(bool isFinished) {

View file

@ -22,7 +22,7 @@ class ThreadedAssignment : public Assignment {
Q_OBJECT Q_OBJECT
public: public:
ThreadedAssignment(ReceivedMessage& message); ThreadedAssignment(ReceivedMessage& message);
~ThreadedAssignment() { stop(); } ~ThreadedAssignment();
virtual void aboutToFinish() { }; virtual void aboutToFinish() { };
void addPacketStatsAndSendStatsPacket(QJsonObject statsObject); void addPacketStatsAndSendStatsPacket(QJsonObject statsObject);

View file

@ -72,7 +72,7 @@ PacketVersion versionForPacketType(PacketType packetType) {
return static_cast<PacketVersion>(DomainConnectionDeniedVersion::IncludesExtraInfo); return static_cast<PacketVersion>(DomainConnectionDeniedVersion::IncludesExtraInfo);
case PacketType::DomainConnectRequest: case PacketType::DomainConnectRequest:
return static_cast<PacketVersion>(DomainConnectRequestVersion::HasSystemInfo); return static_cast<PacketVersion>(DomainConnectRequestVersion::HasCompressedSystemInfo);
case PacketType::DomainServerAddedNode: case PacketType::DomainServerAddedNode:
return static_cast<PacketVersion>(DomainServerAddedNodeVersion::PermissionsGrid); return static_cast<PacketVersion>(DomainServerAddedNodeVersion::PermissionsGrid);

View file

@ -347,7 +347,8 @@ enum class DomainConnectRequestVersion : PacketVersion {
AlwaysHasMachineFingerprint, AlwaysHasMachineFingerprint,
HasTimestamp, HasTimestamp,
HasReason, HasReason,
HasSystemInfo HasSystemInfo,
HasCompressedSystemInfo
}; };
enum class DomainConnectionDeniedVersion : PacketVersion { enum class DomainConnectionDeniedVersion : PacketVersion {

View file

@ -5,3 +5,11 @@ link_hifi_libraries(shared)
GroupSources("src") GroupSources("src")
target_json() target_json()
if (APPLE)
# link in required OS X frameworks and include the right GL headers
find_library(OpenGL OpenGL)
find_library(AppKit AppKit)
target_link_libraries(${TARGET_NAME} ${OpenGL} ${AppKit})
endif ()

View file

@ -45,7 +45,7 @@ namespace PrioritySortUtil {
class PriorityQueue { class PriorityQueue {
public: public:
PriorityQueue() = delete; PriorityQueue() = delete;
PriorityQueue(const ConicalViewFrustums& views) : _views(views) { } PriorityQueue(const ConicalViewFrustums& views) : _views(views), _usecCurrentTime(usecTimestampNow()) { }
PriorityQueue(const ConicalViewFrustums& views, float angularWeight, float centerWeight, float ageWeight) PriorityQueue(const ConicalViewFrustums& views, float angularWeight, float centerWeight, float ageWeight)
: _views(views), _angularWeight(angularWeight), _centerWeight(centerWeight), _ageWeight(ageWeight) : _views(views), _angularWeight(angularWeight), _centerWeight(centerWeight), _ageWeight(ageWeight)
, _usecCurrentTime(usecTimestampNow()) { , _usecCurrentTime(usecTimestampNow()) {