correct handleing of app shutdown and scripting enging termination

This commit is contained in:
ZappoMan 2013-12-16 11:26:30 -08:00
parent af52be7860
commit f9b7c23857
10 changed files with 79 additions and 19 deletions

View file

@ -240,9 +240,15 @@ Application::Application(int& argc, char** argv, timeval &startup_time) :
// probably not the right long term solution. But for now, we're going to do this to // probably not the right long term solution. But for now, we're going to do this to
// allow you to move a particle around in your hand // allow you to move a particle around in your hand
_particleEditSender.setPacketsPerSecond(3000); // super high!! _particleEditSender.setPacketsPerSecond(3000); // super high!!
printf("Application::Application() _voxelEditSender=%p\n", &_voxelEditSender);
printf("Application::Application() _particleEditSender=%p\n", &_particleEditSender);
} }
Application::~Application() { Application::~Application() {
qDebug() << "START Application::~Application()...\n";
// make sure we don't call the idle timer any more // make sure we don't call the idle timer any more
delete idleTimer; delete idleTimer;
@ -263,8 +269,7 @@ Application::~Application() {
delete _settings; delete _settings;
delete _followMode; delete _followMode;
delete _glWidget; delete _glWidget;
qDebug() << "DONE Application::~Application()...\n";
qDebug() << "DONE... Application::~Application()\n";
} }
void Application::restoreSizeAndPosition() { void Application::restoreSizeAndPosition() {
@ -1395,6 +1400,7 @@ void Application::terminate() {
pthread_join(_networkReceiveThread, NULL); pthread_join(_networkReceiveThread, NULL);
} }
printf("");
_voxelProcessor.terminate(); _voxelProcessor.terminate();
_voxelHideShowThread.terminate(); _voxelHideShowThread.terminate();
_voxelEditSender.terminate(); _voxelEditSender.terminate();
@ -4421,33 +4427,40 @@ void Application::loadScript() {
// start the script on a new thread... // start the script on a new thread...
bool wantMenuItems = true; // tells the ScriptEngine object to add menu items for itself bool wantMenuItems = true; // tells the ScriptEngine object to add menu items for itself
qDebug("about to create ScriptEngine\n");
ScriptEngine* scriptEngine = new ScriptEngine(script, wantMenuItems, fileName, Menu::getInstance()); ScriptEngine* scriptEngine = new ScriptEngine(script, wantMenuItems, fileName, Menu::getInstance());
qDebug("scriptEngine=%p\n",scriptEngine);
scriptEngine->setupMenuItems();
// setup the packet senders and jurisdiction listeners of the script engine's scripting interfaces so // setup the packet senders and jurisdiction listeners of the script engine's scripting interfaces so
// we can use the same ones from the application. // we can use the same ones from the application.
scriptEngine->getVoxelScriptingInterface()->setPacketSender(&_voxelEditSender); scriptEngine->getVoxelScriptingInterface()->setPacketSender(&_voxelEditSender);
scriptEngine->getParticleScriptingInterface()->setPacketSender(&_particleEditSender); scriptEngine->getParticleScriptingInterface()->setPacketSender(&_particleEditSender);
qDebug("about to create workerThread\n");
QThread* workerThread = new QThread(this); QThread* workerThread = new QThread(this);
qDebug("workerThread=%p\n",workerThread);
// when the worker thread is started, call our engine's run.. // when the worker thread is started, call our engine's run..
connect(workerThread, SIGNAL(started()), scriptEngine, SLOT(run())); connect(workerThread, SIGNAL(started()), scriptEngine, SLOT(run()));
// when the engine emits finished, call our threads quit
connect(scriptEngine, SIGNAL(finished()), workerThread, SLOT(quit()));
// when the thread is terminated, add both scriptEngine and thread to the deleteLater queue // when the thread is terminated, add both scriptEngine and thread to the deleteLater queue
connect(workerThread, SIGNAL(finished()), scriptEngine, SLOT(deleteLater())); connect(scriptEngine, SIGNAL(finished()), scriptEngine, SLOT(deleteLater()));
connect(workerThread, SIGNAL(finished()), workerThread, SLOT(deleteLater())); connect(workerThread, SIGNAL(finished()), workerThread, SLOT(deleteLater()));
// when the application is about to quit, stop our script engine so it unwinds properly // when the application is about to quit, stop our script engine so it unwinds properly
connect(this, SIGNAL(aboutToQuit()), scriptEngine, SLOT(stop())); connect(this, SIGNAL(aboutToQuit()), scriptEngine, SLOT(stop()));
qDebug("about to scriptEngine->moveToThread(workerThread)\n");
scriptEngine->moveToThread(workerThread); scriptEngine->moveToThread(workerThread);
qDebug("after scriptEngine->moveToThread(workerThread)\n");
// Starts an event loop, and emits workerThread->started() // Starts an event loop, and emits workerThread->started()
qDebug("about to workerThread->start()\n");
workerThread->start(); workerThread->start();
qDebug("after workerThread->start()\n");
// restore the main window's active state // restore the main window's active state

View file

@ -711,8 +711,6 @@ QAction* Menu::addCheckableActionToQMenuAndActionHash(QMenu* destinationMenu,
} }
void Menu::removeAction(QMenu* menu, const QString& actionName) { void Menu::removeAction(QMenu* menu, const QString& actionName) {
qDebug() << "removeAction() menu=" << menu << " actionName=" << actionName << "\n";
menu->removeAction(_actionHash.value(actionName)); menu->removeAction(_actionHash.value(actionName));
} }

View file

@ -35,6 +35,7 @@ OctreeEditPacketSender::OctreeEditPacketSender(PacketSenderNotify* notify) :
_serverJurisdictions(NULL), _serverJurisdictions(NULL),
_sequenceNumber(0), _sequenceNumber(0),
_maxPacketSize(MAX_PACKET_SIZE) { _maxPacketSize(MAX_PACKET_SIZE) {
printf("OctreeEditPacketSender::OctreeEditPacketSender() [%p] created... \n", this);
} }
OctreeEditPacketSender::~OctreeEditPacketSender() { OctreeEditPacketSender::~OctreeEditPacketSender() {
@ -48,6 +49,7 @@ OctreeEditPacketSender::~OctreeEditPacketSender() {
delete packet; delete packet;
_preServerPackets.erase(_preServerPackets.begin()); _preServerPackets.erase(_preServerPackets.begin());
} }
printf("OctreeEditPacketSender::~OctreeEditPacketSender() [%p] destroyed... \n", this);
} }

View file

@ -27,7 +27,7 @@ public:
}; };
/// Utility for processing, packing, queueing and sending of outbound edit messages. /// Utility for processing, packing, queueing and sending of outbound edit messages.
class OctreeEditPacketSender : public virtual PacketSender { class OctreeEditPacketSender : public PacketSender {
public: public:
OctreeEditPacketSender(PacketSenderNotify* notify = NULL); OctreeEditPacketSender(PacketSenderNotify* notify = NULL);
~OctreeEditPacketSender(); ~OctreeEditPacketSender();

View file

@ -16,10 +16,17 @@ OctreeScriptingInterface::OctreeScriptingInterface(OctreeEditPacketSender* packe
} }
OctreeScriptingInterface::~OctreeScriptingInterface() { OctreeScriptingInterface::~OctreeScriptingInterface() {
printf("OctreeScriptingInterface::~OctreeScriptingInterface()\n");
if (_managedJuridiciontListerner) { if (_managedJuridiciontListerner) {
printf("OctreeScriptingInterface::~OctreeScriptingInterface() _managedJuridiciontListerner... _jurisdictionListener->terminate()\n");
_jurisdictionListener->terminate();
printf("OctreeScriptingInterface::~OctreeScriptingInterface() _managedJuridiciontListerner... deleting _jurisdictionListener\n");
delete _jurisdictionListener; delete _jurisdictionListener;
} }
if (_managedPacketSender) { if (_managedPacketSender) {
printf("OctreeScriptingInterface::~OctreeScriptingInterface() _managedJuridiciontListerner... _packetSender->terminate()\n");
_packetSender->terminate();
printf("OctreeScriptingInterface::~OctreeScriptingInterface() _managedPacketSender... deleting _packetSender\n");
delete _packetSender; delete _packetSender;
} }
} }
@ -33,11 +40,13 @@ void OctreeScriptingInterface::setJurisdictionListener(JurisdictionListener* jur
} }
void OctreeScriptingInterface::init() { void OctreeScriptingInterface::init() {
printf("OctreeScriptingInterface::init()\n");
if (_jurisdictionListener) { if (_jurisdictionListener) {
_managedJuridiciontListerner = false; _managedJuridiciontListerner = false;
} else { } else {
_managedJuridiciontListerner = true; _managedJuridiciontListerner = true;
_jurisdictionListener = new JurisdictionListener(getServerNodeType()); _jurisdictionListener = new JurisdictionListener(getServerNodeType());
printf("OctreeScriptingInterface::init() _managedJuridiciontListerner=true, creating _jurisdictionListener=%p\n", _jurisdictionListener);
_jurisdictionListener->initialize(true); _jurisdictionListener->initialize(true);
} }
@ -46,6 +55,7 @@ void OctreeScriptingInterface::init() {
} else { } else {
_managedPacketSender = true; _managedPacketSender = true;
_packetSender = createPacketSender(); _packetSender = createPacketSender();
printf("OctreeScriptingInterface::init() _managedPacketSender=true, creating _packetSender=%p\n", _packetSender);
_packetSender->setServerJurisdictions(_jurisdictionListener->getJurisdictions()); _packetSender->setServerJurisdictions(_jurisdictionListener->getJurisdictions());
} }
} }

View file

@ -9,6 +9,7 @@
#include <QtCore/QCoreApplication> #include <QtCore/QCoreApplication>
#include <QtCore/QEventLoop> #include <QtCore/QEventLoop>
#include <QtCore/QTimer> #include <QtCore/QTimer>
#include <QtCore/QThread>
#include <QtNetwork/QNetworkAccessManager> #include <QtNetwork/QNetworkAccessManager>
#include <QtNetwork/QNetworkRequest> #include <QtNetwork/QNetworkRequest>
#include <QtNetwork/QNetworkReply> #include <QtNetwork/QNetworkReply>
@ -39,6 +40,11 @@ ScriptEngine::ScriptEngine(QString scriptContents, bool wantMenuItems,
_menu = menu; _menu = menu;
} }
ScriptEngine::~ScriptEngine() {
printf("ScriptEngine::~ScriptEngine()...\n");
}
void ScriptEngine::setupMenuItems() { void ScriptEngine::setupMenuItems() {
if (_menu && _wantMenuItems) { if (_menu && _wantMenuItems) {
_menu->addActionToQMenuAndActionHash(_menu->getActiveScriptsMenu(), _scriptMenuName, 0, this, SLOT(stop())); _menu->addActionToQMenuAndActionHash(_menu->getActiveScriptsMenu(), _scriptMenuName, 0, this, SLOT(stop()));
@ -53,7 +59,7 @@ void ScriptEngine::cleanMenuItems() {
void ScriptEngine::run() { void ScriptEngine::run() {
setupMenuItems(); //setupMenuItems();
QScriptEngine engine; QScriptEngine engine;
@ -103,12 +109,14 @@ void ScriptEngine::run() {
} }
if (_isFinished) { if (_isFinished) {
qDebug() << "line: " << __LINE__ << " _isFinished... breaking loop\n";
break; break;
} }
QCoreApplication::processEvents(); QCoreApplication::processEvents();
if (_isFinished) { if (_isFinished) {
qDebug() << "line: " << __LINE__ << " _isFinished... breaking loop\n";
break; break;
} }
@ -146,6 +154,23 @@ void ScriptEngine::run() {
} }
} }
cleanMenuItems(); cleanMenuItems();
qDebug() << "About to emit finished...\n";
// If we were on a thread, then wait till it's done
if (thread()) {
qDebug() << "line: " << __LINE__ << " calling quit()...\n";
thread()->quit();
}
qDebug() << "line: " << __LINE__ << " emitting finished()...\n";
emit finished(); emit finished();
} }
void ScriptEngine::stop() {
_isFinished = true;
qDebug() << "line: " << __LINE__ << " ScriptEngine::stop().. setting _isFinished = true...\n";
}
void ScriptEngine::applicationAboutToQuit() {
qDebug() << "line: " << __LINE__ << " ScriptEngine::applicationAboutToQuit().. setting _isFinished = true...\n";
stop();
}

View file

@ -25,17 +25,21 @@ public:
ScriptEngine(QString scriptContents, bool wantMenuItems = false, ScriptEngine(QString scriptContents, bool wantMenuItems = false,
const char* scriptMenuName = NULL, AbstractMenuInterface* menu = NULL); const char* scriptMenuName = NULL, AbstractMenuInterface* menu = NULL);
~ScriptEngine();
/// Access the VoxelScriptingInterface in order to initialize it with a custom packet sender and jurisdiction listener /// Access the VoxelScriptingInterface in order to initialize it with a custom packet sender and jurisdiction listener
VoxelScriptingInterface* getVoxelScriptingInterface() { return &_voxelScriptingInterface; } VoxelScriptingInterface* getVoxelScriptingInterface() { return &_voxelScriptingInterface; }
/// Access the ParticleScriptingInterface in order to initialize it with a custom packet sender and jurisdiction listener /// Access the ParticleScriptingInterface in order to initialize it with a custom packet sender and jurisdiction listener
ParticleScriptingInterface* getParticleScriptingInterface() { return &_particleScriptingInterface; } ParticleScriptingInterface* getParticleScriptingInterface() { return &_particleScriptingInterface; }
void setupMenuItems();
void cleanMenuItems();
public slots: public slots:
void run(); void run();
void stop() { void stop();
_isFinished = true; void applicationAboutToQuit();
}
signals: signals:
void willSendAudioDataCallback(); void willSendAudioDataCallback();
@ -45,8 +49,6 @@ protected:
QString _scriptContents; QString _scriptContents;
bool _isFinished; bool _isFinished;
void setupMenuItems();
void cleanMenuItems();
private: private:
VoxelScriptingInterface _voxelScriptingInterface; VoxelScriptingInterface _voxelScriptingInterface;

View file

@ -42,8 +42,11 @@ HifiSockAddr::HifiSockAddr(const QString& hostname, quint16 hostOrderPort) {
} }
HifiSockAddr& HifiSockAddr::operator=(const HifiSockAddr& rhsSockAddr) { HifiSockAddr& HifiSockAddr::operator=(const HifiSockAddr& rhsSockAddr) {
HifiSockAddr temp(rhsSockAddr); //HifiSockAddr temp(rhsSockAddr);
swap(temp); //swap(temp);
_address = rhsSockAddr._address;
_port = rhsSockAddr._port;
return *this; return *this;
} }

View file

@ -41,6 +41,11 @@ PacketSender::PacketSender(PacketSenderNotify* notify, int packetsPerSecond) :
_totalPacketsQueued(0), _totalPacketsQueued(0),
_totalBytesQueued(0) _totalBytesQueued(0)
{ {
printf("PacketSender[%p] created... \n", this);
}
PacketSender::~PacketSender() {
printf("PacketSender::~PacketSender[%p] destroyed... \n", this);
} }
@ -328,6 +333,7 @@ bool PacketSender::nonThreadedProcess() {
while ((packetsSentThisCall < packetsToSendThisCall) && (packetsLeft > 0)) { while ((packetsSentThisCall < packetsToSendThisCall) && (packetsLeft > 0)) {
lock(); lock();
NetworkPacket& packet = _packets.front(); NetworkPacket& packet = _packets.front();
printf("PacketSender[%p], copying packet... \n", this);
NetworkPacket temporary = packet; // make a copy NetworkPacket temporary = packet; // make a copy
_packets.erase(_packets.begin()); _packets.erase(_packets.begin());
packetsLeft = _packets.size(); packetsLeft = _packets.size();

View file

@ -36,6 +36,7 @@ public:
static const int MINIMAL_SLEEP_INTERVAL; static const int MINIMAL_SLEEP_INTERVAL;
PacketSender(PacketSenderNotify* notify = NULL, int packetsPerSecond = DEFAULT_PACKETS_PER_SECOND); PacketSender(PacketSenderNotify* notify = NULL, int packetsPerSecond = DEFAULT_PACKETS_PER_SECOND);
~PacketSender();
/// Add packet to outbound queue. /// Add packet to outbound queue.
/// \param HifiSockAddr& address the destination address /// \param HifiSockAddr& address the destination address