fetch entity filter script asynchronously (but reject edits while waiting)

This commit is contained in:
howard-stearns 2017-01-30 11:06:36 -08:00
parent ae8d0d1948
commit 93414d802d
4 changed files with 15 additions and 16 deletions

View file

@ -294,7 +294,9 @@ void EntityServer::readAdditionalConfiguration(const QJsonObject& settingsSectio
} }
if (readOptionString("entityEditFilter", settingsSectionObject, _entityEditFilter) && !_entityEditFilter.isEmpty()) { if (readOptionString("entityEditFilter", settingsSectionObject, _entityEditFilter) && !_entityEditFilter.isEmpty()) {
// Fetch script from file synchronously. We don't want the server processing edits while a restarting entity server is fetching from a DOS'd source. // Tell the tree that we have a filter, so that it doesn't accept edits until we have a filter function set up.
std::static_pointer_cast<EntityTree>(_tree)->setHasEntityFilter(true);
// Now fetch script from file asynchronously.
QUrl scriptURL(_entityEditFilter); QUrl scriptURL(_entityEditFilter);
// The following should be abstracted out for use in Agent.cpp (and maybe later AvatarMixer.cpp) // The following should be abstracted out for use in Agent.cpp (and maybe later AvatarMixer.cpp)
@ -315,8 +317,6 @@ void EntityServer::readAdditionalConfiguration(const QJsonObject& settingsSectio
qInfo() << "Requesting script at URL" << qPrintable(scriptRequest->getUrl().toString()); qInfo() << "Requesting script at URL" << qPrintable(scriptRequest->getUrl().toString());
scriptRequest->send(); scriptRequest->send();
qDebug() << "script request sent"; qDebug() << "script request sent";
_scriptRequestLoop.exec(); // Block here, but allow the request to be processed and its signals to be handled.
qDebug() << "script request event loop complete";
} }
} }
@ -367,11 +367,7 @@ void EntityServer::scriptRequestFinished() {
return hadUncaughtExceptions(_entityEditFilterEngine, _entityEditFilter); return hadUncaughtExceptions(_entityEditFilterEngine, _entityEditFilter);
}); });
scriptRequest->deleteLater(); scriptRequest->deleteLater();
qDebug() << "script request ending event loop. running:" << _scriptRequestLoop.isRunning(); qDebug() << "script request filter processed";
if (_scriptRequestLoop.isRunning()) {
_scriptRequestLoop.quit();
}
qDebug() << "script request event loop quit";
return; return;
} }
} }
@ -386,11 +382,6 @@ void EntityServer::scriptRequestFinished() {
// Alas, only indications will be the above logging with assignment client restarting repeatedly, and clients will not see any entities. // Alas, only indications will be the above logging with assignment client restarting repeatedly, and clients will not see any entities.
qDebug() << "script request failure causing stop"; qDebug() << "script request failure causing stop";
stop(); stop();
qDebug() << "script request ending event loop. running:" << _scriptRequestLoop.isRunning();
if (_scriptRequestLoop.isRunning()) {
_scriptRequestLoop.quit();
}
qDebug() << "script request event loop quit";
} }
void EntityServer::nodeAdded(SharedNodePointer node) { void EntityServer::nodeAdded(SharedNodePointer node) {

View file

@ -80,7 +80,6 @@ private:
QString _entityEditFilter{}; QString _entityEditFilter{};
QScriptEngine _entityEditFilterEngine{}; QScriptEngine _entityEditFilterEngine{};
QEventLoop _scriptRequestLoop{};
}; };
#endif // hifi_EntityServer_h #endif // hifi_EntityServer_h

View file

@ -927,13 +927,21 @@ void EntityTree::initEntityEditFilterEngine(QScriptEngine* engine, std::function
_entityEditFilterHadUncaughtExceptions = entityEditFilterHadUncaughtExceptions; _entityEditFilterHadUncaughtExceptions = entityEditFilterHadUncaughtExceptions;
auto global = _entityEditFilterEngine->globalObject(); auto global = _entityEditFilterEngine->globalObject();
_entityEditFilterFunction = global.property("filter"); _entityEditFilterFunction = global.property("filter");
_hasEntityEditFilter = _entityEditFilterFunction.isFunction(); if (!_entityEditFilterFunction.isFunction()) {
qCDebug(entities) << "Filter function specified but not found. Will reject all edits.";
_entityEditFilterEngine = nullptr; // So that we don't try to call it. See filterProperties.
}
_hasEntityEditFilter = true;
} }
bool EntityTree::filterProperties(EntityItemProperties& propertiesIn, EntityItemProperties& propertiesOut, bool& wasChanged) { bool EntityTree::filterProperties(EntityItemProperties& propertiesIn, EntityItemProperties& propertiesOut, bool& wasChanged) {
if (!_hasEntityEditFilter || !_entityEditFilterEngine) { if (!_entityEditFilterEngine) {
propertiesOut = propertiesIn; propertiesOut = propertiesIn;
wasChanged = false; // not changed wasChanged = false; // not changed
if (_hasEntityEditFilter) {
qCDebug(entities) << "Rejecting properties because filter has not been set.";
return false;
}
return true; // allowed return true; // allowed
} }
auto oldProperties = propertiesIn.getDesiredProperties(); auto oldProperties = propertiesIn.getDesiredProperties();

View file

@ -267,6 +267,7 @@ public:
void notifyNewCollisionSoundURL(const QString& newCollisionSoundURL, const EntityItemID& entityID); void notifyNewCollisionSoundURL(const QString& newCollisionSoundURL, const EntityItemID& entityID);
void initEntityEditFilterEngine(QScriptEngine* engine, std::function<bool()> entityEditFilterHadUncaughtExceptions); void initEntityEditFilterEngine(QScriptEngine* engine, std::function<bool()> entityEditFilterHadUncaughtExceptions);
void setHasEntityFilter(bool hasFilter) { _hasEntityEditFilter = hasFilter; }
static const float DEFAULT_MAX_TMP_ENTITY_LIFETIME; static const float DEFAULT_MAX_TMP_ENTITY_LIFETIME;