Merge branch 'master' of https://github.com/highfidelity/hifi into metavoxels

This commit is contained in:
Andrzej Kapolka 2014-06-30 18:02:56 -07:00
commit 0075bb89c4
10 changed files with 118 additions and 21 deletions

View file

@ -28,7 +28,8 @@ OctreeInboundPacketProcessor::OctreeInboundPacketProcessor(OctreeServer* myServe
_totalLockWaitTime(0), _totalLockWaitTime(0),
_totalElementsInPacket(0), _totalElementsInPacket(0),
_totalPackets(0), _totalPackets(0),
_lastNackTime(usecTimestampNow()) _lastNackTime(usecTimestampNow()),
_shuttingDown(false)
{ {
} }
@ -72,6 +73,10 @@ void OctreeInboundPacketProcessor::midProcess() {
} }
void OctreeInboundPacketProcessor::processPacket(const SharedNodePointer& sendingNode, const QByteArray& packet) { void OctreeInboundPacketProcessor::processPacket(const SharedNodePointer& sendingNode, const QByteArray& packet) {
if (_shuttingDown) {
qDebug() << "OctreeInboundPacketProcessor::processPacket() while shutting down... ignoring incoming packet";
return;
}
bool debugProcessPacket = _myServer->wantsVerboseDebug(); bool debugProcessPacket = _myServer->wantsVerboseDebug();
@ -182,8 +187,13 @@ void OctreeInboundPacketProcessor::trackInboundPacket(const QUuid& nodeUUID, uns
} }
int OctreeInboundPacketProcessor::sendNackPackets() { int OctreeInboundPacketProcessor::sendNackPackets() {
int packetsSent = 0; int packetsSent = 0;
if (_shuttingDown) {
qDebug() << "OctreeInboundPacketProcessor::sendNackPackets() while shutting down... ignore";
return packetsSent;
}
char packet[MAX_PACKET_SIZE]; char packet[MAX_PACKET_SIZE];
NodeToSenderStatsMapIterator i = _singleSenderStats.begin(); NodeToSenderStatsMapIterator i = _singleSenderStats.begin();
@ -241,6 +251,8 @@ int OctreeInboundPacketProcessor::sendNackPackets() {
// send it // send it
NodeList::getInstance()->writeUnverifiedDatagram(packet, dataAt - packet, destinationNode); NodeList::getInstance()->writeUnverifiedDatagram(packet, dataAt - packet, destinationNode);
packetsSent++; packetsSent++;
qDebug() << "NACK Sent back to editor/client... destinationNode=" << nodeUUID;
} }
i++; i++;
} }

View file

@ -73,6 +73,8 @@ public:
NodeToSenderStatsMap& getSingleSenderStats() { return _singleSenderStats; } NodeToSenderStatsMap& getSingleSenderStats() { return _singleSenderStats; }
void shuttingDown() { _shuttingDown = true;}
protected: protected:
virtual void processPacket(const SharedNodePointer& sendingNode, const QByteArray& packet); virtual void processPacket(const SharedNodePointer& sendingNode, const QByteArray& packet);
@ -100,5 +102,6 @@ private:
NodeToSenderStatsMap _singleSenderStats; NodeToSenderStatsMap _singleSenderStats;
quint64 _lastNackTime; quint64 _lastNackTime;
bool _shuttingDown;
}; };
#endif // hifi_OctreeInboundPacketProcessor_h #endif // hifi_OctreeInboundPacketProcessor_h

View file

@ -1097,6 +1097,8 @@ void OctreeServer::forceNodeShutdown(SharedNodePointer node) {
void OctreeServer::aboutToFinish() { void OctreeServer::aboutToFinish() {
qDebug() << qPrintable(_safeServerName) << "server STARTING about to finish..."; qDebug() << qPrintable(_safeServerName) << "server STARTING about to finish...";
qDebug() << qPrintable(_safeServerName) << "inform Octree Inbound Packet Processor that we are shutting down...";
_octreeInboundPacketProcessor->shuttingDown();
foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) { foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) {
qDebug() << qPrintable(_safeServerName) << "server about to finish while node still connected node:" << *node; qDebug() << qPrintable(_safeServerName) << "server about to finish while node still connected node:" << *node;
forceNodeShutdown(node); forceNodeShutdown(node);

View file

@ -3628,7 +3628,8 @@ ScriptEngine* Application::loadScript(const QString& scriptName, bool loadScript
} }
void Application::scriptFinished(const QString& scriptName) { void Application::scriptFinished(const QString& scriptName) {
QHash<QString, ScriptEngine*>::iterator it = _scriptEnginesHash.find(scriptName); const QString& scriptURLString = QUrl(scriptName).toString();
QHash<QString, ScriptEngine*>::iterator it = _scriptEnginesHash.find(scriptURLString);
if (it != _scriptEnginesHash.end()) { if (it != _scriptEnginesHash.end()) {
_scriptEnginesHash.erase(it); _scriptEnginesHash.erase(it);
_runningScriptsWidget->scriptStopped(scriptName); _runningScriptsWidget->scriptStopped(scriptName);

View file

@ -28,8 +28,12 @@
ScriptEditorWidget::ScriptEditorWidget() : ScriptEditorWidget::ScriptEditorWidget() :
_scriptEditorWidgetUI(new Ui::ScriptEditorWidget), _scriptEditorWidgetUI(new Ui::ScriptEditorWidget),
_scriptEngine(NULL) _scriptEngine(NULL),
_isRestarting(false),
_isReloading(false)
{ {
setAttribute(Qt::WA_DeleteOnClose);
_scriptEditorWidgetUI->setupUi(this); _scriptEditorWidgetUI->setupUi(this);
connect(_scriptEditorWidgetUI->scriptEdit->document(), &QTextDocument::modificationChanged, this, connect(_scriptEditorWidgetUI->scriptEdit->document(), &QTextDocument::modificationChanged, this,
@ -51,15 +55,19 @@ ScriptEditorWidget::~ScriptEditorWidget() {
} }
void ScriptEditorWidget::onScriptModified() { void ScriptEditorWidget::onScriptModified() {
if(_scriptEditorWidgetUI->onTheFlyCheckBox->isChecked() && isRunning()) { if(_scriptEditorWidgetUI->onTheFlyCheckBox->isChecked() && isModified() && isRunning() && !_isReloading) {
_isRestarting = true;
setRunning(false); setRunning(false);
setRunning(true); // Script is restarted once current script instance finishes.
} }
} }
void ScriptEditorWidget::onScriptEnding() { void ScriptEditorWidget::onScriptFinished(const QString& scriptPath) {
// signals will automatically be disonnected when the _scriptEngine is deleted later
_scriptEngine = NULL; _scriptEngine = NULL;
if (_isRestarting) {
_isRestarting = false;
setRunning(true);
}
} }
bool ScriptEditorWidget::isModified() { bool ScriptEditorWidget::isModified() {
@ -71,27 +79,28 @@ bool ScriptEditorWidget::isRunning() {
} }
bool ScriptEditorWidget::setRunning(bool run) { bool ScriptEditorWidget::setRunning(bool run) {
if (run && !save()) { if (run && isModified() && !save()) {
return false; return false;
} }
// Clean-up old connections.
if (_scriptEngine != NULL) { if (_scriptEngine != NULL) {
disconnect(_scriptEngine, &ScriptEngine::runningStateChanged, this, &ScriptEditorWidget::runningStateChanged); disconnect(_scriptEngine, &ScriptEngine::runningStateChanged, this, &ScriptEditorWidget::runningStateChanged);
disconnect(_scriptEngine, &ScriptEngine::errorMessage, this, &ScriptEditorWidget::onScriptError); disconnect(_scriptEngine, &ScriptEngine::errorMessage, this, &ScriptEditorWidget::onScriptError);
disconnect(_scriptEngine, &ScriptEngine::printedMessage, this, &ScriptEditorWidget::onScriptPrint); disconnect(_scriptEngine, &ScriptEngine::printedMessage, this, &ScriptEditorWidget::onScriptPrint);
disconnect(_scriptEngine, &ScriptEngine::scriptEnding, this, &ScriptEditorWidget::onScriptEnding); disconnect(_scriptEngine, &ScriptEngine::update, this, &ScriptEditorWidget::onScriptModified);
disconnect(_scriptEngine, &ScriptEngine::finished, this, &ScriptEditorWidget::onScriptFinished);
} }
if (run) { if (run) {
_scriptEngine = Application::getInstance()->loadScript(_currentScript, true); const QString& scriptURLString = QUrl(_currentScript).toString();
_scriptEngine = Application::getInstance()->loadScript(scriptURLString, true);
connect(_scriptEngine, &ScriptEngine::runningStateChanged, this, &ScriptEditorWidget::runningStateChanged); connect(_scriptEngine, &ScriptEngine::runningStateChanged, this, &ScriptEditorWidget::runningStateChanged);
// Make new connections.
connect(_scriptEngine, &ScriptEngine::errorMessage, this, &ScriptEditorWidget::onScriptError); connect(_scriptEngine, &ScriptEngine::errorMessage, this, &ScriptEditorWidget::onScriptError);
connect(_scriptEngine, &ScriptEngine::printedMessage, this, &ScriptEditorWidget::onScriptPrint); connect(_scriptEngine, &ScriptEngine::printedMessage, this, &ScriptEditorWidget::onScriptPrint);
connect(_scriptEngine, &ScriptEngine::scriptEnding, this, &ScriptEditorWidget::onScriptEnding); connect(_scriptEngine, &ScriptEngine::update, this, &ScriptEditorWidget::onScriptModified);
connect(_scriptEngine, &ScriptEngine::finished, this, &ScriptEditorWidget::onScriptFinished);
} else { } else {
connect(_scriptEngine, &ScriptEngine::finished, this, &ScriptEditorWidget::onScriptFinished);
Application::getInstance()->stopScript(_currentScript); Application::getInstance()->stopScript(_currentScript);
_scriptEngine = NULL; _scriptEngine = NULL;
} }
@ -108,6 +117,7 @@ bool ScriptEditorWidget::saveFile(const QString &scriptPath) {
QTextStream out(&file); QTextStream out(&file);
out << _scriptEditorWidgetUI->scriptEdit->toPlainText(); out << _scriptEditorWidgetUI->scriptEdit->toPlainText();
file.close();
setScriptFile(scriptPath); setScriptFile(scriptPath);
return true; return true;
@ -127,13 +137,15 @@ void ScriptEditorWidget::loadFile(const QString& scriptPath) {
} }
QTextStream in(&file); QTextStream in(&file);
_scriptEditorWidgetUI->scriptEdit->setPlainText(in.readAll()); _scriptEditorWidgetUI->scriptEdit->setPlainText(in.readAll());
file.close();
setScriptFile(scriptPath); setScriptFile(scriptPath);
if (_scriptEngine != NULL) { if (_scriptEngine != NULL) {
disconnect(_scriptEngine, &ScriptEngine::runningStateChanged, this, &ScriptEditorWidget::runningStateChanged); disconnect(_scriptEngine, &ScriptEngine::runningStateChanged, this, &ScriptEditorWidget::runningStateChanged);
disconnect(_scriptEngine, &ScriptEngine::errorMessage, this, &ScriptEditorWidget::onScriptError); disconnect(_scriptEngine, &ScriptEngine::errorMessage, this, &ScriptEditorWidget::onScriptError);
disconnect(_scriptEngine, &ScriptEngine::printedMessage, this, &ScriptEditorWidget::onScriptPrint); disconnect(_scriptEngine, &ScriptEngine::printedMessage, this, &ScriptEditorWidget::onScriptPrint);
disconnect(_scriptEngine, &ScriptEngine::scriptEnding, this, &ScriptEditorWidget::onScriptEnding); disconnect(_scriptEngine, &ScriptEngine::update, this, &ScriptEditorWidget::onScriptModified);
disconnect(_scriptEngine, &ScriptEngine::finished, this, &ScriptEditorWidget::onScriptFinished);
} }
} else { } else {
QNetworkAccessManager* networkManager = new QNetworkAccessManager(this); QNetworkAccessManager* networkManager = new QNetworkAccessManager(this);
@ -148,12 +160,14 @@ void ScriptEditorWidget::loadFile(const QString& scriptPath) {
} }
} }
_scriptEngine = Application::getInstance()->getScriptEngine(_currentScript); const QString& scriptURLString = QUrl(_currentScript).toString();
_scriptEngine = Application::getInstance()->getScriptEngine(scriptURLString);
if (_scriptEngine != NULL) { if (_scriptEngine != NULL) {
connect(_scriptEngine, &ScriptEngine::runningStateChanged, this, &ScriptEditorWidget::runningStateChanged); connect(_scriptEngine, &ScriptEngine::runningStateChanged, this, &ScriptEditorWidget::runningStateChanged);
connect(_scriptEngine, &ScriptEngine::errorMessage, this, &ScriptEditorWidget::onScriptError); connect(_scriptEngine, &ScriptEngine::errorMessage, this, &ScriptEditorWidget::onScriptError);
connect(_scriptEngine, &ScriptEngine::printedMessage, this, &ScriptEditorWidget::onScriptPrint); connect(_scriptEngine, &ScriptEngine::printedMessage, this, &ScriptEditorWidget::onScriptPrint);
connect(_scriptEngine, &ScriptEngine::scriptEnding, this, &ScriptEditorWidget::onScriptEnding); connect(_scriptEngine, &ScriptEngine::update, this, &ScriptEditorWidget::onScriptModified);
connect(_scriptEngine, &ScriptEngine::finished, this, &ScriptEditorWidget::onScriptFinished);
} }
} }
@ -175,6 +189,7 @@ bool ScriptEditorWidget::saveAs() {
void ScriptEditorWidget::setScriptFile(const QString& scriptPath) { void ScriptEditorWidget::setScriptFile(const QString& scriptPath) {
_currentScript = scriptPath; _currentScript = scriptPath;
_currentScriptModified = QFileInfo(_currentScript).lastModified();
_scriptEditorWidgetUI->scriptEdit->document()->setModified(false); _scriptEditorWidgetUI->scriptEdit->document()->setModified(false);
setWindowModified(false); setWindowModified(false);
@ -198,3 +213,29 @@ void ScriptEditorWidget::onScriptError(const QString& message) {
void ScriptEditorWidget::onScriptPrint(const QString& message) { void ScriptEditorWidget::onScriptPrint(const QString& message) {
_scriptEditorWidgetUI->debugText->appendPlainText("> " + message); _scriptEditorWidgetUI->debugText->appendPlainText("> " + message);
} }
void ScriptEditorWidget::onWindowActivated() {
if (!_isReloading) {
_isReloading = true;
if (QFileInfo(_currentScript).lastModified() > _currentScriptModified) {
if (static_cast<ScriptEditorWindow*>(this->parent()->parent()->parent())->autoReloadScripts()
|| QMessageBox::warning(this, _currentScript,
tr("This file has been modified outside of the Interface editor.") + "\n\n"
+ (isModified()
? tr("Do you want to reload it and lose the changes you've made in the Interface editor?")
: tr("Do you want to reload it?")),
QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
loadFile(_currentScript);
if (_scriptEditorWidgetUI->onTheFlyCheckBox->isChecked() && isRunning()) {
_isRestarting = true;
setRunning(false);
// Script is restarted once current script instance finishes.
}
}
}
_isReloading = false;
}
}

View file

@ -13,6 +13,7 @@
#define hifi_ScriptEditorWidget_h #define hifi_ScriptEditorWidget_h
#include <QDockWidget> #include <QDockWidget>
#include "ScriptEngine.h" #include "ScriptEngine.h"
namespace Ui { namespace Ui {
@ -42,16 +43,22 @@ signals:
void scriptnameChanged(); void scriptnameChanged();
void scriptModified(); void scriptModified();
public slots:
void onWindowActivated();
private slots: private slots:
void onScriptError(const QString& message); void onScriptError(const QString& message);
void onScriptPrint(const QString& message); void onScriptPrint(const QString& message);
void onScriptModified(); void onScriptModified();
void onScriptEnding(); void onScriptFinished(const QString& scriptName);
private: private:
Ui::ScriptEditorWidget* _scriptEditorWidgetUI; Ui::ScriptEditorWidget* _scriptEditorWidgetUI;
ScriptEngine* _scriptEngine; ScriptEngine* _scriptEngine;
QString _currentScript; QString _currentScript;
QDateTime _currentScriptModified;
bool _isRestarting;
bool _isReloading;
}; };
#endif // hifi_ScriptEditorWidget_h #endif // hifi_ScriptEditorWidget_h

View file

@ -36,6 +36,8 @@ ScriptEditorWindow::ScriptEditorWindow() :
_loadMenu(new QMenu), _loadMenu(new QMenu),
_saveMenu(new QMenu) _saveMenu(new QMenu)
{ {
setAttribute(Qt::WA_DeleteOnClose);
_ScriptEditorWindowUI->setupUi(this); _ScriptEditorWindowUI->setupUi(this);
this->setWindowFlags(Qt::Tool); this->setWindowFlags(Qt::Tool);
show(); show();
@ -140,6 +142,7 @@ ScriptEditorWidget* ScriptEditorWindow::addScriptEditorWidget(QString title) {
connect(newScriptEditorWidget, &ScriptEditorWidget::scriptnameChanged, this, &ScriptEditorWindow::updateScriptNameOrStatus); connect(newScriptEditorWidget, &ScriptEditorWidget::scriptnameChanged, this, &ScriptEditorWindow::updateScriptNameOrStatus);
connect(newScriptEditorWidget, &ScriptEditorWidget::scriptModified, this, &ScriptEditorWindow::updateScriptNameOrStatus); connect(newScriptEditorWidget, &ScriptEditorWidget::scriptModified, this, &ScriptEditorWindow::updateScriptNameOrStatus);
connect(newScriptEditorWidget, &ScriptEditorWidget::runningStateChanged, this, &ScriptEditorWindow::updateButtons); connect(newScriptEditorWidget, &ScriptEditorWidget::runningStateChanged, this, &ScriptEditorWindow::updateButtons);
connect(this, &ScriptEditorWindow::windowActivated, newScriptEditorWidget, &ScriptEditorWidget::onWindowActivated);
_ScriptEditorWindowUI->tabWidget->addTab(newScriptEditorWidget, title); _ScriptEditorWindowUI->tabWidget->addTab(newScriptEditorWidget, title);
_ScriptEditorWindowUI->tabWidget->setCurrentWidget(newScriptEditorWidget); _ScriptEditorWindowUI->tabWidget->setCurrentWidget(newScriptEditorWidget);
newScriptEditorWidget->setUpdatesEnabled(true); newScriptEditorWidget->setUpdatesEnabled(true);
@ -216,3 +219,15 @@ void ScriptEditorWindow::terminateCurrentTab() {
this->raise(); this->raise();
} }
} }
bool ScriptEditorWindow::autoReloadScripts() {
return _ScriptEditorWindowUI->autoReloadCheckBox->isChecked();
}
bool ScriptEditorWindow::event(QEvent* event) {
if (event->type() == QEvent::WindowActivate) {
emit windowActivated();
}
return QWidget::event(event);
}

View file

@ -26,9 +26,14 @@ public:
~ScriptEditorWindow(); ~ScriptEditorWindow();
void terminateCurrentTab(); void terminateCurrentTab();
bool autoReloadScripts();
signals:
void windowActivated();
protected: protected:
void closeEvent(QCloseEvent* event); void closeEvent(QCloseEvent* event);
virtual bool event(QEvent* event);
private: private:
Ui::ScriptEditorWindow* _ScriptEditorWindowUI; Ui::ScriptEditorWindow* _ScriptEditorWindowUI;

View file

@ -33,7 +33,7 @@
<number>0</number> <number>0</number>
</property> </property>
<item> <item>
<layout class="QHBoxLayout" name="horizontalLayout" stretch="0,0,0,0,0"> <layout class="QHBoxLayout" name="horizontalLayout" stretch="0,0,0,0,0,0">
<property name="spacing"> <property name="spacing">
<number>3</number> <number>3</number>
</property> </property>
@ -185,6 +185,16 @@
</property> </property>
</spacer> </spacer>
</item> </item>
<item>
<widget class="QCheckBox" name="autoReloadCheckBox">
<property name="styleSheet">
<string notr="true">font: 13px &quot;Helvetica&quot;,&quot;Arial&quot;,&quot;sans-serif&quot;;</string>
</property>
<property name="text">
<string>Automatically reload externally changed files</string>
</property>
</widget>
</item>
</layout> </layout>
</item> </item>
<item> <item>

View file

@ -349,6 +349,7 @@ void ScriptEngine::run() {
init(); init();
} }
_isRunning = true; _isRunning = true;
_isFinished = false;
emit runningStateChanged(); emit runningStateChanged();
QScriptValue result = _engine.evaluate(_scriptContents); QScriptValue result = _engine.evaluate(_scriptContents);