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
25int ScriptEngine::_scriptNumber = 1;
26
27ScriptEngine::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
46ScriptEngine::~ScriptEngine() {
47 //printf("ScriptEngine::~ScriptEngine()...\n");
48}
49
50
51void ScriptEngine::setupMenuItems() {
52 if (_menu && _wantMenuItems) {
53 _menu->addActionToQMenuAndActionHash(_menu->getActiveScriptsMenu(), _scriptMenuName, 0, this, SLOT(stop()));
54 }
55}
56
57void ScriptEngine::cleanMenuItems() {
58 if (_menu && _wantMenuItems) {
59 _menu->removeAction(_menu->getActiveScriptsMenu(), _scriptMenuName);
60 }
61}
62
63bool ScriptEngine::setScriptContents(const QString& scriptContents) {
64 if (_isRunning) {
65 return false;
66 }
67 _scriptContents = scriptContents;
68 return true;
69}
70
71void 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
177void ScriptEngine::stop() {
178 _isFinished = true;
179}
180
181