Add the ability to get the context that a script is running in

This commit is contained in:
Ryan Huffman 2017-01-12 15:08:27 -08:00
parent 6da188b6ae
commit 9b1cd52fb4
7 changed files with 47 additions and 10 deletions

View file

@ -68,7 +68,7 @@ Agent::Agent(ReceivedMessage& message) :
DependencyManager::set<recording::Recorder>(); DependencyManager::set<recording::Recorder>();
DependencyManager::set<RecordingScriptingInterface>(); DependencyManager::set<RecordingScriptingInterface>();
DependencyManager::set<ScriptCache>(); DependencyManager::set<ScriptCache>();
DependencyManager::set<ScriptEngines>(); DependencyManager::set<ScriptEngines>(ScriptEngine::AGENT_SCRIPT);
auto& packetReceiver = DependencyManager::get<NodeList>()->getPacketReceiver(); auto& packetReceiver = DependencyManager::get<NodeList>()->getPacketReceiver();
@ -321,7 +321,7 @@ void Agent::scriptRequestFinished() {
} }
void Agent::executeScript() { void Agent::executeScript() {
_scriptEngine = std::unique_ptr<ScriptEngine>(new ScriptEngine(_scriptContents, _payload)); _scriptEngine = std::unique_ptr<ScriptEngine>(new ScriptEngine(ScriptEngine::AGENT_SCRIPT, _scriptContents, _payload));
_scriptEngine->setParent(this); // be the parent of the script engine so it gets moved when we do _scriptEngine->setParent(this); // be the parent of the script engine so it gets moved when we do
// setup an Avatar for the script to use // setup an Avatar for the script to use

View file

@ -459,7 +459,7 @@ bool setupEssentials(int& argc, char** argv) {
// Set dependencies // Set dependencies
DependencyManager::set<AccountManager>(std::bind(&Application::getUserAgent, qApp)); DependencyManager::set<AccountManager>(std::bind(&Application::getUserAgent, qApp));
DependencyManager::set<StatTracker>(); DependencyManager::set<StatTracker>();
DependencyManager::set<ScriptEngines>(); DependencyManager::set<ScriptEngines>(ScriptEngine::CLIENT_SCRIPT);
DependencyManager::set<Preferences>(); DependencyManager::set<Preferences>();
DependencyManager::set<recording::Deck>(); DependencyManager::set<recording::Deck>();
DependencyManager::set<recording::Recorder>(); DependencyManager::set<recording::Recorder>();

View file

@ -101,7 +101,7 @@ void EntityTreeRenderer::resetEntitiesScriptEngine() {
// Keep a ref to oldEngine until newEngine is ready so EntityScriptingInterface has something to use // Keep a ref to oldEngine until newEngine is ready so EntityScriptingInterface has something to use
auto oldEngine = _entitiesScriptEngine; auto oldEngine = _entitiesScriptEngine;
auto newEngine = new ScriptEngine(NO_SCRIPT, QString("Entities %1").arg(++_entitiesScriptEngineCount)); auto newEngine = new ScriptEngine(ScriptEngine::ENTITY_CLIENT_SCRIPT, NO_SCRIPT, QString("Entities %1").arg(++_entitiesScriptEngineCount));
_entitiesScriptEngine = QSharedPointer<ScriptEngine>(newEngine, entitiesScriptEngineDeleter); _entitiesScriptEngine = QSharedPointer<ScriptEngine>(newEngine, entitiesScriptEngineDeleter);
_scriptingServices->registerScriptEngineWithApplicationServices(_entitiesScriptEngine.data()); _scriptingServices->registerScriptEngineWithApplicationServices(_entitiesScriptEngine.data());

View file

@ -168,7 +168,8 @@ static bool hadUncaughtExceptions(QScriptEngine& engine, const QString& fileName
return false; return false;
} }
ScriptEngine::ScriptEngine(const QString& scriptContents, const QString& fileNameString) : ScriptEngine::ScriptEngine(Context context, const QString& scriptContents, const QString& fileNameString) :
_context(context),
_scriptContents(scriptContents), _scriptContents(scriptContents),
_timerFunctionMap(), _timerFunctionMap(),
_fileNameString(fileNameString), _fileNameString(fileNameString),
@ -183,6 +184,22 @@ ScriptEngine::ScriptEngine(const QString& scriptContents, const QString& fileNam
setProcessEventsInterval(MSECS_PER_SECOND); setProcessEventsInterval(MSECS_PER_SECOND);
} }
QString ScriptEngine::getContext() const {
switch (_context) {
case CLIENT_SCRIPT:
return "client";
case ENTITY_CLIENT_SCRIPT:
return "entity_client";
case ENTITY_SERVER_SCRIPT:
return "entity_server";
case AGENT_SCRIPT:
return "agent";
default:
return "unknown";
}
return "unknown";
}
ScriptEngine::~ScriptEngine() { ScriptEngine::~ScriptEngine() {
scriptInfoMessage("Script Engine shutting down:" + getFilename()); scriptInfoMessage("Script Engine shutting down:" + getFilename());

View file

@ -72,8 +72,17 @@ public:
class ScriptEngine : public QScriptEngine, public ScriptUser, public EntitiesScriptEngineProvider { class ScriptEngine : public QScriptEngine, public ScriptUser, public EntitiesScriptEngineProvider {
Q_OBJECT Q_OBJECT
Q_PROPERTY(QString context READ getContext)
public: public:
ScriptEngine(const QString& scriptContents = NO_SCRIPT, const QString& fileNameString = QString(""));
enum Context {
CLIENT_SCRIPT,
ENTITY_CLIENT_SCRIPT,
ENTITY_SERVER_SCRIPT,
AGENT_SCRIPT
};
ScriptEngine(Context context, const QString& scriptContents = NO_SCRIPT, const QString& fileNameString = QString(""));
~ScriptEngine(); ~ScriptEngine();
/// run the script in a dedicated thread. This will have the side effect of evalulating /// run the script in a dedicated thread. This will have the side effect of evalulating
@ -124,6 +133,12 @@ public:
/// to scripts. we may not need this to be invokable /// to scripts. we may not need this to be invokable
void loadURL(const QUrl& scriptURL, bool reload); void loadURL(const QUrl& scriptURL, bool reload);
Q_INVOKABLE QString getContext() const;
Q_INVOKABLE bool isClientScript() const { return _context == CLIENT_SCRIPT; }
Q_INVOKABLE bool isEntityClientScript() const { return _context == ENTITY_CLIENT_SCRIPT; }
Q_INVOKABLE bool isEntityServerScript() const { return _context == ENTITY_SERVER_SCRIPT; }
Q_INVOKABLE bool isAgentScript() const { return _context == AGENT_SCRIPT; }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// NOTE - these are intended to be public interfaces available to scripts // NOTE - these are intended to be public interfaces available to scripts
Q_INVOKABLE void addEventHandler(const EntityItemID& entityID, const QString& eventName, QScriptValue handler); Q_INVOKABLE void addEventHandler(const EntityItemID& entityID, const QString& eventName, QScriptValue handler);
@ -230,6 +245,8 @@ protected:
void doWithEnvironment(const EntityItemID& entityID, const QUrl& sandboxURL, std::function<void()> operation); void doWithEnvironment(const EntityItemID& entityID, const QUrl& sandboxURL, std::function<void()> operation);
void callWithEnvironment(const EntityItemID& entityID, const QUrl& sandboxURL, QScriptValue function, QScriptValue thisObject, QScriptValueList args); void callWithEnvironment(const EntityItemID& entityID, const QUrl& sandboxURL, QScriptValue function, QScriptValue thisObject, QScriptValueList args);
Context _context;
QString _scriptContents; QString _scriptContents;
QString _parentURL; QString _parentURL;
std::atomic<bool> _isFinished { false }; std::atomic<bool> _isFinished { false };

View file

@ -62,8 +62,9 @@ void ScriptEngines::onErrorLoadingScript(const QString& url) {
emit errorLoadingScript(url, scriptName); emit errorLoadingScript(url, scriptName);
} }
ScriptEngines::ScriptEngines() ScriptEngines::ScriptEngines(ScriptEngine::Context context)
: _scriptsLocationHandle("scriptsLocation", DESKTOP_LOCATION) : _context(context),
_scriptsLocationHandle("scriptsLocation", DESKTOP_LOCATION)
{ {
_scriptsModelFilter.setSourceModel(&_scriptsModel); _scriptsModelFilter.setSourceModel(&_scriptsModel);
_scriptsModelFilter.sort(0, Qt::AscendingOrder); _scriptsModelFilter.sort(0, Qt::AscendingOrder);
@ -453,7 +454,7 @@ ScriptEngine* ScriptEngines::loadScript(const QUrl& scriptFilename, bool isUserL
return scriptEngine; return scriptEngine;
} }
scriptEngine = new ScriptEngine(NO_SCRIPT, ""); scriptEngine = new ScriptEngine(_context, NO_SCRIPT, "");
scriptEngine->setUserLoaded(isUserLoaded); scriptEngine->setUserLoaded(isUserLoaded);
connect(scriptEngine, &ScriptEngine::doneRunning, this, [scriptEngine] { connect(scriptEngine, &ScriptEngine::doneRunning, this, [scriptEngine] {
scriptEngine->deleteLater(); scriptEngine->deleteLater();

View file

@ -20,6 +20,7 @@
#include <SettingHandle.h> #include <SettingHandle.h>
#include <DependencyManager.h> #include <DependencyManager.h>
#include "ScriptEngine.h"
#include "ScriptsModel.h" #include "ScriptsModel.h"
#include "ScriptsModelFilter.h" #include "ScriptsModelFilter.h"
@ -34,7 +35,7 @@ class ScriptEngines : public QObject, public Dependency {
public: public:
using ScriptInitializer = std::function<void(ScriptEngine*)>; using ScriptInitializer = std::function<void(ScriptEngine*)>;
ScriptEngines(); ScriptEngines(ScriptEngine::Context context);
void registerScriptInitializer(ScriptInitializer initializer); void registerScriptInitializer(ScriptInitializer initializer);
void loadScripts(); void loadScripts();
@ -100,6 +101,7 @@ protected:
void onScriptEngineError(const QString& scriptFilename); void onScriptEngineError(const QString& scriptFilename);
void launchScriptEngine(ScriptEngine* engine); void launchScriptEngine(ScriptEngine* engine);
ScriptEngine::Context _context;
QReadWriteLock _scriptEnginesHashLock; QReadWriteLock _scriptEnginesHashLock;
QHash<QUrl, ScriptEngine*> _scriptEnginesHash; QHash<QUrl, ScriptEngine*> _scriptEnginesHash;
QSet<ScriptEngine*> _allKnownScriptEngines; QSet<ScriptEngine*> _allKnownScriptEngines;