Showing the changes to libraries/script-engine/src/ScriptEngine.cpp (1 of 5 files). Show all
Unified · Split
| @@ -19,11 +19,14 @@ · 18 unmodified lines | |||
| 19 | #include <PacketHeaders.h> | 19 | #include <PacketHeaders.h> |
| 20 | #include <UUID.h> | 20 | #include <UUID.h> |
| 21 | #include <VoxelConstants.h> | 21 | #include <VoxelConstants.h> |
| 22 | #include <ParticlesScriptingInterface.h> | ||
| 22 | 23 | ||
| 23 | #include <Sound.h> | 24 | #include <Sound.h> |
| 24 | 25 | ||
| 25 | #include "ScriptEngine.h" | 26 | #include "ScriptEngine.h" |
| 26 | 27 | ||
| 28 | const unsigned int VISUAL_DATA_CALLBACK_USECS = (1.0 / 60.0) * 1000 * 1000; | ||
| 29 | |||
| 27 | int ScriptEngine::_scriptNumber = 1; | 30 | int ScriptEngine::_scriptNumber = 1; |
| 28 | VoxelsScriptingInterface ScriptEngine::_voxelsScriptingInterface; | 31 | VoxelsScriptingInterface ScriptEngine::_voxelsScriptingInterface; |
| 29 | ParticlesScriptingInterface ScriptEngine::_particlesScriptingInterface; | 32 | ParticlesScriptingInterface ScriptEngine::_particlesScriptingInterface; |
| @@ -31,7 +34,7 @@ ParticlesScriptingInterface ScriptEngine::_particlesScriptingInterface; · 1 unmodified line | |||
| 31 | static QScriptValue soundConstructor(QScriptContext* context, QScriptEngine* engine) { | 34 | static QScriptValue soundConstructor(QScriptContext* context, QScriptEngine* engine) { |
| 32 | QUrl soundURL = QUrl(context->argument(0).toString()); | 35 | QUrl soundURL = QUrl(context->argument(0).toString()); |
| 33 | QScriptValue soundScriptValue = engine->newQObject(new Sound(soundURL), QScriptEngine::ScriptOwnership); | 36 | QScriptValue soundScriptValue = engine->newQObject(new Sound(soundURL), QScriptEngine::ScriptOwnership); |
| 34 | 37 | ||
| 35 | return soundScriptValue; | 38 | return soundScriptValue; |
| 36 | } | 39 | } |
| 37 | 40 | ||
| @@ -41,7 +44,8 @@ ScriptEngine::ScriptEngine(const QString& scriptContents, bool wantMenuItems, · 3 unmodified lines | |||
| 41 | _scriptContents = scriptContents; | 44 | _scriptContents = scriptContents; |
| 42 | _isFinished = false; | 45 | _isFinished = false; |
| 43 | _isRunning = false; | 46 | _isRunning = false; |
| 44 | 47 | _isInitialized = false; | |
| 48 | |||
| 45 | // some clients will use these menu features | 49 | // some clients will use these menu features |
| 46 | _wantMenuItems = wantMenuItems; | 50 | _wantMenuItems = wantMenuItems; |
| 47 | if (scriptMenuName) { | 51 | if (scriptMenuName) { |
| @@ -54,15 +58,6 @@ ScriptEngine::ScriptEngine(const QString& scriptContents, bool wantMenuItems, · 6 unmodified lines | |||
| 54 | } | 58 | } |
| 55 | _menu = menu; | 59 | _menu = menu; |
| 56 | _controllerScriptingInterface = controllerScriptingInterface; | 60 | _controllerScriptingInterface = controllerScriptingInterface; |
| 57 | |||
| 58 | // hook up our interfaces | ||
| 59 | if (!Particle::getVoxelsScriptingInterface()) { | ||
| 60 | Particle::setVoxelsScriptingInterface(getVoxelsScriptingInterface()); | ||
| 61 | } | ||
| 62 | |||
| 63 | if (!Particle::getParticlesScriptingInterface()) { | ||
| 64 | Particle::setParticlesScriptingInterface(getParticlesScriptingInterface()); | ||
| 65 | } | ||
| 66 | } | 61 | } |
| 67 | 62 | ||
| 68 | ScriptEngine::~ScriptEngine() { | 63 | ScriptEngine::~ScriptEngine() { |
| @@ -92,63 +87,89 @@ bool ScriptEngine::setScriptContents(const QString& scriptContents) { · 23 unmodified lines | |||
| 92 | 87 | ||
| 93 | Q_SCRIPT_DECLARE_QMETAOBJECT(AudioInjectorOptions, QObject*) | 88 | Q_SCRIPT_DECLARE_QMETAOBJECT(AudioInjectorOptions, QObject*) |
| 94 | 89 | ||
| 95 | void ScriptEngine::run() { | 90 | void ScriptEngine::init() { |
| 96 | _isRunning = true; | 91 | if (_isInitialized) { |
| 97 | QScriptEngine engine; | 92 | return; // only initialize once |
| 98 | 93 | } | |
| 94 | |||
| 95 | _isInitialized = true; | ||
| 96 | |||
| 99 | _voxelsScriptingInterface.init(); | 97 | _voxelsScriptingInterface.init(); |
| 100 | _particlesScriptingInterface.init(); | 98 | _particlesScriptingInterface.init(); |
| 101 | 99 | ||
| 102 | // register meta-type for glm::vec3 conversions | 100 | // register meta-type for glm::vec3 conversions |
| 103 | registerMetaTypes(&engine); | 101 | registerMetaTypes(&_engine); |
| 104 | 102 | ||
| 105 | QScriptValue agentValue = engine.newQObject(this); | 103 | QScriptValue agentValue = _engine.newQObject(this); |
| 106 | engine.globalObject().setProperty("Agent", agentValue); | 104 | _engine.globalObject().setProperty("Agent", agentValue); |
| 107 | 105 | ||
| 108 | QScriptValue voxelScripterValue = engine.newQObject(&_voxelsScriptingInterface); | 106 | QScriptValue voxelScripterValue = _engine.newQObject(&_voxelsScriptingInterface); |
| 109 | engine.globalObject().setProperty("Voxels", voxelScripterValue); | 107 | _engine.globalObject().setProperty("Voxels", voxelScripterValue); |
| 110 | 108 | ||
| 111 | QScriptValue particleScripterValue = engine.newQObject(&_particlesScriptingInterface); | 109 | QScriptValue particleScripterValue = _engine.newQObject(&_particlesScriptingInterface); |
| 112 | engine.globalObject().setProperty("Particles", particleScripterValue); | 110 | _engine.globalObject().setProperty("Particles", particleScripterValue); |
| 113 | 111 | ||
| 114 | 112 | QScriptValue soundConstructorValue = _engine.newFunction(soundConstructor); | |
| 115 | QScriptValue soundConstructorValue = engine.newFunction(soundConstructor); | 113 | QScriptValue soundMetaObject = _engine.newQMetaObject(&Sound::staticMetaObject, soundConstructorValue); |
| 116 | QScriptValue soundMetaObject = engine.newQMetaObject(&Sound::staticMetaObject, soundConstructorValue); | 114 | _engine.globalObject().setProperty("Sound", soundMetaObject); |
| 117 | engine.globalObject().setProperty("Sound", soundMetaObject); | 115 | |
| 118 | 116 | QScriptValue injectionOptionValue = _engine.scriptValueFromQMetaObject<AudioInjectorOptions>(); | |
| 119 | QScriptValue injectionOptionValue = engine.scriptValueFromQMetaObject<AudioInjectorOptions>(); | 117 | _engine.globalObject().setProperty("AudioInjectionOptions", injectionOptionValue); |
| 120 | engine.globalObject().setProperty("AudioInjectionOptions", injectionOptionValue); | 118 | |
| 121 | 119 | QScriptValue audioScriptingInterfaceValue = _engine.newQObject(&_audioScriptingInterface); | |
| 122 | QScriptValue audioScriptingInterfaceValue = engine.newQObject(&_audioScriptingInterface); | 120 | _engine.globalObject().setProperty("Audio", audioScriptingInterfaceValue); |
| 123 | engine.globalObject().setProperty("Audio", audioScriptingInterfaceValue); | 121 | |
| 124 | |||
| 125 | if (_controllerScriptingInterface) { | 122 | if (_controllerScriptingInterface) { |
| 126 | QScriptValue controllerScripterValue = engine.newQObject(_controllerScriptingInterface); | 123 | QScriptValue controllerScripterValue = _engine.newQObject(_controllerScriptingInterface); |
| 127 | engine.globalObject().setProperty("Controller", controllerScripterValue); | 124 | _engine.globalObject().setProperty("Controller", controllerScripterValue); |
| 128 | } | 125 | } |
| 129 | 126 | ||
| 130 | QScriptValue treeScaleValue = engine.newVariant(QVariant(TREE_SCALE)); | 127 | QScriptValue treeScaleValue = _engine.newVariant(QVariant(TREE_SCALE)); |
| 131 | engine.globalObject().setProperty("TREE_SCALE", treeScaleValue); | 128 | _engine.globalObject().setProperty("TREE_SCALE", treeScaleValue); |
| 132 | 129 | ||
| 133 | const unsigned int VISUAL_DATA_CALLBACK_USECS = (1.0 / 60.0) * 1000 * 1000; | ||
| 134 | |||
| 135 | // let the VoxelPacketSender know how frequently we plan to call it | 130 | // let the VoxelPacketSender know how frequently we plan to call it |
| 136 | _voxelsScriptingInterface.getVoxelPacketSender()->setProcessCallIntervalHint(VISUAL_DATA_CALLBACK_USECS); | 131 | _voxelsScriptingInterface.getVoxelPacketSender()->setProcessCallIntervalHint(VISUAL_DATA_CALLBACK_USECS); |
| 137 | _particlesScriptingInterface.getParticlePacketSender()->setProcessCallIntervalHint(VISUAL_DATA_CALLBACK_USECS); | 132 | _particlesScriptingInterface.getParticlePacketSender()->setProcessCallIntervalHint(VISUAL_DATA_CALLBACK_USECS); |
| 138 | 133 | ||
| 139 | //qDebug() << "Script:\n" << _scriptContents << "\n"; | 134 | //qDebug() << "Script:\n" << _scriptContents << "\n"; |
| 140 | 135 | } | |
| 141 | QScriptValue result = engine.evaluate(_scriptContents); | 136 | |
| 137 | void ScriptEngine::registerGlobalObject(const QString& name, QObject* object) { | ||
| 138 | QScriptValue value = _engine.newQObject(object); | ||
| 139 | _engine.globalObject().setProperty(name, value); | ||
| 140 | } | ||
| 141 | |||
| 142 | void ScriptEngine::evaluate() { | ||
| 143 | if (!_isInitialized) { | ||
| 144 | init(); | ||
| 145 | } | ||
| 146 | |||
| 147 | QScriptValue result = _engine.evaluate(_scriptContents); | ||
| 142 | qDebug() << "Evaluated script.\n"; | 148 | qDebug() << "Evaluated script.\n"; |
| 143 | 149 | ||
| 144 | if (engine.hasUncaughtException()) { | 150 | if (_engine.hasUncaughtException()) { |
| 145 | int line = engine.uncaughtExceptionLineNumber(); | 151 | int line = _engine.uncaughtExceptionLineNumber(); |
| 146 | qDebug() << "Uncaught exception at line" << line << ":" << result.toString() << "\n"; | 152 | qDebug() << "Uncaught exception at line" << line << ":" << result.toString() << "\n"; |
| 147 | } | 153 | } |
| 148 | 154 | } | |
| 155 | |||
| 156 | void ScriptEngine::run() { | ||
| 157 | if (!_isInitialized) { | ||
| 158 | init(); | ||
| 159 | } | ||
| 160 | _isRunning = true; | ||
| 161 | |||
| 162 | QScriptValue result = _engine.evaluate(_scriptContents); | ||
| 163 | qDebug() << "Evaluated script.\n"; | ||
| 164 | |||
| 165 | if (_engine.hasUncaughtException()) { | ||
| 166 | int line = _engine.uncaughtExceptionLineNumber(); | ||
| 167 | qDebug() << "Uncaught exception at line" << line << ":" << result.toString() << "\n"; | ||
| 168 | } | ||
| 169 | |||
| 149 | timeval startTime; | 170 | timeval startTime; |
| 150 | gettimeofday(&startTime, NULL); | 171 | gettimeofday(&startTime, NULL); |
| 151 | 172 | ||
| 152 | int thisFrame = 0; | 173 | int thisFrame = 0; |
| 153 | 174 | ||
| 154 | while (!_isFinished) { | 175 | while (!_isFinished) { |
| @@ -166,15 +187,15 @@ void ScriptEngine::run() { · 11 unmodified lines | |||
| 166 | if (_isFinished) { | 187 | if (_isFinished) { |
| 167 | break; | 188 | break; |
| 168 | } | 189 | } |
| 169 | 190 | ||
| 170 | bool willSendVisualDataCallBack = false; | 191 | bool willSendVisualDataCallBack = false; |
| 171 | if (_voxelsScriptingInterface.getVoxelPacketSender()->serversExist()) { | 192 | if (_voxelsScriptingInterface.getVoxelPacketSender()->serversExist()) { |
| 172 | // allow the scripter's call back to setup visual data | 193 | // allow the scripter's call back to setup visual data |
| 173 | willSendVisualDataCallBack = true; | 194 | willSendVisualDataCallBack = true; |
| 174 | 195 | ||
| 175 | // release the queue of edit voxel messages. | 196 | // release the queue of edit voxel messages. |
| 176 | _voxelsScriptingInterface.getVoxelPacketSender()->releaseQueuedMessages(); | 197 | _voxelsScriptingInterface.getVoxelPacketSender()->releaseQueuedMessages(); |
| 177 | 198 | ||
| 178 | // since we're in non-threaded mode, call process so that the packets are sent | 199 | // since we're in non-threaded mode, call process so that the packets are sent |
| 179 | if (!_voxelsScriptingInterface.getVoxelPacketSender()->isThreaded()) { | 200 | if (!_voxelsScriptingInterface.getVoxelPacketSender()->isThreaded()) { |
| 180 | _voxelsScriptingInterface.getVoxelPacketSender()->process(); | 201 | _voxelsScriptingInterface.getVoxelPacketSender()->process(); |
| @@ -184,23 +205,23 @@ void ScriptEngine::run() { · 3 unmodified lines | |||
| 184 | if (_particlesScriptingInterface.getParticlePacketSender()->serversExist()) { | 205 | if (_particlesScriptingInterface.getParticlePacketSender()->serversExist()) { |
| 185 | // allow the scripter's call back to setup visual data | 206 | // allow the scripter's call back to setup visual data |
| 186 | willSendVisualDataCallBack = true; | 207 | willSendVisualDataCallBack = true; |
| 187 | 208 | ||
| 188 | // release the queue of edit voxel messages. | 209 | // release the queue of edit voxel messages. |
| 189 | _particlesScriptingInterface.getParticlePacketSender()->releaseQueuedMessages(); | 210 | _particlesScriptingInterface.getParticlePacketSender()->releaseQueuedMessages(); |
| 190 | 211 | ||
| 191 | // since we're in non-threaded mode, call process so that the packets are sent | 212 | // since we're in non-threaded mode, call process so that the packets are sent |
| 192 | if (!_particlesScriptingInterface.getParticlePacketSender()->isThreaded()) { | 213 | if (!_particlesScriptingInterface.getParticlePacketSender()->isThreaded()) { |
| 193 | _particlesScriptingInterface.getParticlePacketSender()->process(); | 214 | _particlesScriptingInterface.getParticlePacketSender()->process(); |
| 194 | } | 215 | } |
| 195 | } | 216 | } |
| 196 | 217 | ||
| 197 | if (willSendVisualDataCallBack) { | 218 | if (willSendVisualDataCallBack) { |
| 198 | emit willSendVisualDataCallback(); | 219 | emit willSendVisualDataCallback(); |
| 199 | } | 220 | } |
| 200 | 221 | ||
| 201 | if (engine.hasUncaughtException()) { | 222 | if (_engine.hasUncaughtException()) { |
| 202 | int line = engine.uncaughtExceptionLineNumber(); | 223 | int line = _engine.uncaughtExceptionLineNumber(); |
| 203 | qDebug() << "Uncaught exception at line" << line << ":" << engine.uncaughtException().toString() << "\n"; | 224 | qDebug() << "Uncaught exception at line" << line << ":" << _engine.uncaughtException().toString() << "\n"; |
| 204 | } | 225 | } |
| 205 | } | 226 | } |
| 206 | cleanMenuItems(); | 227 | cleanMenuItems(); |
| @@ -213,9 +234,8 @@ void ScriptEngine::run() { · 6 unmodified lines | |||
| 213 | emit finished(); | 234 | emit finished(); |
| 214 | _isRunning = false; | 235 | _isRunning = false; |
| 215 | } | 236 | } |
| 216 | 237 | void ScriptEngine::stop() { | |
| 217 | void ScriptEngine::stop() { | 238 | _isFinished = true; |
| 218 | _isFinished = true; | ||
| 219 | } | 239 | } |
| 220 | 240 | ||
| 221 | 241 | ||