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