mirror of
https://thingvellir.net/git/overte
synced 2025-03-27 23:52:03 +01:00
Merge pull request #13555 from SamGondelman/destroy
Trying to fix dependency shutdown
This commit is contained in:
commit
1edf1b4337
27 changed files with 294 additions and 289 deletions
|
@ -516,7 +516,7 @@ void Agent::setIsListeningToAudioStream(bool isListeningToAudioStream) {
|
|||
|
||||
auto nodeList = DependencyManager::get<NodeList>();
|
||||
nodeList->eachMatchingNode(
|
||||
[&](const SharedNodePointer& node)->bool {
|
||||
[](const SharedNodePointer& node)->bool {
|
||||
return (node->getType() == NodeType::AudioMixer) && node->getActiveSocket();
|
||||
},
|
||||
[&](const SharedNodePointer& node) {
|
||||
|
|
|
@ -264,7 +264,8 @@ void DomainGatekeeper::updateNodePermissions() {
|
|||
QList<SharedNodePointer> nodesToKill;
|
||||
|
||||
auto limitedNodeList = DependencyManager::get<LimitedNodeList>();
|
||||
limitedNodeList->eachNode([this, limitedNodeList, &nodesToKill](const SharedNodePointer& node){
|
||||
QWeakPointer<LimitedNodeList> limitedNodeListWeak = limitedNodeList;
|
||||
limitedNodeList->eachNode([this, limitedNodeListWeak, &nodesToKill](const SharedNodePointer& node){
|
||||
// the id and the username in NodePermissions will often be the same, but id is set before
|
||||
// authentication and verifiedUsername is only set once they user's key has been confirmed.
|
||||
QString verifiedUsername = node->getPermissions().getVerifiedUserName();
|
||||
|
@ -296,7 +297,8 @@ void DomainGatekeeper::updateNodePermissions() {
|
|||
machineFingerprint = nodeData->getMachineFingerprint();
|
||||
|
||||
auto sendingAddress = nodeData->getSendingSockAddr().getAddress();
|
||||
isLocalUser = (sendingAddress == limitedNodeList->getLocalSockAddr().getAddress() ||
|
||||
auto nodeList = limitedNodeListWeak.lock();
|
||||
isLocalUser = ((nodeList && sendingAddress == nodeList->getLocalSockAddr().getAddress()) ||
|
||||
sendingAddress == QHostAddress::LocalHost);
|
||||
}
|
||||
|
||||
|
@ -458,7 +460,7 @@ SharedNodePointer DomainGatekeeper::processAgentConnectRequest(const NodeConnect
|
|||
|
||||
// in case this is a node that's failing to connect
|
||||
// double check we don't have the same node whose sockets match exactly already in the list
|
||||
limitedNodeList->eachNodeBreakable([&](const SharedNodePointer& node){
|
||||
limitedNodeList->eachNodeBreakable([nodeConnection, username, &existingNodeID](const SharedNodePointer& node){
|
||||
|
||||
if (node->getPublicSocket() == nodeConnection.publicSockAddr && node->getLocalSocket() == nodeConnection.localSockAddr) {
|
||||
// we have a node that already has these exact sockets - this can occur if a node
|
||||
|
@ -1009,7 +1011,7 @@ void DomainGatekeeper::refreshGroupsCache() {
|
|||
getDomainOwnerFriendsList();
|
||||
|
||||
auto nodeList = DependencyManager::get<LimitedNodeList>();
|
||||
nodeList->eachNode([&](const SharedNodePointer& node) {
|
||||
nodeList->eachNode([this](const SharedNodePointer& node) {
|
||||
if (!node->getPermissions().isAssignment) {
|
||||
// this node is an agent
|
||||
const QString& verifiedUserName = node->getPermissions().getVerifiedUserName();
|
||||
|
|
|
@ -1078,7 +1078,7 @@ bool DomainServer::isInInterestSet(const SharedNodePointer& nodeA, const SharedN
|
|||
unsigned int DomainServer::countConnectedUsers() {
|
||||
unsigned int result = 0;
|
||||
auto nodeList = DependencyManager::get<LimitedNodeList>();
|
||||
nodeList->eachNode([&](const SharedNodePointer& node){
|
||||
nodeList->eachNode([&result](const SharedNodePointer& node){
|
||||
// only count unassigned agents (i.e., users)
|
||||
if (node->getType() == NodeType::Agent) {
|
||||
auto nodeData = static_cast<DomainServerNodeData*>(node->getLinkedData());
|
||||
|
@ -1181,7 +1181,7 @@ void DomainServer::sendDomainListToNode(const SharedNodePointer& node, const Hif
|
|||
// DTLSServerSession* dtlsSession = _isUsingDTLS ? _dtlsSessions[senderSockAddr] : NULL;
|
||||
if (nodeData->isAuthenticated()) {
|
||||
// if this authenticated node has any interest types, send back those nodes as well
|
||||
limitedNodeList->eachNode([&](const SharedNodePointer& otherNode) {
|
||||
limitedNodeList->eachNode([this, node, &domainListPackets, &domainListStream](const SharedNodePointer& otherNode) {
|
||||
if (otherNode->getUUID() != node->getUUID() && isInInterestSet(node, otherNode)) {
|
||||
// since we're about to add a node to the packet we start a segment
|
||||
domainListPackets->startSegment();
|
||||
|
@ -1230,6 +1230,7 @@ QUuid DomainServer::connectionSecretForNodes(const SharedNodePointer& nodeA, con
|
|||
void DomainServer::broadcastNewNode(const SharedNodePointer& addedNode) {
|
||||
|
||||
auto limitedNodeList = DependencyManager::get<LimitedNodeList>();
|
||||
QWeakPointer<LimitedNodeList> limitedNodeListWeak = limitedNodeList;
|
||||
|
||||
auto addNodePacket = NLPacket::create(PacketType::DomainServerAddedNode);
|
||||
|
||||
|
@ -1241,7 +1242,7 @@ void DomainServer::broadcastNewNode(const SharedNodePointer& addedNode) {
|
|||
int connectionSecretIndex = addNodePacket->pos();
|
||||
|
||||
limitedNodeList->eachMatchingNode(
|
||||
[&](const SharedNodePointer& node)->bool {
|
||||
[this, addedNode](const SharedNodePointer& node)->bool {
|
||||
if (node->getLinkedData() && node->getActiveSocket() && node != addedNode) {
|
||||
// is the added Node in this node's interest list?
|
||||
return isInInterestSet(node, addedNode);
|
||||
|
@ -1249,16 +1250,19 @@ void DomainServer::broadcastNewNode(const SharedNodePointer& addedNode) {
|
|||
return false;
|
||||
}
|
||||
},
|
||||
[&](const SharedNodePointer& node) {
|
||||
addNodePacket->seek(connectionSecretIndex);
|
||||
|
||||
QByteArray rfcConnectionSecret = connectionSecretForNodes(node, addedNode).toRfc4122();
|
||||
|
||||
// replace the bytes at the end of the packet for the connection secret between these nodes
|
||||
addNodePacket->write(rfcConnectionSecret);
|
||||
|
||||
[this, &addNodePacket, connectionSecretIndex, addedNode, limitedNodeListWeak](const SharedNodePointer& node) {
|
||||
// send off this packet to the node
|
||||
limitedNodeList->sendUnreliablePacket(*addNodePacket, *node);
|
||||
auto limitedNodeList = limitedNodeListWeak.lock();
|
||||
if (limitedNodeList) {
|
||||
addNodePacket->seek(connectionSecretIndex);
|
||||
|
||||
QByteArray rfcConnectionSecret = connectionSecretForNodes(node, addedNode).toRfc4122();
|
||||
|
||||
// replace the bytes at the end of the packet for the connection secret between these nodes
|
||||
addNodePacket->write(rfcConnectionSecret);
|
||||
|
||||
limitedNodeList->sendUnreliablePacket(*addNodePacket, *node);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
@ -2864,7 +2868,7 @@ void DomainServer::updateReplicationNodes(ReplicationServerDirection direction)
|
|||
auto serversSettings = replicationSettings.value(serversKey).toList();
|
||||
|
||||
std::vector<HifiSockAddr> knownReplicationNodes;
|
||||
nodeList->eachNode([&](const SharedNodePointer& otherNode) {
|
||||
nodeList->eachNode([direction, &knownReplicationNodes](const SharedNodePointer& otherNode) {
|
||||
if ((direction == Upstream && NodeType::isUpstream(otherNode->getType()))
|
||||
|| (direction == Downstream && NodeType::isDownstream(otherNode->getType()))) {
|
||||
knownReplicationNodes.push_back(otherNode->getPublicSocket());
|
||||
|
@ -2902,7 +2906,7 @@ void DomainServer::updateReplicationNodes(ReplicationServerDirection direction)
|
|||
// collect them in a vector to separately remove them with handleKillNode (since eachNode has a read lock and
|
||||
// we cannot recursively take the write lock required by handleKillNode)
|
||||
std::vector<SharedNodePointer> nodesToKill;
|
||||
nodeList->eachNode([&](const SharedNodePointer& otherNode) {
|
||||
nodeList->eachNode([this, direction, replicationNodesInSettings, replicationDirection, &nodesToKill](const SharedNodePointer& otherNode) {
|
||||
if ((direction == Upstream && NodeType::isUpstream(otherNode->getType()))
|
||||
|| (direction == Downstream && NodeType::isDownstream(otherNode->getType()))) {
|
||||
bool nodeInSettings = find(replicationNodesInSettings.cbegin(), replicationNodesInSettings.cend(),
|
||||
|
|
|
@ -45,9 +45,7 @@ QString AboutUtil::getQtVersion() const {
|
|||
}
|
||||
|
||||
void AboutUtil::openUrl(const QString& url) const {
|
||||
|
||||
auto tabletScriptingInterface = DependencyManager::get<TabletScriptingInterface>();
|
||||
auto tablet = tabletScriptingInterface->getTablet("com.highfidelity.interface.tablet.system");
|
||||
auto tablet = DependencyManager::get<TabletScriptingInterface>()->getTablet("com.highfidelity.interface.tablet.system");
|
||||
auto hmd = DependencyManager::get<HMDScriptingInterface>();
|
||||
auto offscreenUi = DependencyManager::get<OffscreenUi>();
|
||||
|
||||
|
|
|
@ -1139,8 +1139,10 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
|
||||
// setup a timer for domain-server check ins
|
||||
QTimer* domainCheckInTimer = new QTimer(this);
|
||||
connect(domainCheckInTimer, &QTimer::timeout, [this, nodeList] {
|
||||
if (!isServerlessMode()) {
|
||||
QWeakPointer<NodeList> nodeListWeak = nodeList;
|
||||
connect(domainCheckInTimer, &QTimer::timeout, [this, nodeListWeak] {
|
||||
auto nodeList = nodeListWeak.lock();
|
||||
if (!isServerlessMode() && nodeList) {
|
||||
nodeList->sendDomainServerCheckIn();
|
||||
}
|
||||
});
|
||||
|
@ -1150,33 +1152,34 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
domainCheckInTimer->deleteLater();
|
||||
});
|
||||
|
||||
{
|
||||
auto audioIO = DependencyManager::get<AudioClient>().data();
|
||||
audioIO->setPositionGetter([] {
|
||||
auto avatarManager = DependencyManager::get<AvatarManager>();
|
||||
auto myAvatar = avatarManager ? avatarManager->getMyAvatar() : nullptr;
|
||||
|
||||
auto audioIO = DependencyManager::get<AudioClient>();
|
||||
audioIO->setPositionGetter([]{
|
||||
auto avatarManager = DependencyManager::get<AvatarManager>();
|
||||
auto myAvatar = avatarManager ? avatarManager->getMyAvatar() : nullptr;
|
||||
return myAvatar ? myAvatar->getPositionForAudio() : Vectors::ZERO;
|
||||
});
|
||||
audioIO->setOrientationGetter([] {
|
||||
auto avatarManager = DependencyManager::get<AvatarManager>();
|
||||
auto myAvatar = avatarManager ? avatarManager->getMyAvatar() : nullptr;
|
||||
|
||||
return myAvatar ? myAvatar->getPositionForAudio() : Vectors::ZERO;
|
||||
});
|
||||
audioIO->setOrientationGetter([]{
|
||||
auto avatarManager = DependencyManager::get<AvatarManager>();
|
||||
auto myAvatar = avatarManager ? avatarManager->getMyAvatar() : nullptr;
|
||||
return myAvatar ? myAvatar->getOrientationForAudio() : Quaternions::IDENTITY;
|
||||
});
|
||||
|
||||
return myAvatar ? myAvatar->getOrientationForAudio() : Quaternions::IDENTITY;
|
||||
});
|
||||
recording::Frame::registerFrameHandler(AudioConstants::getAudioFrameName(), [&audioIO](recording::Frame::ConstPointer frame) {
|
||||
audioIO->handleRecordedAudioInput(frame->data);
|
||||
});
|
||||
|
||||
recording::Frame::registerFrameHandler(AudioConstants::getAudioFrameName(), [=](recording::Frame::ConstPointer frame) {
|
||||
audioIO->handleRecordedAudioInput(frame->data);
|
||||
});
|
||||
|
||||
connect(audioIO.data(), &AudioClient::inputReceived, [](const QByteArray& audio){
|
||||
static auto recorder = DependencyManager::get<recording::Recorder>();
|
||||
if (recorder->isRecording()) {
|
||||
static const recording::FrameType AUDIO_FRAME_TYPE = recording::Frame::registerFrameType(AudioConstants::getAudioFrameName());
|
||||
recorder->recordFrame(AUDIO_FRAME_TYPE, audio);
|
||||
}
|
||||
});
|
||||
audioIO->startThread();
|
||||
connect(audioIO, &AudioClient::inputReceived, [](const QByteArray& audio) {
|
||||
static auto recorder = DependencyManager::get<recording::Recorder>();
|
||||
if (recorder->isRecording()) {
|
||||
static const recording::FrameType AUDIO_FRAME_TYPE = recording::Frame::registerFrameType(AudioConstants::getAudioFrameName());
|
||||
recorder->recordFrame(AUDIO_FRAME_TYPE, audio);
|
||||
}
|
||||
});
|
||||
audioIO->startThread();
|
||||
}
|
||||
|
||||
// Make sure we don't time out during slow operations at startup
|
||||
updateHeartbeat();
|
||||
|
@ -1275,27 +1278,29 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
// Inititalize sample before registering
|
||||
_sampleSound = DependencyManager::get<SoundCache>()->getSound(PathUtils::resourcesUrl("sounds/sample.wav"));
|
||||
|
||||
auto scriptEngines = DependencyManager::get<ScriptEngines>().data();
|
||||
scriptEngines->registerScriptInitializer([this](ScriptEnginePointer engine){
|
||||
registerScriptEngineWithApplicationServices(engine);
|
||||
});
|
||||
{
|
||||
auto scriptEngines = DependencyManager::get<ScriptEngines>().data();
|
||||
scriptEngines->registerScriptInitializer([this](ScriptEnginePointer engine) {
|
||||
registerScriptEngineWithApplicationServices(engine);
|
||||
});
|
||||
|
||||
connect(scriptEngines, &ScriptEngines::scriptCountChanged, scriptEngines, [this] {
|
||||
auto scriptEngines = DependencyManager::get<ScriptEngines>();
|
||||
if (scriptEngines->getRunningScripts().isEmpty()) {
|
||||
getMyAvatar()->clearScriptableSettings();
|
||||
}
|
||||
}, Qt::QueuedConnection);
|
||||
connect(scriptEngines, &ScriptEngines::scriptCountChanged, this, [this] {
|
||||
auto scriptEngines = DependencyManager::get<ScriptEngines>();
|
||||
if (scriptEngines->getRunningScripts().isEmpty()) {
|
||||
getMyAvatar()->clearScriptableSettings();
|
||||
}
|
||||
}, Qt::QueuedConnection);
|
||||
|
||||
connect(scriptEngines, &ScriptEngines::scriptsReloading, scriptEngines, [this] {
|
||||
getEntities()->reloadEntityScripts();
|
||||
loadAvatarScripts(getMyAvatar()->getScriptUrls());
|
||||
}, Qt::QueuedConnection);
|
||||
connect(scriptEngines, &ScriptEngines::scriptsReloading, this, [this] {
|
||||
getEntities()->reloadEntityScripts();
|
||||
loadAvatarScripts(getMyAvatar()->getScriptUrls());
|
||||
}, Qt::QueuedConnection);
|
||||
|
||||
connect(scriptEngines, &ScriptEngines::scriptLoadError,
|
||||
scriptEngines, [](const QString& filename, const QString& error){
|
||||
OffscreenUi::asyncWarning(nullptr, "Error Loading Script", filename + " failed to load.");
|
||||
}, Qt::QueuedConnection);
|
||||
connect(scriptEngines, &ScriptEngines::scriptLoadError,
|
||||
this, [](const QString& filename, const QString& error) {
|
||||
OffscreenUi::asyncWarning(nullptr, "Error Loading Script", filename + " failed to load.");
|
||||
}, Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
WSADATA WsaData;
|
||||
|
@ -1365,10 +1370,11 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
// so we defer the setup of the `scripting::Audio` class until this point
|
||||
{
|
||||
auto audioScriptingInterface = DependencyManager::set<AudioScriptingInterface, scripting::Audio>();
|
||||
connect(audioIO.data(), &AudioClient::mutedByMixer, audioScriptingInterface.data(), &AudioScriptingInterface::mutedByMixer);
|
||||
connect(audioIO.data(), &AudioClient::receivedFirstPacket, audioScriptingInterface.data(), &AudioScriptingInterface::receivedFirstPacket);
|
||||
connect(audioIO.data(), &AudioClient::disconnected, audioScriptingInterface.data(), &AudioScriptingInterface::disconnected);
|
||||
connect(audioIO.data(), &AudioClient::muteEnvironmentRequested, [](glm::vec3 position, float radius) {
|
||||
auto audioIO = DependencyManager::get<AudioClient>().data();
|
||||
connect(audioIO, &AudioClient::mutedByMixer, audioScriptingInterface.data(), &AudioScriptingInterface::mutedByMixer);
|
||||
connect(audioIO, &AudioClient::receivedFirstPacket, audioScriptingInterface.data(), &AudioScriptingInterface::receivedFirstPacket);
|
||||
connect(audioIO, &AudioClient::disconnected, audioScriptingInterface.data(), &AudioScriptingInterface::disconnected);
|
||||
connect(audioIO, &AudioClient::muteEnvironmentRequested, [](glm::vec3 position, float radius) {
|
||||
auto audioClient = DependencyManager::get<AudioClient>();
|
||||
auto audioScriptingInterface = DependencyManager::get<AudioScriptingInterface>();
|
||||
auto myAvatarPosition = DependencyManager::get<AvatarManager>()->getMyAvatar()->getWorldPosition();
|
||||
|
@ -1697,23 +1703,26 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
userInputMapper->registerDevice(_touchscreenVirtualPadDevice->getInputDevice());
|
||||
}
|
||||
|
||||
// this will force the model the look at the correct directory (weird order of operations issue)
|
||||
scriptEngines->reloadLocalFiles();
|
||||
{
|
||||
auto scriptEngines = DependencyManager::get<ScriptEngines>().data();
|
||||
// this will force the model the look at the correct directory (weird order of operations issue)
|
||||
scriptEngines->reloadLocalFiles();
|
||||
|
||||
// do this as late as possible so that all required subsystems are initialized
|
||||
// If we've overridden the default scripts location, just load default scripts
|
||||
// otherwise, load 'em all
|
||||
// do this as late as possible so that all required subsystems are initialized
|
||||
// If we've overridden the default scripts location, just load default scripts
|
||||
// otherwise, load 'em all
|
||||
|
||||
// we just want to see if --scripts was set, we've already parsed it and done
|
||||
// the change in PathUtils. Rather than pass that in the constructor, lets just
|
||||
// look (this could be debated)
|
||||
QString scriptsSwitch = QString("--").append(SCRIPTS_SWITCH);
|
||||
QDir defaultScriptsLocation(getCmdOption(argc, constArgv, scriptsSwitch.toStdString().c_str()));
|
||||
if (!defaultScriptsLocation.exists()) {
|
||||
scriptEngines->loadDefaultScripts();
|
||||
scriptEngines->defaultScriptsLocationOverridden(true);
|
||||
} else {
|
||||
scriptEngines->loadScripts();
|
||||
// we just want to see if --scripts was set, we've already parsed it and done
|
||||
// the change in PathUtils. Rather than pass that in the constructor, lets just
|
||||
// look (this could be debated)
|
||||
QString scriptsSwitch = QString("--").append(SCRIPTS_SWITCH);
|
||||
QDir defaultScriptsLocation(getCmdOption(argc, constArgv, scriptsSwitch.toStdString().c_str()));
|
||||
if (!defaultScriptsLocation.exists()) {
|
||||
scriptEngines->loadDefaultScripts();
|
||||
scriptEngines->defaultScriptsLocationOverridden(true);
|
||||
} else {
|
||||
scriptEngines->loadScripts();
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure we don't time out during slow operations at startup
|
||||
|
@ -1763,13 +1772,16 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
cameraMenuChanged();
|
||||
}
|
||||
|
||||
// set the local loopback interface for local sounds
|
||||
AudioInjector::setLocalAudioInterface(audioIO.data());
|
||||
auto audioScriptingInterface = DependencyManager::get<AudioScriptingInterface>();
|
||||
audioScriptingInterface->setLocalAudioInterface(audioIO.data());
|
||||
connect(audioIO.data(), &AudioClient::noiseGateOpened, audioScriptingInterface.data(), &AudioScriptingInterface::noiseGateOpened);
|
||||
connect(audioIO.data(), &AudioClient::noiseGateClosed, audioScriptingInterface.data(), &AudioScriptingInterface::noiseGateClosed);
|
||||
connect(audioIO.data(), &AudioClient::inputReceived, audioScriptingInterface.data(), &AudioScriptingInterface::inputReceived);
|
||||
{
|
||||
auto audioIO = DependencyManager::get<AudioClient>().data();
|
||||
// set the local loopback interface for local sounds
|
||||
AudioInjector::setLocalAudioInterface(audioIO);
|
||||
auto audioScriptingInterface = DependencyManager::get<AudioScriptingInterface>();
|
||||
audioScriptingInterface->setLocalAudioInterface(audioIO);
|
||||
connect(audioIO, &AudioClient::noiseGateOpened, audioScriptingInterface.data(), &AudioScriptingInterface::noiseGateOpened);
|
||||
connect(audioIO, &AudioClient::noiseGateClosed, audioScriptingInterface.data(), &AudioScriptingInterface::noiseGateClosed);
|
||||
connect(audioIO, &AudioClient::inputReceived, audioScriptingInterface.data(), &AudioScriptingInterface::inputReceived);
|
||||
}
|
||||
|
||||
this->installEventFilter(this);
|
||||
|
||||
|
@ -1826,13 +1838,13 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
}
|
||||
});
|
||||
|
||||
connect(entityScriptingInterface.data(), &EntityScriptingInterface::deletingEntity, [=](const EntityItemID& entityItemID) {
|
||||
connect(entityScriptingInterface.data(), &EntityScriptingInterface::deletingEntity, [this](const EntityItemID& entityItemID) {
|
||||
if (entityItemID == _keyboardFocusedEntity.get()) {
|
||||
setKeyboardFocusEntity(UNKNOWN_ENTITY_ID);
|
||||
}
|
||||
});
|
||||
|
||||
connect(getEntities()->getTree().get(), &EntityTree::deletingEntity, [=](const EntityItemID& entityItemID) {
|
||||
connect(getEntities()->getTree().get(), &EntityTree::deletingEntity, [](const EntityItemID& entityItemID) {
|
||||
auto avatarManager = DependencyManager::get<AvatarManager>();
|
||||
auto myAvatar = avatarManager ? avatarManager->getMyAvatar() : nullptr;
|
||||
if (myAvatar) {
|
||||
|
@ -1840,7 +1852,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
}
|
||||
});
|
||||
|
||||
EntityTree::setAddMaterialToEntityOperator([&](const QUuid& entityID, graphics::MaterialLayer material, const std::string& parentMaterialName) {
|
||||
EntityTree::setAddMaterialToEntityOperator([this](const QUuid& entityID, graphics::MaterialLayer material, const std::string& parentMaterialName) {
|
||||
// try to find the renderable
|
||||
auto renderable = getEntities()->renderableForEntityId(entityID);
|
||||
if (renderable) {
|
||||
|
@ -1855,7 +1867,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
}
|
||||
return false;
|
||||
});
|
||||
EntityTree::setRemoveMaterialFromEntityOperator([&](const QUuid& entityID, graphics::MaterialPointer material, const std::string& parentMaterialName) {
|
||||
EntityTree::setRemoveMaterialFromEntityOperator([this](const QUuid& entityID, graphics::MaterialPointer material, const std::string& parentMaterialName) {
|
||||
// try to find the renderable
|
||||
auto renderable = getEntities()->renderableForEntityId(entityID);
|
||||
if (renderable) {
|
||||
|
@ -1890,7 +1902,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
return false;
|
||||
});
|
||||
|
||||
EntityTree::setAddMaterialToOverlayOperator([&](const QUuid& overlayID, graphics::MaterialLayer material, const std::string& parentMaterialName) {
|
||||
EntityTree::setAddMaterialToOverlayOperator([this](const QUuid& overlayID, graphics::MaterialLayer material, const std::string& parentMaterialName) {
|
||||
auto overlay = _overlays.getOverlay(overlayID);
|
||||
if (overlay) {
|
||||
overlay->addMaterial(material, parentMaterialName);
|
||||
|
@ -1898,7 +1910,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
}
|
||||
return false;
|
||||
});
|
||||
EntityTree::setRemoveMaterialFromOverlayOperator([&](const QUuid& overlayID, graphics::MaterialPointer material, const std::string& parentMaterialName) {
|
||||
EntityTree::setRemoveMaterialFromOverlayOperator([this](const QUuid& overlayID, graphics::MaterialPointer material, const std::string& parentMaterialName) {
|
||||
auto overlay = _overlays.getOverlay(overlayID);
|
||||
if (overlay) {
|
||||
overlay->removeMaterial(material, parentMaterialName);
|
||||
|
@ -1909,13 +1921,13 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
|
||||
// Keyboard focus handling for Web overlays.
|
||||
auto overlays = &(qApp->getOverlays());
|
||||
connect(overlays, &Overlays::overlayDeleted, [=](const OverlayID& overlayID) {
|
||||
connect(overlays, &Overlays::overlayDeleted, [this](const OverlayID& overlayID) {
|
||||
if (overlayID == _keyboardFocusedOverlay.get()) {
|
||||
setKeyboardFocusOverlay(UNKNOWN_OVERLAY_ID);
|
||||
}
|
||||
});
|
||||
|
||||
connect(this, &Application::aboutToQuit, [=]() {
|
||||
connect(this, &Application::aboutToQuit, [this]() {
|
||||
setKeyboardFocusOverlay(UNKNOWN_OVERLAY_ID);
|
||||
setKeyboardFocusEntity(UNKNOWN_ENTITY_ID);
|
||||
});
|
||||
|
@ -2184,23 +2196,22 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
QVariant testProperty = property(hifi::properties::TEST);
|
||||
qDebug() << testProperty;
|
||||
if (testProperty.isValid()) {
|
||||
auto scriptEngines = DependencyManager::get<ScriptEngines>();
|
||||
const auto testScript = property(hifi::properties::TEST).toUrl();
|
||||
|
||||
// Set last parameter to exit interface when the test script finishes, if so requested
|
||||
scriptEngines->loadScript(testScript, false, false, false, false, quitWhenFinished);
|
||||
DependencyManager::get<ScriptEngines>()->loadScript(testScript, false, false, false, false, quitWhenFinished);
|
||||
|
||||
// This is done so we don't get a "connection time-out" message when we haven't passed in a URL.
|
||||
if (arguments().contains("--url")) {
|
||||
auto reply = SandboxUtils::getStatus();
|
||||
connect(reply, &QNetworkReply::finished, this, [=] {
|
||||
connect(reply, &QNetworkReply::finished, this, [this, reply] {
|
||||
handleSandboxStatus(reply);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
PROFILE_RANGE(render, "GetSandboxStatus");
|
||||
auto reply = SandboxUtils::getStatus();
|
||||
connect(reply, &QNetworkReply::finished, this, [=] {
|
||||
connect(reply, &QNetworkReply::finished, this, [this, reply] {
|
||||
handleSandboxStatus(reply);
|
||||
});
|
||||
}
|
||||
|
@ -2227,8 +2238,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
|
||||
connect(&_myCamera, &Camera::modeUpdated, this, &Application::cameraModeChanged);
|
||||
|
||||
DependencyManager::get<PickManager>()->setShouldPickHUDOperator([&]() { return DependencyManager::get<HMDScriptingInterface>()->isHMDMode(); });
|
||||
DependencyManager::get<PickManager>()->setCalculatePos2DFromHUDOperator([&](const glm::vec3& intersection) {
|
||||
DependencyManager::get<PickManager>()->setShouldPickHUDOperator([]() { return DependencyManager::get<HMDScriptingInterface>()->isHMDMode(); });
|
||||
DependencyManager::get<PickManager>()->setCalculatePos2DFromHUDOperator([this](const glm::vec3& intersection) {
|
||||
const glm::vec2 MARGIN(25.0f);
|
||||
glm::vec2 maxPos = _controllerScriptingInterface->getViewportDimensions() - MARGIN;
|
||||
glm::vec2 pos2D = DependencyManager::get<HMDScriptingInterface>()->overlayFromWorldPoint(intersection);
|
||||
|
@ -2238,7 +2249,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
// Setup the mouse ray pick and related operators
|
||||
DependencyManager::get<EntityTreeRenderer>()->setMouseRayPickID(DependencyManager::get<PickManager>()->addPick(PickQuery::Ray, std::make_shared<MouseRayPick>(
|
||||
PickFilter(PickScriptingInterface::PICK_ENTITIES() | PickScriptingInterface::PICK_INCLUDE_NONCOLLIDABLE()), 0.0f, true)));
|
||||
DependencyManager::get<EntityTreeRenderer>()->setMouseRayPickResultOperator([&](unsigned int rayPickID) {
|
||||
DependencyManager::get<EntityTreeRenderer>()->setMouseRayPickResultOperator([](unsigned int rayPickID) {
|
||||
RayToEntityIntersectionResult entityResult;
|
||||
entityResult.intersects = false;
|
||||
auto pickResult = DependencyManager::get<PickManager>()->getPrevPickResultTyped<RayPickResult>(rayPickID);
|
||||
|
@ -2254,7 +2265,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
}
|
||||
return entityResult;
|
||||
});
|
||||
DependencyManager::get<EntityTreeRenderer>()->setSetPrecisionPickingOperator([&](unsigned int rayPickID, bool value) {
|
||||
DependencyManager::get<EntityTreeRenderer>()->setSetPrecisionPickingOperator([](unsigned int rayPickID, bool value) {
|
||||
DependencyManager::get<PickManager>()->setPrecisionPicking(rayPickID, value);
|
||||
});
|
||||
|
||||
|
@ -2453,21 +2464,35 @@ void Application::cleanupBeforeQuit() {
|
|||
_keyboardFocusHighlight = nullptr;
|
||||
}
|
||||
|
||||
auto nodeList = DependencyManager::get<NodeList>();
|
||||
{
|
||||
auto nodeList = DependencyManager::get<NodeList>();
|
||||
|
||||
// send the domain a disconnect packet, force stoppage of domain-server check-ins
|
||||
nodeList->getDomainHandler().disconnect();
|
||||
nodeList->setIsShuttingDown(true);
|
||||
// send the domain a disconnect packet, force stoppage of domain-server check-ins
|
||||
nodeList->getDomainHandler().disconnect();
|
||||
nodeList->setIsShuttingDown(true);
|
||||
|
||||
// tell the packet receiver we're shutting down, so it can drop packets
|
||||
nodeList->getPacketReceiver().setShouldDropPackets(true);
|
||||
// tell the packet receiver we're shutting down, so it can drop packets
|
||||
nodeList->getPacketReceiver().setShouldDropPackets(true);
|
||||
}
|
||||
|
||||
getEntities()->shutdown(); // tell the entities system we're shutting down, so it will stop running scripts
|
||||
|
||||
// Clear any queued processing (I/O, FBX/OBJ/Texture parsing)
|
||||
QThreadPool::globalInstance()->clear();
|
||||
|
||||
DependencyManager::destroy<RecordingScriptingInterface>();
|
||||
|
||||
// FIXME: Something is still holding on to the ScriptEnginePointers contained in ScriptEngines, and they hold backpointers to ScriptEngines,
|
||||
// so this doesn't shut down properly
|
||||
DependencyManager::get<ScriptEngines>()->shutdownScripting(); // stop all currently running global scripts
|
||||
// These classes hold ScriptEnginePointers, so they must be destroyed before ScriptEngines
|
||||
// Must be done after shutdownScripting in case any scripts try to access these things
|
||||
{
|
||||
DependencyManager::destroy<StandAloneJSConsole>();
|
||||
EntityTreePointer tree = getEntities()->getTree();
|
||||
tree->setSimulation(nullptr);
|
||||
DependencyManager::destroy<EntityTreeRenderer>();
|
||||
}
|
||||
DependencyManager::destroy<ScriptEngines>();
|
||||
|
||||
_displayPlugin.reset();
|
||||
|
@ -2504,6 +2529,8 @@ void Application::cleanupBeforeQuit() {
|
|||
DependencyManager::destroy<EyeTracker>();
|
||||
#endif
|
||||
|
||||
DependencyManager::destroy<ContextOverlayInterface>(); // Must be destroyed before TabletScriptingInterface
|
||||
|
||||
// stop QML
|
||||
DependencyManager::destroy<TabletScriptingInterface>();
|
||||
DependencyManager::destroy<ToolbarScriptingInterface>();
|
||||
|
@ -2515,10 +2542,6 @@ void Application::cleanupBeforeQuit() {
|
|||
_snapshotSoundInjector->stop();
|
||||
}
|
||||
|
||||
// FIXME: something else is holding a reference to AudioClient,
|
||||
// so it must be explicitly synchronously stopped here
|
||||
DependencyManager::get<AudioClient>()->cleanupBeforeQuit();
|
||||
|
||||
// destroy Audio so it and its threads have a chance to go down safely
|
||||
// this must happen after QML, as there are unexplained audio crashes originating in qtwebengine
|
||||
DependencyManager::destroy<AudioClient>();
|
||||
|
@ -2558,9 +2581,6 @@ Application::~Application() {
|
|||
_entityClipboard->eraseAllOctreeElements();
|
||||
_entityClipboard.reset();
|
||||
|
||||
EntityTreePointer tree = getEntities()->getTree();
|
||||
tree->setSimulation(nullptr);
|
||||
|
||||
_octreeProcessor.terminate();
|
||||
_entityEditSender.terminate();
|
||||
|
||||
|
@ -3274,8 +3294,7 @@ void Application::showHelp() {
|
|||
QUrlQuery queryString;
|
||||
queryString.addQueryItem("handControllerName", handControllerName);
|
||||
queryString.addQueryItem("defaultTab", defaultTab);
|
||||
auto tabletScriptingInterface = DependencyManager::get<TabletScriptingInterface>();
|
||||
TabletProxy* tablet = dynamic_cast<TabletProxy*>(tabletScriptingInterface->getTablet(SYSTEM_TABLET));
|
||||
TabletProxy* tablet = dynamic_cast<TabletProxy*>(DependencyManager::get<TabletScriptingInterface>()->getTablet(SYSTEM_TABLET));
|
||||
tablet->gotoWebScreen(PathUtils::resourcesUrl() + INFO_HELP_PATH + "?" + queryString.toString());
|
||||
DependencyManager::get<HMDScriptingInterface>()->openTablet();
|
||||
//InfoView::show(INFO_HELP_PATH, false, queryString.toString());
|
||||
|
@ -3588,6 +3607,10 @@ static void dumpEventQueue(QThread* thread) {
|
|||
|
||||
bool Application::event(QEvent* event) {
|
||||
|
||||
if (_aboutToQuit) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!Menu::getInstance()) {
|
||||
return false;
|
||||
}
|
||||
|
@ -3992,10 +4015,6 @@ void Application::maybeToggleMenuVisible(QMouseEvent* event) const {
|
|||
void Application::mouseMoveEvent(QMouseEvent* event) {
|
||||
PROFILE_RANGE(app_input_mouse, __FUNCTION__);
|
||||
|
||||
if (_aboutToQuit) {
|
||||
return;
|
||||
}
|
||||
|
||||
maybeToggleMenuVisible(event);
|
||||
|
||||
auto& compositor = getApplicationCompositor();
|
||||
|
@ -4060,11 +4079,9 @@ void Application::mousePressEvent(QMouseEvent* event) {
|
|||
event->screenPos(), event->button(),
|
||||
event->buttons(), event->modifiers());
|
||||
|
||||
if (!_aboutToQuit) {
|
||||
getOverlays().mousePressEvent(&mappedEvent);
|
||||
if (!_controllerScriptingInterface->areEntityClicksCaptured()) {
|
||||
getEntities()->mousePressEvent(&mappedEvent);
|
||||
}
|
||||
getOverlays().mousePressEvent(&mappedEvent);
|
||||
if (!_controllerScriptingInterface->areEntityClicksCaptured()) {
|
||||
getEntities()->mousePressEvent(&mappedEvent);
|
||||
}
|
||||
|
||||
_controllerScriptingInterface->emitMousePressEvent(&mappedEvent); // send events to any registered scripts
|
||||
|
@ -4101,14 +4118,11 @@ void Application::mouseDoublePressEvent(QMouseEvent* event) {
|
|||
event->screenPos(), event->button(),
|
||||
event->buttons(), event->modifiers());
|
||||
|
||||
if (!_aboutToQuit) {
|
||||
getOverlays().mouseDoublePressEvent(&mappedEvent);
|
||||
if (!_controllerScriptingInterface->areEntityClicksCaptured()) {
|
||||
getEntities()->mouseDoublePressEvent(&mappedEvent);
|
||||
}
|
||||
getOverlays().mouseDoublePressEvent(&mappedEvent);
|
||||
if (!_controllerScriptingInterface->areEntityClicksCaptured()) {
|
||||
getEntities()->mouseDoublePressEvent(&mappedEvent);
|
||||
}
|
||||
|
||||
|
||||
// if one of our scripts have asked to capture this event, then stop processing it
|
||||
if (_controllerScriptingInterface->isMouseCaptured()) {
|
||||
return;
|
||||
|
@ -4127,10 +4141,8 @@ void Application::mouseReleaseEvent(QMouseEvent* event) {
|
|||
event->screenPos(), event->button(),
|
||||
event->buttons(), event->modifiers());
|
||||
|
||||
if (!_aboutToQuit) {
|
||||
getOverlays().mouseReleaseEvent(&mappedEvent);
|
||||
getEntities()->mouseReleaseEvent(&mappedEvent);
|
||||
}
|
||||
getOverlays().mouseReleaseEvent(&mappedEvent);
|
||||
getEntities()->mouseReleaseEvent(&mappedEvent);
|
||||
|
||||
_controllerScriptingInterface->emitMouseReleaseEvent(&mappedEvent); // send events to any registered scripts
|
||||
|
||||
|
@ -4281,7 +4293,6 @@ bool Application::shouldPaint() const {
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
auto displayPlugin = getActiveDisplayPlugin();
|
||||
|
||||
#ifdef DEBUG_PAINT_DELAY
|
||||
|
@ -4761,7 +4772,7 @@ bool Application::exportEntities(const QString& filename,
|
|||
exportTree->createRootElement();
|
||||
glm::vec3 root(TREE_SCALE, TREE_SCALE, TREE_SCALE);
|
||||
bool success = true;
|
||||
entityTree->withReadLock([&] {
|
||||
entityTree->withReadLock([entityIDs, entityTree, givenOffset, myAvatarID, &root, &entities, &success, &exportTree] {
|
||||
for (auto entityID : entityIDs) { // Gather entities and properties.
|
||||
auto entityItem = entityTree->findEntityByEntityItemID(entityID);
|
||||
if (!entityItem) {
|
||||
|
@ -5510,6 +5521,10 @@ static bool domainLoadingInProgress = false;
|
|||
void Application::update(float deltaTime) {
|
||||
PROFILE_RANGE_EX(app, __FUNCTION__, 0xffff0000, (uint64_t)_renderFrameCount + 1);
|
||||
|
||||
if (_aboutToQuit) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_physicsEnabled) {
|
||||
if (!domainLoadingInProgress) {
|
||||
PROFILE_ASYNC_BEGIN(app, "Scene Loading", "");
|
||||
|
@ -5778,15 +5793,13 @@ void Application::update(float deltaTime) {
|
|||
_entitySimulation->handleDeactivatedMotionStates(deactivations);
|
||||
});
|
||||
|
||||
if (!_aboutToQuit) {
|
||||
// handleCollisionEvents() AFTER handleChangedMotionStates()
|
||||
{
|
||||
PROFILE_RANGE(simulation_physics, "CollisionEvents");
|
||||
avatarManager->handleCollisionEvents(collisionEvents);
|
||||
// Collision events (and their scripts) must not be handled when we're locked, above. (That would risk
|
||||
// deadlock.)
|
||||
_entitySimulation->handleCollisionEvents(collisionEvents);
|
||||
}
|
||||
// handleCollisionEvents() AFTER handleChangedMotionStates()
|
||||
{
|
||||
PROFILE_RANGE(simulation_physics, "CollisionEvents");
|
||||
avatarManager->handleCollisionEvents(collisionEvents);
|
||||
// Collision events (and their scripts) must not be handled when we're locked, above. (That would risk
|
||||
// deadlock.)
|
||||
_entitySimulation->handleCollisionEvents(collisionEvents);
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -5804,11 +5817,9 @@ void Application::update(float deltaTime) {
|
|||
}
|
||||
auto t4 = std::chrono::high_resolution_clock::now();
|
||||
|
||||
if (!_aboutToQuit) {
|
||||
// NOTE: the getEntities()->update() call below will wait for lock
|
||||
// and will provide non-physical entity motion
|
||||
getEntities()->update(true); // update the models...
|
||||
}
|
||||
// NOTE: the getEntities()->update() call below will wait for lock
|
||||
// and will provide non-physical entity motion
|
||||
getEntities()->update(true); // update the models...
|
||||
|
||||
auto t5 = std::chrono::high_resolution_clock::now();
|
||||
|
||||
|
@ -6374,7 +6385,6 @@ void Application::domainURLChanged(QUrl domainURL) {
|
|||
void Application::resettingDomain() {
|
||||
_notifiedPacketVersionMismatchThisDomain = false;
|
||||
|
||||
auto nodeList = DependencyManager::get<NodeList>();
|
||||
clearDomainOctreeDetails();
|
||||
}
|
||||
|
||||
|
@ -6729,16 +6739,12 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEnginePointe
|
|||
pickScriptingInterface->registerMetaTypes(scriptEngine.data());
|
||||
|
||||
// connect this script engines printedMessage signal to the global ScriptEngines these various messages
|
||||
connect(scriptEngine.data(), &ScriptEngine::printedMessage,
|
||||
DependencyManager::get<ScriptEngines>().data(), &ScriptEngines::onPrintedMessage);
|
||||
connect(scriptEngine.data(), &ScriptEngine::errorMessage,
|
||||
DependencyManager::get<ScriptEngines>().data(), &ScriptEngines::onErrorMessage);
|
||||
connect(scriptEngine.data(), &ScriptEngine::warningMessage,
|
||||
DependencyManager::get<ScriptEngines>().data(), &ScriptEngines::onWarningMessage);
|
||||
connect(scriptEngine.data(), &ScriptEngine::infoMessage,
|
||||
DependencyManager::get<ScriptEngines>().data(), &ScriptEngines::onInfoMessage);
|
||||
connect(scriptEngine.data(), &ScriptEngine::clearDebugWindow,
|
||||
DependencyManager::get<ScriptEngines>().data(), &ScriptEngines::onClearDebugWindow);
|
||||
auto scriptEngines = DependencyManager::get<ScriptEngines>().data();
|
||||
connect(scriptEngine.data(), &ScriptEngine::printedMessage, scriptEngines, &ScriptEngines::onPrintedMessage);
|
||||
connect(scriptEngine.data(), &ScriptEngine::errorMessage, scriptEngines, &ScriptEngines::onErrorMessage);
|
||||
connect(scriptEngine.data(), &ScriptEngine::warningMessage, scriptEngines, &ScriptEngines::onWarningMessage);
|
||||
connect(scriptEngine.data(), &ScriptEngine::infoMessage, scriptEngines, &ScriptEngines::onInfoMessage);
|
||||
connect(scriptEngine.data(), &ScriptEngine::clearDebugWindow, scriptEngines, &ScriptEngines::onClearDebugWindow);
|
||||
|
||||
}
|
||||
|
||||
|
@ -7046,10 +7052,9 @@ void Application::showDialog(const QUrl& widgetUrl, const QUrl& tabletUrl, const
|
|||
}
|
||||
|
||||
void Application::showScriptLogs() {
|
||||
auto scriptEngines = DependencyManager::get<ScriptEngines>();
|
||||
QUrl defaultScriptsLoc = PathUtils::defaultScriptsLocation();
|
||||
defaultScriptsLoc.setPath(defaultScriptsLoc.path() + "developer/debugging/debugWindow.js");
|
||||
scriptEngines->loadScript(defaultScriptsLoc.toString());
|
||||
DependencyManager::get<ScriptEngines>()->loadScript(defaultScriptsLoc.toString());
|
||||
}
|
||||
|
||||
void Application::showAssetServerWidget(QString filePath) {
|
||||
|
@ -7615,7 +7620,6 @@ void Application::openUrl(const QUrl& url) const {
|
|||
}
|
||||
|
||||
void Application::loadDialog() {
|
||||
auto scriptEngines = DependencyManager::get<ScriptEngines>();
|
||||
ModalDialogListener* dlg = OffscreenUi::getOpenFileNameAsync(_glWidget, tr("Open Script"),
|
||||
getPreviousScriptLocation(),
|
||||
tr("JavaScript Files (*.js)"));
|
||||
|
|
|
@ -64,7 +64,7 @@ void addAvatarEntities(const QVariantList& avatarEntities) {
|
|||
|
||||
EntityItemID id = EntityItemID(QUuid::createUuid());
|
||||
bool success = true;
|
||||
entityTree->withWriteLock([&] {
|
||||
entityTree->withWriteLock([&entityTree, id, &entityProperties, &success] {
|
||||
EntityItemPointer entity = entityTree->addEntity(id, entityProperties);
|
||||
if (entity) {
|
||||
if (entityProperties.queryAACubeRelatedPropertyChanged()) {
|
||||
|
|
|
@ -147,9 +147,11 @@ Menu::Menu() {
|
|||
auto assetServerAction = addActionToQMenuAndActionHash(editMenu, MenuOption::AssetServer,
|
||||
Qt::CTRL | Qt::SHIFT | Qt::Key_A,
|
||||
qApp, SLOT(showAssetServerWidget()));
|
||||
auto nodeList = DependencyManager::get<NodeList>();
|
||||
QObject::connect(nodeList.data(), &NodeList::canWriteAssetsChanged, assetServerAction, &QAction::setEnabled);
|
||||
assetServerAction->setEnabled(nodeList->getThisNodeCanWriteAssets());
|
||||
{
|
||||
auto nodeList = DependencyManager::get<NodeList>();
|
||||
QObject::connect(nodeList.data(), &NodeList::canWriteAssetsChanged, assetServerAction, &QAction::setEnabled);
|
||||
assetServerAction->setEnabled(nodeList->getThisNodeCanWriteAssets());
|
||||
}
|
||||
|
||||
// Edit > Package Model as .fst...
|
||||
addActionToQMenuAndActionHash(editMenu, MenuOption::PackageModel, 0,
|
||||
|
@ -620,8 +622,11 @@ Menu::Menu() {
|
|||
addCheckableActionToQMenuAndActionHash(networkMenu, MenuOption::SendWrongProtocolVersion, 0, false,
|
||||
qApp, SLOT(sendWrongProtocolVersionsSignature(bool)));
|
||||
|
||||
addCheckableActionToQMenuAndActionHash(networkMenu, MenuOption::SendWrongDSConnectVersion, 0, false,
|
||||
nodeList.data(), SLOT(toggleSendNewerDSConnectVersion(bool)));
|
||||
{
|
||||
auto nodeList = DependencyManager::get<NodeList>();
|
||||
addCheckableActionToQMenuAndActionHash(networkMenu, MenuOption::SendWrongDSConnectVersion, 0, false,
|
||||
nodeList.data(), SLOT(toggleSendNewerDSConnectVersion(bool)));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -655,10 +660,9 @@ Menu::Menu() {
|
|||
|
||||
action = addActionToQMenuAndActionHash(audioDebugMenu, "Stats...");
|
||||
connect(action, &QAction::triggered, [] {
|
||||
auto scriptEngines = DependencyManager::get<ScriptEngines>();
|
||||
QUrl defaultScriptsLoc = PathUtils::defaultScriptsLocation();
|
||||
defaultScriptsLoc.setPath(defaultScriptsLoc.path() + "developer/utilities/audio/stats.js");
|
||||
scriptEngines->loadScript(defaultScriptsLoc.toString());
|
||||
DependencyManager::get<ScriptEngines>()->loadScript(defaultScriptsLoc.toString());
|
||||
});
|
||||
|
||||
action = addActionToQMenuAndActionHash(audioDebugMenu, "Buffers...");
|
||||
|
@ -667,16 +671,14 @@ Menu::Menu() {
|
|||
QString("hifi/tablet/TabletAudioBuffers.qml"), "AudioBuffersDialog");
|
||||
});
|
||||
|
||||
auto audioIO = DependencyManager::get<AudioClient>();
|
||||
addActionToQMenuAndActionHash(audioDebugMenu, MenuOption::MuteEnvironment, 0,
|
||||
audioIO.data(), SLOT(sendMuteEnvironmentPacket()));
|
||||
DependencyManager::get<AudioClient>().data(), SLOT(sendMuteEnvironmentPacket()));
|
||||
|
||||
action = addActionToQMenuAndActionHash(audioDebugMenu, MenuOption::AudioScope);
|
||||
connect(action, &QAction::triggered, [] {
|
||||
auto scriptEngines = DependencyManager::get<ScriptEngines>();
|
||||
QUrl defaultScriptsLoc = PathUtils::defaultScriptsLocation();
|
||||
defaultScriptsLoc.setPath(defaultScriptsLoc.path() + "developer/utilities/audio/audioScope.js");
|
||||
scriptEngines->loadScript(defaultScriptsLoc.toString());
|
||||
DependencyManager::get<ScriptEngines>()->loadScript(defaultScriptsLoc.toString());
|
||||
});
|
||||
|
||||
// Developer > Physics >>>
|
||||
|
@ -756,10 +758,9 @@ Menu::Menu() {
|
|||
// Developer > API Debugger
|
||||
action = addActionToQMenuAndActionHash(developerMenu, "API Debugger");
|
||||
connect(action, &QAction::triggered, [] {
|
||||
auto scriptEngines = DependencyManager::get<ScriptEngines>();
|
||||
QUrl defaultScriptsLoc = PathUtils::defaultScriptsLocation();
|
||||
defaultScriptsLoc.setPath(defaultScriptsLoc.path() + "developer/utilities/tools/currentAPI.js");
|
||||
scriptEngines->loadScript(defaultScriptsLoc.toString());
|
||||
DependencyManager::get<ScriptEngines>()->loadScript(defaultScriptsLoc.toString());
|
||||
});
|
||||
|
||||
// Developer > Log...
|
||||
|
@ -767,11 +768,14 @@ Menu::Menu() {
|
|||
qApp, SLOT(toggleLogDialog()));
|
||||
auto essLogAction = addActionToQMenuAndActionHash(developerMenu, MenuOption::EntityScriptServerLog, 0,
|
||||
qApp, SLOT(toggleEntityScriptServerLogDialog()));
|
||||
QObject::connect(nodeList.data(), &NodeList::canRezChanged, essLogAction, [essLogAction] {
|
||||
{
|
||||
auto nodeList = DependencyManager::get<NodeList>();
|
||||
QObject::connect(nodeList.data(), &NodeList::canRezChanged, essLogAction, [essLogAction] {
|
||||
auto nodeList = DependencyManager::get<NodeList>();
|
||||
essLogAction->setEnabled(nodeList->getThisNodeCanRez());
|
||||
});
|
||||
essLogAction->setEnabled(nodeList->getThisNodeCanRez());
|
||||
});
|
||||
essLogAction->setEnabled(nodeList->getThisNodeCanRez());
|
||||
}
|
||||
|
||||
addActionToQMenuAndActionHash(developerMenu, "Script Log (HMD friendly)...", Qt::NoButton,
|
||||
qApp, SLOT(showScriptLogs()));
|
||||
|
|
|
@ -79,7 +79,7 @@ AvatarManager::AvatarManager(QObject* parent) :
|
|||
|
||||
// when we hear that the user has ignored an avatar by session UUID
|
||||
// immediately remove that avatar instead of waiting for the absence of packets from avatar mixer
|
||||
connect(nodeList.data(), &NodeList::ignoredNode, this, [=](const QUuid& nodeID, bool enabled) {
|
||||
connect(nodeList.data(), &NodeList::ignoredNode, this, [this](const QUuid& nodeID, bool enabled) {
|
||||
if (enabled) {
|
||||
removeAvatar(nodeID, KillAvatarReason::AvatarIgnored);
|
||||
}
|
||||
|
@ -318,16 +318,21 @@ void AvatarManager::postUpdate(float deltaTime, const render::ScenePointer& scen
|
|||
|
||||
void AvatarManager::sendIdentityRequest(const QUuid& avatarID) const {
|
||||
auto nodeList = DependencyManager::get<NodeList>();
|
||||
QWeakPointer<NodeList> nodeListWeak = nodeList;
|
||||
nodeList->eachMatchingNode(
|
||||
[&](const SharedNodePointer& node)->bool {
|
||||
return node->getType() == NodeType::AvatarMixer && node->getActiveSocket();
|
||||
},
|
||||
[&](const SharedNodePointer& node) {
|
||||
auto packet = NLPacket::create(PacketType::AvatarIdentityRequest, NUM_BYTES_RFC4122_UUID, true);
|
||||
packet->write(avatarID.toRfc4122());
|
||||
nodeList->sendPacket(std::move(packet), *node);
|
||||
++_identityRequestsSent;
|
||||
});
|
||||
[](const SharedNodePointer& node)->bool {
|
||||
return node->getType() == NodeType::AvatarMixer && node->getActiveSocket();
|
||||
},
|
||||
[this, avatarID, nodeListWeak](const SharedNodePointer& node) {
|
||||
auto nodeList = nodeListWeak.lock();
|
||||
if (nodeList) {
|
||||
auto packet = NLPacket::create(PacketType::AvatarIdentityRequest, NUM_BYTES_RFC4122_UUID, true);
|
||||
packet->write(avatarID.toRfc4122());
|
||||
nodeList->sendPacket(std::move(packet), *node);
|
||||
++_identityRequestsSent;
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
void AvatarManager::simulateAvatarFades(float deltaTime) {
|
||||
|
|
|
@ -498,14 +498,14 @@ void MyAvatar::update(float deltaTime) {
|
|||
// Get audio loudness data from audio input device
|
||||
// Also get the AudioClient so we can update the avatar bounding box data
|
||||
// on the AudioClient side.
|
||||
auto audio = DependencyManager::get<AudioClient>();
|
||||
auto audio = DependencyManager::get<AudioClient>().data();
|
||||
setAudioLoudness(audio->getLastInputLoudness());
|
||||
setAudioAverageLoudness(audio->getAudioAverageInputLoudness());
|
||||
|
||||
glm::vec3 halfBoundingBoxDimensions(_characterController.getCapsuleRadius(), _characterController.getCapsuleHalfHeight(), _characterController.getCapsuleRadius());
|
||||
// This might not be right! Isn't the capsule local offset in avatar space? -HRS 5/26/17
|
||||
halfBoundingBoxDimensions += _characterController.getCapsuleLocalOffset();
|
||||
QMetaObject::invokeMethod(audio.data(), "setAvatarBoundingBoxParameters",
|
||||
QMetaObject::invokeMethod(audio, "setAvatarBoundingBoxParameters",
|
||||
Q_ARG(glm::vec3, (getWorldPosition() - halfBoundingBoxDimensions)),
|
||||
Q_ARG(glm::vec3, (halfBoundingBoxDimensions*2.0f)));
|
||||
|
||||
|
|
|
@ -352,8 +352,7 @@ bool QmlCommerce::openApp(const QString& itemHref) {
|
|||
QJsonObject appFileJsonObject = appFileJsonDocument.object();
|
||||
QString homeUrl = appFileJsonObject["homeURL"].toString();
|
||||
|
||||
auto tabletScriptingInterface = DependencyManager::get<TabletScriptingInterface>();
|
||||
auto tablet = dynamic_cast<TabletProxy*>(tabletScriptingInterface->getTablet("com.highfidelity.interface.tablet.system"));
|
||||
auto tablet = dynamic_cast<TabletProxy*>(DependencyManager::get<TabletScriptingInterface>()->getTablet("com.highfidelity.interface.tablet.system"));
|
||||
if (homeUrl.contains(".qml", Qt::CaseInsensitive)) {
|
||||
tablet->loadQMLSource(homeUrl);
|
||||
} else if (homeUrl.contains(".html", Qt::CaseInsensitive)) {
|
||||
|
|
|
@ -328,7 +328,7 @@ Wallet::Wallet() {
|
|||
packetReceiver.registerListener(PacketType::ChallengeOwnership, this, "handleChallengeOwnershipPacket");
|
||||
packetReceiver.registerListener(PacketType::ChallengeOwnershipRequest, this, "handleChallengeOwnershipPacket");
|
||||
|
||||
connect(ledger.data(), &Ledger::accountResult, this, [&](QJsonObject result) {
|
||||
connect(ledger.data(), &Ledger::accountResult, this, [](QJsonObject result) {
|
||||
auto wallet = DependencyManager::get<Wallet>();
|
||||
auto walletScriptingInterface = DependencyManager::get<WalletScriptingInterface>();
|
||||
uint status;
|
||||
|
|
|
@ -60,23 +60,20 @@ Audio::Audio() : _devices(_contextIsHMD) {
|
|||
}
|
||||
|
||||
bool Audio::startRecording(const QString& filepath) {
|
||||
auto client = DependencyManager::get<AudioClient>().data();
|
||||
return resultWithWriteLock<bool>([&] {
|
||||
return client->startRecording(filepath);
|
||||
return DependencyManager::get<AudioClient>()->startRecording(filepath);
|
||||
});
|
||||
}
|
||||
|
||||
bool Audio::getRecording() {
|
||||
auto client = DependencyManager::get<AudioClient>().data();
|
||||
return resultWithReadLock<bool>([&] {
|
||||
return client->getRecording();
|
||||
return DependencyManager::get<AudioClient>()->getRecording();
|
||||
});
|
||||
}
|
||||
|
||||
void Audio::stopRecording() {
|
||||
auto client = DependencyManager::get<AudioClient>().data();
|
||||
withWriteLock([&] {
|
||||
client->stopRecording();
|
||||
DependencyManager::get<AudioClient>()->stopRecording();
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -360,11 +360,11 @@ void AudioInputDeviceList::onPeakValueListChanged(const QList<float>& peakValueL
|
|||
}
|
||||
|
||||
AudioDevices::AudioDevices(bool& contextIsHMD) : _contextIsHMD(contextIsHMD) {
|
||||
auto client = DependencyManager::get<AudioClient>();
|
||||
auto client = DependencyManager::get<AudioClient>().data();
|
||||
|
||||
connect(client.data(), &AudioClient::deviceChanged, this, &AudioDevices::onDeviceChanged, Qt::QueuedConnection);
|
||||
connect(client.data(), &AudioClient::devicesChanged, this, &AudioDevices::onDevicesChanged, Qt::QueuedConnection);
|
||||
connect(client.data(), &AudioClient::peakValueListChanged, &_inputs, &AudioInputDeviceList::onPeakValueListChanged, Qt::QueuedConnection);
|
||||
connect(client, &AudioClient::deviceChanged, this, &AudioDevices::onDeviceChanged, Qt::QueuedConnection);
|
||||
connect(client, &AudioClient::devicesChanged, this, &AudioDevices::onDevicesChanged, Qt::QueuedConnection);
|
||||
connect(client, &AudioClient::peakValueListChanged, &_inputs, &AudioInputDeviceList::onPeakValueListChanged, Qt::QueuedConnection);
|
||||
|
||||
_inputs.onDeviceChanged(client->getActiveAudioDevice(QAudio::AudioInput), contextIsHMD);
|
||||
_outputs.onDeviceChanged(client->getActiveAudioDevice(QAudio::AudioOutput), contextIsHMD);
|
||||
|
@ -446,7 +446,7 @@ void AudioDevices::onDevicesChanged(QAudio::Mode mode, const QList<QAudioDeviceI
|
|||
static std::once_flag once;
|
||||
std::call_once(once, [&] {
|
||||
//readout settings
|
||||
auto client = DependencyManager::get<AudioClient>();
|
||||
auto client = DependencyManager::get<AudioClient>().data();
|
||||
|
||||
_inputs._hmdSavedDeviceName = getTargetDevice(true, QAudio::AudioInput);
|
||||
_inputs._desktopSavedDeviceName = getTargetDevice(false, QAudio::AudioInput);
|
||||
|
@ -494,9 +494,9 @@ void AudioDevices::onDevicesChanged(QAudio::Mode mode, const QList<QAudioDeviceI
|
|||
void AudioDevices::chooseInputDevice(const QAudioDeviceInfo& device, bool isHMD) {
|
||||
//check if current context equals device to change
|
||||
if (_contextIsHMD == isHMD) {
|
||||
auto client = DependencyManager::get<AudioClient>();
|
||||
auto client = DependencyManager::get<AudioClient>().data();
|
||||
_requestedInputDevice = device;
|
||||
QMetaObject::invokeMethod(client.data(), "switchAudioDevice",
|
||||
QMetaObject::invokeMethod(client, "switchAudioDevice",
|
||||
Q_ARG(QAudio::Mode, QAudio::AudioInput),
|
||||
Q_ARG(const QAudioDeviceInfo&, device));
|
||||
} else {
|
||||
|
@ -511,9 +511,9 @@ void AudioDevices::chooseInputDevice(const QAudioDeviceInfo& device, bool isHMD)
|
|||
void AudioDevices::chooseOutputDevice(const QAudioDeviceInfo& device, bool isHMD) {
|
||||
//check if current context equals device to change
|
||||
if (_contextIsHMD == isHMD) {
|
||||
auto client = DependencyManager::get<AudioClient>();
|
||||
auto client = DependencyManager::get<AudioClient>().data();
|
||||
_requestedOutputDevice = device;
|
||||
QMetaObject::invokeMethod(client.data(), "switchAudioDevice",
|
||||
QMetaObject::invokeMethod(client, "switchAudioDevice",
|
||||
Q_ARG(QAudio::Mode, QAudio::AudioOutput),
|
||||
Q_ARG(const QAudioDeviceInfo&, device));
|
||||
} else {
|
||||
|
|
|
@ -312,7 +312,7 @@ JSConsole::~JSConsole() {
|
|||
delete _ui;
|
||||
}
|
||||
|
||||
void JSConsole::setScriptEngine(const ScriptEnginePointer& scriptEngine) {
|
||||
void JSConsole::setScriptEngine(const ScriptEnginePointer& scriptEngine) {
|
||||
if (_scriptEngine == scriptEngine && scriptEngine != nullptr) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -162,9 +162,7 @@ void LoginDialog::createAccountFromStream(QString username) {
|
|||
}
|
||||
|
||||
void LoginDialog::openUrl(const QString& url) const {
|
||||
|
||||
auto tabletScriptingInterface = DependencyManager::get<TabletScriptingInterface>();
|
||||
auto tablet = dynamic_cast<TabletProxy*>(tabletScriptingInterface->getTablet("com.highfidelity.interface.tablet.system"));
|
||||
auto tablet = dynamic_cast<TabletProxy*>(DependencyManager::get<TabletScriptingInterface>()->getTablet("com.highfidelity.interface.tablet.system"));
|
||||
auto hmd = DependencyManager::get<HMDScriptingInterface>();
|
||||
auto offscreenUi = DependencyManager::get<OffscreenUi>();
|
||||
|
||||
|
|
|
@ -27,28 +27,27 @@
|
|||
|
||||
void setupPreferences() {
|
||||
auto preferences = DependencyManager::get<Preferences>();
|
||||
auto nodeList = DependencyManager::get<NodeList>();
|
||||
auto myAvatar = DependencyManager::get<AvatarManager>()->getMyAvatar();
|
||||
static const QString AVATAR_BASICS { "Avatar Basics" };
|
||||
{
|
||||
auto getter = [=]()->QString { return myAvatar->getDisplayName(); };
|
||||
auto setter = [=](const QString& value) { myAvatar->setDisplayName(value); };
|
||||
auto getter = [myAvatar]()->QString { return myAvatar->getDisplayName(); };
|
||||
auto setter = [myAvatar](const QString& value) { myAvatar->setDisplayName(value); };
|
||||
auto preference = new EditPreference(AVATAR_BASICS, "Avatar display name (optional)", getter, setter);
|
||||
preference->setPlaceholderText("Not showing a name");
|
||||
preferences->addPreference(preference);
|
||||
}
|
||||
|
||||
{
|
||||
auto getter = [=]()->QString { return myAvatar->getCollisionSoundURL(); };
|
||||
auto setter = [=](const QString& value) { myAvatar->setCollisionSoundURL(value); };
|
||||
auto getter = [myAvatar]()->QString { return myAvatar->getCollisionSoundURL(); };
|
||||
auto setter = [myAvatar](const QString& value) { myAvatar->setCollisionSoundURL(value); };
|
||||
auto preference = new EditPreference(AVATAR_BASICS, "Avatar collision sound URL (optional)", getter, setter);
|
||||
preference->setPlaceholderText("Enter the URL of a sound to play when you bump into something");
|
||||
preferences->addPreference(preference);
|
||||
}
|
||||
|
||||
{
|
||||
auto getter = [=]()->QString { return myAvatar->getFullAvatarURLFromPreferences().toString(); };
|
||||
auto setter = [=](const QString& value) { myAvatar->useFullAvatarURL(value, ""); qApp->clearAvatarOverrideUrl(); };
|
||||
auto getter = [myAvatar]()->QString { return myAvatar->getFullAvatarURLFromPreferences().toString(); };
|
||||
auto setter = [myAvatar](const QString& value) { myAvatar->useFullAvatarURL(value, ""); qApp->clearAvatarOverrideUrl(); };
|
||||
auto preference = new AvatarPreference(AVATAR_BASICS, "Appearance", getter, setter);
|
||||
preferences->addPreference(preference);
|
||||
}
|
||||
|
@ -163,8 +162,8 @@ void setupPreferences() {
|
|||
|
||||
static const QString VIEW_CATEGORY{ "View" };
|
||||
{
|
||||
auto getter = [=]()->float { return myAvatar->getRealWorldFieldOfView(); };
|
||||
auto setter = [=](float value) { myAvatar->setRealWorldFieldOfView(value); };
|
||||
auto getter = [myAvatar]()->float { return myAvatar->getRealWorldFieldOfView(); };
|
||||
auto setter = [myAvatar](float value) { myAvatar->setRealWorldFieldOfView(value); };
|
||||
auto preference = new SpinnerPreference(VIEW_CATEGORY, "Real world vertical field of view (angular size of monitor)", getter, setter);
|
||||
preference->setMin(1);
|
||||
preference->setMax(180);
|
||||
|
@ -219,13 +218,13 @@ void setupPreferences() {
|
|||
|
||||
static const QString AVATAR_TUNING { "Avatar Tuning" };
|
||||
{
|
||||
auto getter = [=]()->QString { return myAvatar->getDominantHand(); };
|
||||
auto setter = [=](const QString& value) { myAvatar->setDominantHand(value); };
|
||||
auto getter = [myAvatar]()->QString { return myAvatar->getDominantHand(); };
|
||||
auto setter = [myAvatar](const QString& value) { myAvatar->setDominantHand(value); };
|
||||
preferences->addPreference(new PrimaryHandPreference(AVATAR_TUNING, "Dominant Hand", getter, setter));
|
||||
}
|
||||
{
|
||||
auto getter = [=]()->float { return myAvatar->getTargetScale(); };
|
||||
auto setter = [=](float value) { myAvatar->setTargetScale(value); };
|
||||
auto getter = [myAvatar]()->float { return myAvatar->getTargetScale(); };
|
||||
auto setter = [myAvatar](float value) { myAvatar->setTargetScale(value); };
|
||||
auto preference = new SpinnerSliderPreference(AVATAR_TUNING, "Avatar Scale", getter, setter);
|
||||
preference->setMin(0.25);
|
||||
preference->setMax(4);
|
||||
|
@ -240,16 +239,16 @@ void setupPreferences() {
|
|||
}
|
||||
|
||||
{
|
||||
auto getter = [=]()->QString { return myAvatar->getAnimGraphOverrideUrl().toString(); };
|
||||
auto setter = [=](const QString& value) { myAvatar->setAnimGraphOverrideUrl(QUrl(value)); };
|
||||
auto getter = [myAvatar]()->QString { return myAvatar->getAnimGraphOverrideUrl().toString(); };
|
||||
auto setter = [myAvatar](const QString& value) { myAvatar->setAnimGraphOverrideUrl(QUrl(value)); };
|
||||
auto preference = new EditPreference(AVATAR_TUNING, "Avatar animation JSON", getter, setter);
|
||||
preference->setPlaceholderText("default");
|
||||
preferences->addPreference(preference);
|
||||
}
|
||||
|
||||
{
|
||||
auto getter = [=]()->bool { return myAvatar->getCollisionsEnabled(); };
|
||||
auto setter = [=](bool value) { myAvatar->setCollisionsEnabled(value); };
|
||||
auto getter = [myAvatar]()->bool { return myAvatar->getCollisionsEnabled(); };
|
||||
auto setter = [myAvatar](bool value) { myAvatar->setCollisionsEnabled(value); };
|
||||
auto preference = new CheckPreference(AVATAR_TUNING, "Enable Avatar collisions", getter, setter);
|
||||
preferences->addPreference(preference);
|
||||
}
|
||||
|
@ -270,20 +269,20 @@ void setupPreferences() {
|
|||
{
|
||||
|
||||
static const QString movementsControlChannel = QStringLiteral("Hifi-Advanced-Movement-Disabler");
|
||||
auto getter = [=]()->bool { return myAvatar->useAdvancedMovementControls(); };
|
||||
auto setter = [=](bool value) { myAvatar->setUseAdvancedMovementControls(value); };
|
||||
auto getter = [myAvatar]()->bool { return myAvatar->useAdvancedMovementControls(); };
|
||||
auto setter = [myAvatar](bool value) { myAvatar->setUseAdvancedMovementControls(value); };
|
||||
preferences->addPreference(new CheckPreference(VR_MOVEMENT,
|
||||
QStringLiteral("Advanced movement for hand controllers"),
|
||||
getter, setter));
|
||||
}
|
||||
{
|
||||
auto getter = [=]()->bool { return myAvatar->getFlyingHMDPref(); };
|
||||
auto setter = [=](bool value) { myAvatar->setFlyingHMDPref(value); };
|
||||
auto getter = [myAvatar]()->bool { return myAvatar->getFlyingHMDPref(); };
|
||||
auto setter = [myAvatar](bool value) { myAvatar->setFlyingHMDPref(value); };
|
||||
preferences->addPreference(new CheckPreference(VR_MOVEMENT, "Flying & jumping (HMD)", getter, setter));
|
||||
}
|
||||
{
|
||||
auto getter = [=]()->int { return myAvatar->getSnapTurn() ? 0 : 1; };
|
||||
auto setter = [=](int value) { myAvatar->setSnapTurn(value == 0); };
|
||||
auto getter = [myAvatar]()->int { return myAvatar->getSnapTurn() ? 0 : 1; };
|
||||
auto setter = [myAvatar](int value) { myAvatar->setSnapTurn(value == 0); };
|
||||
auto preference = new RadioButtonsPreference(VR_MOVEMENT, "Snap turn / Smooth turn", getter, setter);
|
||||
QStringList items;
|
||||
items << "Snap turn" << "Smooth turn";
|
||||
|
@ -309,8 +308,8 @@ void setupPreferences() {
|
|||
|
||||
static const QString AVATAR_CAMERA{ "Mouse Sensitivity" };
|
||||
{
|
||||
auto getter = [=]()->float { return myAvatar->getPitchSpeed(); };
|
||||
auto setter = [=](float value) { myAvatar->setPitchSpeed(value); };
|
||||
auto getter = [myAvatar]()->float { return myAvatar->getPitchSpeed(); };
|
||||
auto setter = [myAvatar](float value) { myAvatar->setPitchSpeed(value); };
|
||||
auto preference = new SpinnerSliderPreference(AVATAR_CAMERA, "Y input:", getter, setter);
|
||||
preference->setMin(1.0f);
|
||||
preference->setMax(360.0f);
|
||||
|
@ -319,8 +318,8 @@ void setupPreferences() {
|
|||
preferences->addPreference(preference);
|
||||
}
|
||||
{
|
||||
auto getter = [=]()->float { return myAvatar->getYawSpeed(); };
|
||||
auto setter = [=](float value) { myAvatar->setYawSpeed(value); };
|
||||
auto getter = [myAvatar]()->float { return myAvatar->getYawSpeed(); };
|
||||
auto setter = [myAvatar](float value) { myAvatar->setYawSpeed(value); };
|
||||
auto preference = new SpinnerSliderPreference(AVATAR_CAMERA, "X input:", getter, setter);
|
||||
preference->setMin(1.0f);
|
||||
preference->setMax(360.0f);
|
||||
|
@ -381,12 +380,24 @@ void setupPreferences() {
|
|||
{
|
||||
static const QString NETWORKING("Networking");
|
||||
|
||||
auto nodelist = DependencyManager::get<NodeList>();
|
||||
QWeakPointer<NodeList> nodeListWeak = DependencyManager::get<NodeList>();
|
||||
{
|
||||
static const int MIN_PORT_NUMBER { 0 };
|
||||
static const int MAX_PORT_NUMBER { 65535 };
|
||||
auto getter = [nodelist] { return static_cast<int>(nodelist->getSocketLocalPort()); };
|
||||
auto setter = [nodelist](int preset) { nodelist->setSocketLocalPort(static_cast<quint16>(preset)); };
|
||||
auto getter = [nodeListWeak] {
|
||||
auto nodeList = nodeListWeak.lock();
|
||||
if (nodeList) {
|
||||
return static_cast<int>(nodeList->getSocketLocalPort());
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
};
|
||||
auto setter = [nodeListWeak](int preset) {
|
||||
auto nodeList = nodeListWeak.lock();
|
||||
if (nodeList) {
|
||||
nodeList->setSocketLocalPort(static_cast<quint16>(preset));
|
||||
}
|
||||
};
|
||||
auto preference = new IntSpinnerPreference(NETWORKING, "Listening Port", getter, setter);
|
||||
preference->setMin(MIN_PORT_NUMBER);
|
||||
preference->setMax(MAX_PORT_NUMBER);
|
||||
|
|
|
@ -174,7 +174,7 @@ void Stats::updateStats(bool force) {
|
|||
int octreeServerCount = 0;
|
||||
int pingOctreeMax = 0;
|
||||
int totalEntityKbps = 0;
|
||||
nodeList->eachNode([&](const SharedNodePointer& node) {
|
||||
nodeList->eachNode([&totalPingOctree, &totalEntityKbps, &octreeServerCount, &pingOctreeMax](const SharedNodePointer& node) {
|
||||
// TODO: this should also support entities
|
||||
if (node->getType() == NodeType::EntityServer) {
|
||||
totalPingOctree += node->getPingMs();
|
||||
|
@ -219,7 +219,7 @@ void Stats::updateStats(bool force) {
|
|||
STAT_UPDATE_FLOAT(myAvatarSendRate, avatarManager->getMyAvatarSendRate(), 0.1f);
|
||||
|
||||
SharedNodePointer audioMixerNode = nodeList->soloNodeOfType(NodeType::AudioMixer);
|
||||
auto audioClient = DependencyManager::get<AudioClient>();
|
||||
auto audioClient = DependencyManager::get<AudioClient>().data();
|
||||
if (audioMixerNode || force) {
|
||||
STAT_UPDATE(audioMixerKbps, (int)roundf(
|
||||
bandwidthRecorder->getAverageInputKilobitsPerSecond(NodeType::AudioMixer) +
|
||||
|
|
|
@ -23,8 +23,7 @@ TestingDialog::TestingDialog(QWidget* parent) :
|
|||
|
||||
_console->setFixedHeight(TESTING_CONSOLE_HEIGHT);
|
||||
|
||||
auto _engines = DependencyManager::get<ScriptEngines>();
|
||||
_engine = _engines->loadScript(qApp->applicationDirPath() + testRunnerRelativePath);
|
||||
_engine = DependencyManager::get<ScriptEngines>()->loadScript(qApp->applicationDirPath() + testRunnerRelativePath);
|
||||
_console->setScriptEngine(_engine);
|
||||
connect(_engine.data(), &ScriptEngine::finished, this, &TestingDialog::onTestingFinished);
|
||||
}
|
||||
|
|
|
@ -274,31 +274,14 @@ AudioClient::~AudioClient() {
|
|||
}
|
||||
|
||||
void AudioClient::customDeleter() {
|
||||
deleteLater();
|
||||
}
|
||||
|
||||
void AudioClient::cleanupBeforeQuit() {
|
||||
// FIXME: this should be put in customDeleter, but there is still a reference to this when it is called,
|
||||
// so this must be explicitly, synchronously stopped
|
||||
static ConditionalGuard guard;
|
||||
if (QThread::currentThread() != thread()) {
|
||||
// This will likely be called from the main thread, but we don't want to do blocking queued calls
|
||||
// from the main thread, so we use a normal auto-connection invoke, and then use a conditional to wait
|
||||
// for completion
|
||||
// The effect is the same, yes, but we actually want to avoid the use of Qt::BlockingQueuedConnection
|
||||
// in the code
|
||||
QMetaObject::invokeMethod(this, "cleanupBeforeQuit");
|
||||
guard.wait();
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined(Q_OS_ANDROID)
|
||||
_shouldRestartInputSetup = false;
|
||||
#endif
|
||||
stop();
|
||||
_checkDevicesTimer->stop();
|
||||
_checkPeakValuesTimer->stop();
|
||||
guard.trigger();
|
||||
|
||||
deleteLater();
|
||||
}
|
||||
|
||||
void AudioClient::handleMismatchAudioFormat(SharedNodePointer node, const QString& currentCodec, const QString& recievedCodec) {
|
||||
|
|
|
@ -171,7 +171,6 @@ public:
|
|||
public slots:
|
||||
void start();
|
||||
void stop();
|
||||
void cleanupBeforeQuit();
|
||||
|
||||
void handleAudioEnvironmentDataPacket(QSharedPointer<ReceivedMessage> message);
|
||||
void handleAudioDataPacket(QSharedPointer<ReceivedMessage> message);
|
||||
|
|
|
@ -95,8 +95,6 @@ void AudioIOStats::processStreamStatsPacket(QSharedPointer<ReceivedMessage> mess
|
|||
}
|
||||
|
||||
void AudioIOStats::publish() {
|
||||
auto audioIO = DependencyManager::get<AudioClient>();
|
||||
|
||||
// call _receivedAudioStream's per-second callback
|
||||
_receivedAudioStream->perSecondCallbackForUpdatingStats();
|
||||
|
||||
|
|
|
@ -2069,7 +2069,7 @@ void AvatarData::sendIdentityPacket() {
|
|||
auto packetList = NLPacketList::create(PacketType::AvatarIdentity, QByteArray(), true, true);
|
||||
packetList->write(identityData);
|
||||
nodeList->eachMatchingNode(
|
||||
[&](const SharedNodePointer& node)->bool {
|
||||
[](const SharedNodePointer& node)->bool {
|
||||
return node->getType() == NodeType::AvatarMixer && node->getActiveSocket();
|
||||
},
|
||||
[&](const SharedNodePointer& node) {
|
||||
|
|
|
@ -1252,7 +1252,7 @@ bool EntityScriptingInterface::actionWorker(const QUuid& entityID,
|
|||
|
||||
EntityItemPointer entity;
|
||||
bool doTransmit = false;
|
||||
_entityTree->withWriteLock([&] {
|
||||
_entityTree->withWriteLock([this, &entity, entityID, myNodeID, &doTransmit, actor, &properties] {
|
||||
EntitySimulationPointer simulation = _entityTree->getSimulation();
|
||||
entity = _entityTree->findEntityByEntityItemID(entityID);
|
||||
if (!entity) {
|
||||
|
|
|
@ -1435,7 +1435,7 @@ void EntityTree::validatePop(const QString& certID, const EntityItemID& entityIt
|
|||
|
||||
QNetworkReply* networkReply = networkAccessManager.put(networkRequest, QJsonDocument(request).toJson());
|
||||
|
||||
connect(networkReply, &QNetworkReply::finished, [=]() {
|
||||
connect(networkReply, &QNetworkReply::finished, [this, networkReply, entityItemID, certID, senderNode]() {
|
||||
QJsonObject jsonObject = QJsonDocument::fromJson(networkReply->readAll()).object();
|
||||
jsonObject = jsonObject["data"].toObject();
|
||||
|
||||
|
|
|
@ -133,7 +133,7 @@ QUrl expandScriptUrl(const QUrl& rawScriptURL) {
|
|||
QObject* scriptsModel();
|
||||
|
||||
bool NativeScriptInitializers::registerNativeScriptInitializer(NativeScriptInitializer initializer) {
|
||||
return registerScriptInitializer([=](ScriptEnginePointer engine) {
|
||||
return registerScriptInitializer([initializer](ScriptEnginePointer engine) {
|
||||
initializer(qobject_cast<QScriptEngine*>(engine.data()));
|
||||
});
|
||||
}
|
||||
|
@ -492,8 +492,7 @@ ScriptEnginePointer ScriptEngines::loadScript(const QUrl& scriptFilename, bool i
|
|||
return scriptEngine;
|
||||
}
|
||||
|
||||
scriptEngine = ScriptEnginePointer(new ScriptEngine(_context, NO_SCRIPT, "about:" + scriptFilename.fileName()));
|
||||
addScriptEngine(scriptEngine);
|
||||
scriptEngine = scriptEngineFactory(_context, NO_SCRIPT, "about:" + scriptFilename.fileName());
|
||||
scriptEngine->setUserLoaded(isUserLoaded);
|
||||
scriptEngine->setQuitWhenFinished(quitWhenFinished);
|
||||
|
||||
|
@ -564,10 +563,10 @@ int ScriptEngines::runScriptInitializers(ScriptEnginePointer scriptEngine) {
|
|||
|
||||
void ScriptEngines::launchScriptEngine(ScriptEnginePointer scriptEngine) {
|
||||
connect(scriptEngine.data(), &ScriptEngine::finished, this, &ScriptEngines::onScriptFinished, Qt::DirectConnection);
|
||||
connect(scriptEngine.data(), &ScriptEngine::loadScript, [&](const QString& scriptName, bool userLoaded) {
|
||||
connect(scriptEngine.data(), &ScriptEngine::loadScript, [this](const QString& scriptName, bool userLoaded) {
|
||||
loadScript(scriptName, userLoaded);
|
||||
});
|
||||
connect(scriptEngine.data(), &ScriptEngine::reloadScript, [&](const QString& scriptName, bool userLoaded) {
|
||||
connect(scriptEngine.data(), &ScriptEngine::reloadScript, [this](const QString& scriptName, bool userLoaded) {
|
||||
loadScript(scriptName, userLoaded, false, false, true);
|
||||
});
|
||||
|
||||
|
|
|
@ -139,7 +139,13 @@ QSharedPointer<T> DependencyManager::set(Args&&... args) {
|
|||
template <typename T>
|
||||
void DependencyManager::destroy() {
|
||||
static size_t hashCode = manager().getHashCode<T>();
|
||||
manager().safeGet(hashCode).clear();
|
||||
QSharedPointer<Dependency>& shared = manager().safeGet(hashCode);
|
||||
QWeakPointer<Dependency> weak = shared;
|
||||
shared.clear();
|
||||
// Check that the dependency was actually destroyed. If it wasn't, it was improperly captured somewhere
|
||||
if (weak.lock()) {
|
||||
qWarning() << "DependencyManager::destroy():" << typeid(T).name() << "was not properly destroyed!";
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Base, typename Derived>
|
||||
|
|
|
@ -329,8 +329,7 @@ void OffscreenQmlSurface::onRootCreated() {
|
|||
getSurfaceContext()->setContextProperty("offscreenWindow", QVariant::fromValue(getWindow()));
|
||||
|
||||
// Connect with the audio client and listen for audio device changes
|
||||
auto audioIO = DependencyManager::get<AudioClient>();
|
||||
connect(audioIO.data(), &AudioClient::deviceChanged, this, [&](QAudio::Mode mode, const QAudioDeviceInfo& device) {
|
||||
connect(DependencyManager::get<AudioClient>().data(), &AudioClient::deviceChanged, this, [this](QAudio::Mode mode, const QAudioDeviceInfo& device) {
|
||||
if (mode == QAudio::Mode::AudioOutput) {
|
||||
QMetaObject::invokeMethod(this, "changeAudioOutputDevice", Qt::QueuedConnection, Q_ARG(QString, device.deviceName()));
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue