History

first cut at moving entity scripts into ScriptEngine

Brad Hefta-Gaub committed 11 years ago

Commit 18fbf891 parent 56118e46 files · +283 −316Browse files

Showing the changes to libraries/script-engine/src/ScriptEngine.cpp (1 of 6 files). Show all

Unified · Split

libraries/script-engine/src/ScriptEngine.cpp+179−0
@@ -16,6 +16,7 @@ · 15 unmodified lines
1616 #include <QtNetwork/QNetworkRequest>
1717 #include <QtNetwork/QNetworkReply>
1818 #include <QScriptEngine>
19+#include <QScriptValue>
1920
2021 #include <AudioConstants.h>
2122 #include <AudioEffectOptions.h>
@@ -848,3 +849,181 @@ void ScriptEngine::generalHandler(const EntityItemID& entityID, const QString& e · 826 unmodified lines
848849 }
849850 }
850851 }
852+
853+// since all of these operations can be asynch we will always do the actual work in the response handler
854+// for the download
855+void ScriptEngine::loadEntityScript(const EntityItemID& entityID, const QString& entityScript, bool forceRedownload) {
856+ if (QThread::currentThread() != thread()) {
857+ qDebug() << "*** WARNING *** ScriptEngine::loadEntityScript() called on wrong thread [" << QThread::currentThread() << "], invoking on correct thread [" << thread() << "] "
858+ "entityID:" << entityID <<
859+ "entityScript:" << entityScript <<
860+ "forceRedownload:" << forceRedownload;
861+
862+ QMetaObject::invokeMethod(this, "loadEntityScript",
863+ Q_ARG(const EntityItemID&, entityID),
864+ Q_ARG(const QString&, entityScript),
865+ Q_ARG(bool, forceRedownload));
866+ return;
867+ }
868+ qDebug() << "ScriptEngine::loadEntityScript() called on correct thread [" << thread() << "] "
869+ "entityID:" << entityID <<
870+ "entityScript:" << entityScript <<
871+ "forceRedownload:" << forceRedownload;
872+
873+ // If we've been called our known entityScripts should not know about us..
874+ assert(!_entityScripts.contains(entityID));
875+
876+ auto scriptCache = DependencyManager::get<ScriptCache>();
877+
878+ scriptCache->getScriptContents(entityScript, [=](const QString& scriptOrURL, const QString& contents, bool isURL, bool success) {
879+
880+ // first check the syntax of the script contents
881+ QScriptSyntaxCheckResult syntaxCheck = QScriptEngine::checkSyntax(contents);
882+ if (syntaxCheck.state() != QScriptSyntaxCheckResult::Valid) {
883+ qCDebug(scriptengine) << "ScriptEngine::loadEntityScript() entity:" << entityID;
884+ qCDebug(scriptengine) << " " << syntaxCheck.errorMessage() << ":"
885+ << syntaxCheck.errorLineNumber() << syntaxCheck.errorColumnNumber();
886+ qCDebug(scriptengine) << " SCRIPT:" << scriptOrURL;
887+ scriptCache->addScriptToBadScriptList(scriptOrURL);
888+ return; // done processing script
889+ }
890+
891+ if (isURL) {
892+ setParentURL(scriptOrURL);
893+ }
894+
895+ QScriptEngine sandbox;
896+ QScriptValue testConstructor = sandbox.evaluate(contents);
897+
898+ if (!testConstructor.isFunction()) {
899+ qCDebug(scriptengine) << "ScriptEngine::loadEntityScript() entity:" << entityID;
900+ qCDebug(scriptengine) << " NOT CONSTRUCTOR";
901+ qCDebug(scriptengine) << " SCRIPT:" << scriptOrURL;
902+ scriptCache->addScriptToBadScriptList(scriptOrURL);
903+ return; // done processing script
904+ }
905+
906+ QScriptValue entityScriptConstructor = evaluate(contents);
907+
908+ QScriptValue entityScriptObject = entityScriptConstructor.construct();
909+ EntityScriptDetails newDetails = { scriptOrURL, entityScriptObject };
910+ _entityScripts[entityID] = newDetails;
911+
912+ if (isURL) {
913+ setParentURL("");
914+ }
915+
916+ // if we got this far, then call the preload method
917+ callEntityScriptMethod(entityID, "preload");
918+
919+ }, forceRedownload);
920+}
921+
922+void ScriptEngine::unloadEntityScript(const EntityItemID& entityID) {
923+ if (QThread::currentThread() != thread()) {
924+ qDebug() << "*** WARNING *** ScriptEngine::unloadEntityScript() called on wrong thread [" << QThread::currentThread() << "], invoking on correct thread [" << thread() << "] "
925+ "entityID:" << entityID;
926+
927+ QMetaObject::invokeMethod(this, "unloadEntityScript",
928+ Q_ARG(const EntityItemID&, entityID));
929+ return;
930+ }
931+ qDebug() << "ScriptEngine::unloadEntityScript() called on correct thread [" << thread() << "] "
932+ "entityID:" << entityID;
933+
934+ if (_entityScripts.contains(entityID)) {
935+ callEntityScriptMethod(entityID, "unload");
936+ _entityScripts.remove(entityID);
937+ }
938+}
939+
940+void ScriptEngine::callEntityScriptMethod(const EntityItemID& entityID, const QString& methodName) {
941+ if (QThread::currentThread() != thread()) {
942+ qDebug() << "*** WARNING *** ScriptEngine::callEntityScriptMethod() called on wrong thread [" << QThread::currentThread() << "], invoking on correct thread [" << thread() << "] "
943+ "entityID:" << entityID <<
944+ "methodName:" << methodName;
945+
946+ QMetaObject::invokeMethod(this, "callEntityScriptMethod",
947+ Q_ARG(const EntityItemID&, entityID),
948+ Q_ARG(const QString&, methodName));
949+ return;
950+ }
951+ qDebug() << "ScriptEngine::callEntityScriptMethod() called on correct thread [" << thread() << "] "
952+ "entityID:" << entityID <<
953+ "methodName:" << methodName;
954+
955+ if (_entityScripts.contains(entityID)) {
956+ EntityScriptDetails details = _entityScripts[entityID];
957+ QScriptValue entityScript = details.scriptObject; // previously loaded
958+ if (entityScript.property(methodName).isFunction()) {
959+ QScriptValueList args;
960+ args << entityID.toScriptValue(this);
961+ entityScript.property(methodName).call(entityScript, args);
962+ }
963+ }
964+}
965+
966+void ScriptEngine::callEntityScriptMethod(const EntityItemID& entityID, const QString& methodName, const MouseEvent& event) {
967+ if (QThread::currentThread() != thread()) {
968+ qDebug() << "*** WARNING *** ScriptEngine::callEntityScriptMethod() called on wrong thread [" << QThread::currentThread() << "], invoking on correct thread [" << thread() << "] "
969+ "entityID:" << entityID <<
970+ "methodName:" << methodName <<
971+ "event: mouseEvent";
972+
973+ QMetaObject::invokeMethod(this, "callEntityScriptMethod",
974+ Q_ARG(const EntityItemID&, entityID),
975+ Q_ARG(const QString&, methodName),
976+ Q_ARG(const MouseEvent&, event));
977+ return;
978+ }
979+ qDebug() << "ScriptEngine::callEntityScriptMethod() called on correct thread [" << thread() << "] "
980+ "entityID:" << entityID <<
981+ "methodName:" << methodName <<
982+ "event: mouseEvent";
983+
984+ if (_entityScripts.contains(entityID)) {
985+ EntityScriptDetails details = _entityScripts[entityID];
986+ QScriptValue entityScript = details.scriptObject; // previously loaded
987+ if (entityScript.property(methodName).isFunction()) {
988+ QScriptValueList args;
989+ args << entityID.toScriptValue(this);
990+ args << event.toScriptValue(this);
991+ entityScript.property(methodName).call(entityScript, args);
992+ }
993+ }
994+}
995+
996+
997+void ScriptEngine::callEntityScriptMethod(const EntityItemID& entityID, const QString& methodName, const EntityItemID& otherID, const Collision& collision) {
998+ if (QThread::currentThread() != thread()) {
999+ qDebug() << "*** WARNING *** ScriptEngine::callEntityScriptMethod() called on wrong thread [" << QThread::currentThread() << "], invoking on correct thread [" << thread() << "] "
1000+ "entityID:" << entityID <<
1001+ "methodName:" << methodName <<
1002+ "otherID:" << otherID <<
1003+ "collision: collision";
1004+
1005+ QMetaObject::invokeMethod(this, "callEntityScriptMethod",
1006+ Q_ARG(const EntityItemID&, entityID),
1007+ Q_ARG(const QString&, methodName),
1008+ Q_ARG(const EntityItemID&, otherID),
1009+ Q_ARG(const Collision&, collision));
1010+ return;
1011+ }
1012+ qDebug() << "ScriptEngine::callEntityScriptMethod() called on correct thread [" << thread() << "] "
1013+ "entityID:" << entityID <<
1014+ "methodName:" << methodName <<
1015+ "otherID:" << otherID <<
1016+ "collision: collision";
1017+
1018+ if (_entityScripts.contains(entityID)) {
1019+ EntityScriptDetails details = _entityScripts[entityID];
1020+ QScriptValue entityScript = details.scriptObject; // previously loaded
1021+ if (entityScript.property(methodName).isFunction()) {
1022+ QScriptValueList args;
1023+ args << entityID.toScriptValue(this);
1024+ args << otherID.toScriptValue(this);
1025+ args << collisionToScriptValue(this, collision);
1026+ entityScript.property(methodName).call(entityScript, args);
1027+ }
1028+ }
1029+}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t