Merge pull request #7624 from birarda/new-home-set

allow ATP scripts to be used by scripted Agent
This commit is contained in:
Chris Collins 2016-04-12 09:42:14 -07:00
commit 0faab41057
3 changed files with 62 additions and 22 deletions

View file

@ -144,6 +144,9 @@ void Agent::run() {
connect(messagesThread, &QThread::started, messagesClient.data(), &MessagesClient::init); connect(messagesThread, &QThread::started, messagesClient.data(), &MessagesClient::init);
messagesThread->start(); messagesThread->start();
// make sure we hear about connected nodes so we can grab an ATP script if a request is pending
connect(nodeList.data(), &LimitedNodeList::nodeActivated, this, &Agent::nodeActivated);
nodeList->addSetOfNodeTypesToNodeInterestSet({ nodeList->addSetOfNodeTypesToNodeInterestSet({
NodeType::AudioMixer, NodeType::AvatarMixer, NodeType::EntityServer, NodeType::MessagesMixer, NodeType::AssetServer NodeType::AudioMixer, NodeType::AvatarMixer, NodeType::EntityServer, NodeType::MessagesMixer, NodeType::AssetServer
}); });
@ -164,52 +167,85 @@ void Agent::requestScript() {
scriptURL = QUrl(_payload); scriptURL = QUrl(_payload);
} }
// setup a network access manager and // make sure this is not a script request for the file scheme
QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); if (scriptURL.scheme() == URL_SCHEME_FILE) {
qWarning() << "Cannot load script for Agent from local filesystem.";
scriptRequestFinished();
return;
}
QNetworkDiskCache* cache = new QNetworkDiskCache(); auto request = ResourceManager::createResourceRequest(this, scriptURL);
QString cachePath = QStandardPaths::writableLocation(QStandardPaths::DataLocation);
cache->setCacheDirectory(!cachePath.isEmpty() ? cachePath : "agentCache");
networkAccessManager.setCache(cache);
QNetworkRequest networkRequest = QNetworkRequest(scriptURL); if (!request) {
networkRequest.setHeader(QNetworkRequest::UserAgentHeader, HIGH_FIDELITY_USER_AGENT); qWarning() << "Could not create ResourceRequest for Agent script at" << scriptURL.toString();
scriptRequestFinished();
return;
}
// setup a timeout for script request // setup a timeout for script request
static const int SCRIPT_TIMEOUT_MS = 10000; static const int SCRIPT_TIMEOUT_MS = 10000;
_scriptRequestTimeout = new QTimer(this); _scriptRequestTimeout = new QTimer;
connect(_scriptRequestTimeout, &QTimer::timeout, this, &Agent::scriptRequestFinished); connect(_scriptRequestTimeout, &QTimer::timeout, this, &Agent::scriptRequestFinished);
_scriptRequestTimeout->start(SCRIPT_TIMEOUT_MS); _scriptRequestTimeout->start(SCRIPT_TIMEOUT_MS);
qDebug() << "Downloading script at" << scriptURL.toString(); connect(request, &ResourceRequest::finished, this, &Agent::scriptRequestFinished);
QNetworkReply* reply = networkAccessManager.get(networkRequest);
connect(reply, &QNetworkReply::finished, this, &Agent::scriptRequestFinished); if (scriptURL.scheme() == URL_SCHEME_ATP) {
// we have an ATP URL for the script - if we're not currently connected to the AssetServer
// then wait for the nodeConnected signal to fire off the request
auto assetServer = nodeList->soloNodeOfType(NodeType::AssetServer);
if (!assetServer || !assetServer->getActiveSocket()) {
qDebug() << "Waiting to connect to Asset Server for ATP script download.";
_pendingScriptRequest = request;
return;
}
}
qInfo() << "Requesting script at URL" << qPrintable(request->getUrl().toString());
request->send();
}
void Agent::nodeActivated(SharedNodePointer activatedNode) {
if (_pendingScriptRequest) {
qInfo() << "Requesting script at URL" << qPrintable(_pendingScriptRequest->getUrl().toString());
_pendingScriptRequest->send();
_pendingScriptRequest = nullptr;
}
} }
void Agent::scriptRequestFinished() { void Agent::scriptRequestFinished() {
auto reply = qobject_cast<QNetworkReply*>(sender()); auto request = qobject_cast<ResourceRequest*>(sender());
_scriptRequestTimeout->stop(); // stop the script request timeout, if it's running
if (_scriptRequestTimeout) {
QMetaObject::invokeMethod(_scriptRequestTimeout, "stop");
_scriptRequestTimeout->deleteLater();
}
if (reply && reply->error() == QNetworkReply::NoError) { if (request && request->getResult() == ResourceRequest::Success) {
_scriptContents = reply->readAll(); _scriptContents = request->getData();
qDebug() << "Downloaded script:" << _scriptContents; qInfo() << "Downloaded script:" << _scriptContents;
// we could just call executeScript directly - we use a QueuedConnection to allow scriptRequestFinished // we could just call executeScript directly - we use a QueuedConnection to allow scriptRequestFinished
// to return before calling executeScript // to return before calling executeScript
QMetaObject::invokeMethod(this, "executeScript", Qt::QueuedConnection); QMetaObject::invokeMethod(this, "executeScript", Qt::QueuedConnection);
} else { } else {
if (reply) { if (request) {
qDebug() << "Failed to download script at" << reply->url().toString() << " - bailing on assignment."; qWarning() << "Failed to download script at" << request->getUrl().toString() << " - bailing on assignment.";
qDebug() << "QNetworkReply error was" << reply->errorString(); qWarning() << "ResourceRequest error was" << request->getResult();
} else { } else {
qDebug() << "Failed to download script - request timed out. Bailing on assignment."; qWarning() << "Failed to download script - request timed out. Bailing on assignment.";
} }
setFinished(true); setFinished(true);
} }
reply->deleteLater(); request->deleteLater();
} }
void Agent::executeScript() { void Agent::executeScript() {

View file

@ -69,6 +69,8 @@ private slots:
void processAgentAvatarAndAudio(float deltaTime); void processAgentAvatarAndAudio(float deltaTime);
void nodeActivated(SharedNodePointer activatedNode);
private: private:
std::unique_ptr<ScriptEngine> _scriptEngine; std::unique_ptr<ScriptEngine> _scriptEngine;
EntityEditPacketSender _entityEditSender; EntityEditPacketSender _entityEditSender;
@ -84,6 +86,7 @@ private:
QString _scriptContents; QString _scriptContents;
QTimer* _scriptRequestTimeout { nullptr }; QTimer* _scriptRequestTimeout { nullptr };
ResourceRequest* _pendingScriptRequest { nullptr };
bool _isListeningToAudioStream = false; bool _isListeningToAudioStream = false;
SharedSoundPointer _avatarSound; SharedSoundPointer _avatarSound;
int _numAvatarSoundSentBytes = 0; int _numAvatarSoundSentBytes = 0;

View file

@ -20,6 +20,7 @@ void ResourceRequest::send() {
QMetaObject::invokeMethod(this, "send", Qt::QueuedConnection); QMetaObject::invokeMethod(this, "send", Qt::QueuedConnection);
return; return;
} }
Q_ASSERT(_state == NotStarted); Q_ASSERT(_state == NotStarted);
_state = InProgress; _state = InProgress;