History

Merge branch 'master' of https://github.com/worklist/hifi into controller_scripting_interface

ZappoMan committed 12 years ago

Commit 4bfdce32 parents a6e6205 82f035c35 files · +410 −271Browse files

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

Unified · Split

libraries/script-engine/src/ScriptEngine.cpp+188−0
@@ -0,0 +1,188 @@
1//
2// Agent.cpp
3// hifi
4//
5// Created by Brad Hefta-Gaub on 12/14/13.
6// Copyright (c) 2013 HighFidelity, Inc. All rights reserved.
7//
8
9#include <QtCore/QCoreApplication>
10#include <QtCore/QEventLoop>
11#include <QtCore/QTimer>
12#include <QtCore/QThread>
13#include <QtNetwork/QNetworkAccessManager>
14#include <QtNetwork/QNetworkRequest>
15#include <QtNetwork/QNetworkReply>
16
17#include <AvatarData.h>
18#include <NodeList.h>
19#include <PacketHeaders.h>
20#include <UUID.h>
21#include <VoxelConstants.h>
22
23#include "ScriptEngine.h"
24
25int ScriptEngine::_scriptNumber = 1;
26
27ScriptEngine::ScriptEngine(const QString& scriptContents, bool wantMenuItems,
28 const char* scriptMenuName, AbstractMenuInterface* menu,
29 ControllerScriptingInterface* controllerScriptingInterface) {
30 _scriptContents = scriptContents;
31 _isFinished = false;
32 _isRunning = false;
33
34 // some clients will use these menu features
35 _wantMenuItems = wantMenuItems;
36 if (scriptMenuName) {
37 _scriptMenuName = "Stop ";
38 _scriptMenuName.append(scriptMenuName);
39 } else {
40 _scriptMenuName = "Stop Script ";
41 _scriptNumber++;
42 _scriptMenuName.append(_scriptNumber);
43 }
44 _menu = menu;
45 _controllerScriptingInterface = controllerScriptingInterface;
46}
47
48ScriptEngine::~ScriptEngine() {
49 //printf("ScriptEngine::~ScriptEngine()...\n");
50}
51
52
53void ScriptEngine::setupMenuItems() {
54 if (_menu && _wantMenuItems) {
55 _menu->addActionToQMenuAndActionHash(_menu->getActiveScriptsMenu(), _scriptMenuName, 0, this, SLOT(stop()));
56 }
57}
58
59void ScriptEngine::cleanMenuItems() {
60 if (_menu && _wantMenuItems) {
61 _menu->removeAction(_menu->getActiveScriptsMenu(), _scriptMenuName);
62 }
63}
64
65bool ScriptEngine::setScriptContents(const QString& scriptContents) {
66 if (_isRunning) {
67 return false;
68 }
69 _scriptContents = scriptContents;
70 return true;
71}
72
73void ScriptEngine::run() {
74 _isRunning = true;
75 QScriptEngine engine;
76
77 _voxelScriptingInterface.init();
78 _particleScriptingInterface.init();
79
80 // register meta-type for glm::vec3 conversions
81 registerMetaTypes(&engine);
82
83 QScriptValue agentValue = engine.newQObject(this);
84 engine.globalObject().setProperty("Agent", agentValue);
85
86 QScriptValue voxelScripterValue = engine.newQObject(&_voxelScriptingInterface);
87 engine.globalObject().setProperty("Voxels", voxelScripterValue);
88
89 QScriptValue particleScripterValue = engine.newQObject(&_particleScriptingInterface);
90 engine.globalObject().setProperty("Particles", particleScripterValue);
91
92 if (_controllerScriptingInterface) {
93 QScriptValue controllerScripterValue = engine.newQObject(_controllerScriptingInterface);
94 engine.globalObject().setProperty("Controller", controllerScripterValue);
95 }
96
97 QScriptValue treeScaleValue = engine.newVariant(QVariant(TREE_SCALE));
98 engine.globalObject().setProperty("TREE_SCALE", treeScaleValue);
99
100 const unsigned int VISUAL_DATA_CALLBACK_USECS = (1.0 / 60.0) * 1000 * 1000;
101
102 // let the VoxelPacketSender know how frequently we plan to call it
103 _voxelScriptingInterface.getVoxelPacketSender()->setProcessCallIntervalHint(VISUAL_DATA_CALLBACK_USECS);
104 _particleScriptingInterface.getParticlePacketSender()->setProcessCallIntervalHint(VISUAL_DATA_CALLBACK_USECS);
105
106 //qDebug() << "Script:\n" << _scriptContents << "\n";
107
108 QScriptValue result = engine.evaluate(_scriptContents);
109 qDebug() << "Evaluated script.\n";
110
111 if (engine.hasUncaughtException()) {
112 int line = engine.uncaughtExceptionLineNumber();
113 qDebug() << "Uncaught exception at line" << line << ":" << result.toString() << "\n";
114 }
115
116 timeval startTime;
117 gettimeofday(&startTime, NULL);
118
119 int thisFrame = 0;
120
121 while (!_isFinished) {
122 int usecToSleep = usecTimestamp(&startTime) + (thisFrame++ * VISUAL_DATA_CALLBACK_USECS) - usecTimestampNow();
123 if (usecToSleep > 0) {
124 usleep(usecToSleep);
125 }
126
127 if (_isFinished) {
128 break;
129 }
130
131 QCoreApplication::processEvents();
132
133 if (_isFinished) {
134 break;
135 }
136
137 bool willSendVisualDataCallBack = false;
138 if (_voxelScriptingInterface.getVoxelPacketSender()->serversExist()) {
139 // allow the scripter's call back to setup visual data
140 willSendVisualDataCallBack = true;
141
142 // release the queue of edit voxel messages.
143 _voxelScriptingInterface.getVoxelPacketSender()->releaseQueuedMessages();
144
145 // since we're in non-threaded mode, call process so that the packets are sent
146 if (!_voxelScriptingInterface.getVoxelPacketSender()->isThreaded()) {
147 _voxelScriptingInterface.getVoxelPacketSender()->process();
148 }
149 }
150
151 if (_particleScriptingInterface.getParticlePacketSender()->serversExist()) {
152 // allow the scripter's call back to setup visual data
153 willSendVisualDataCallBack = true;
154
155 // release the queue of edit voxel messages.
156 _particleScriptingInterface.getParticlePacketSender()->releaseQueuedMessages();
157
158 // since we're in non-threaded mode, call process so that the packets are sent
159 if (!_particleScriptingInterface.getParticlePacketSender()->isThreaded()) {
160 _particleScriptingInterface.getParticlePacketSender()->process();
161 }
162 }
163
164 if (willSendVisualDataCallBack) {
165 emit willSendVisualDataCallback();
166 }
167
168 if (engine.hasUncaughtException()) {
169 int line = engine.uncaughtExceptionLineNumber();
170 qDebug() << "Uncaught exception at line" << line << ":" << engine.uncaughtException().toString() << "\n";
171 }
172 }
173 cleanMenuItems();
174
175 // If we were on a thread, then wait till it's done
176 if (thread()) {
177 thread()->quit();
178 }
179
180 emit finished();
181 _isRunning = false;
182}
183
184void ScriptEngine::stop() {
185 _isFinished = true;
186}
187
188