History

CR feedback

ZappoMan committed 12 years ago

Commit f4695531 parent 88c319a5 files · +7 −7Browse files

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

Unified · Split

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