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
// allow you to move a particle around in your hand
_particleEditSender.setPacketsPerSecond(3000); // super high!!
printf("Application::Application() _voxelEditSender=%p\n", &_voxelEditSender);
printf("Application::Application() _particleEditSender=%p\n", &_particleEditSender);
}
Application::~Application() {
qDebug() << "START Application::~Application()...\n";
// make sure we don't call the idle timer any more
delete idleTimer;
@ -263,8 +269,7 @@ Application::~Application() {
delete _settings;
delete _followMode;
delete _glWidget;
qDebug() << "DONE... Application::~Application()\n";
qDebug() << "DONE Application::~Application()...\n";
}
void Application::restoreSizeAndPosition() {
@ -1395,6 +1400,7 @@ void Application::terminate() {
pthread_join(_networkReceiveThread, NULL);
}
printf("");
_voxelProcessor.terminate();
_voxelHideShowThread.terminate();
_voxelEditSender.terminate();
@ -4421,33 +4427,40 @@ void Application::loadScript() {
// start the script on a new thread...
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());
qDebug("scriptEngine=%p\n",scriptEngine);
scriptEngine->setupMenuItems();
// setup the packet senders and jurisdiction listeners of the script engine's scripting interfaces so
// we can use the same ones from the application.
scriptEngine->getVoxelScriptingInterface()->setPacketSender(&_voxelEditSender);
scriptEngine->getParticleScriptingInterface()->setPacketSender(&_particleEditSender);
qDebug("about to create workerThread\n");
QThread* workerThread = new QThread(this);
qDebug("workerThread=%p\n",workerThread);
// when the worker thread is started, call our engine's 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
connect(workerThread, SIGNAL(finished()), scriptEngine, SLOT(deleteLater()));
connect(scriptEngine, SIGNAL(finished()), scriptEngine, SLOT(deleteLater()));
connect(workerThread, SIGNAL(finished()), workerThread, SLOT(deleteLater()));
// when the application is about to quit, stop our script engine so it unwinds properly
connect(this, SIGNAL(aboutToQuit()), scriptEngine, SLOT(stop()));
qDebug("about to scriptEngine->moveToThread(workerThread)\n");
scriptEngine->moveToThread(workerThread);
qDebug("after scriptEngine->moveToThread(workerThread)\n");
// Starts an event loop, and emits workerThread->started()
qDebug("about to workerThread->start()\n");
workerThread->start();
qDebug("after workerThread->start()\n");
// 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) {
qDebug() << "removeAction() menu=" << menu << " actionName=" << actionName << "\n";
menu->removeAction(_actionHash.value(actionName));
}

View file

@ -35,6 +35,7 @@ OctreeEditPacketSender::OctreeEditPacketSender(PacketSenderNotify* notify) :
_serverJurisdictions(NULL),
_sequenceNumber(0),
_maxPacketSize(MAX_PACKET_SIZE) {
printf("OctreeEditPacketSender::OctreeEditPacketSender() [%p] created... \n", this);
}
OctreeEditPacketSender::~OctreeEditPacketSender() {
@ -48,6 +49,7 @@ OctreeEditPacketSender::~OctreeEditPacketSender() {
delete packet;
_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.
class OctreeEditPacketSender : public virtual PacketSender {
class OctreeEditPacketSender : public PacketSender {
public:
OctreeEditPacketSender(PacketSenderNotify* notify = NULL);
~OctreeEditPacketSender();

View file

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

View file

@ -9,6 +9,7 @@
#include <QtCore/QCoreApplication>
#include <QtCore/QEventLoop>
#include <QtCore/QTimer>
#include <QtCore/QThread>
#include <QtNetwork/QNetworkAccessManager>
#include <QtNetwork/QNetworkRequest>
#include <QtNetwork/QNetworkReply>
@ -39,6 +40,11 @@ ScriptEngine::ScriptEngine(QString scriptContents, bool wantMenuItems,
_menu = menu;
}
ScriptEngine::~ScriptEngine() {
printf("ScriptEngine::~ScriptEngine()...\n");
}
void ScriptEngine::setupMenuItems() {
if (_menu && _wantMenuItems) {
_menu->addActionToQMenuAndActionHash(_menu->getActiveScriptsMenu(), _scriptMenuName, 0, this, SLOT(stop()));
@ -53,7 +59,7 @@ void ScriptEngine::cleanMenuItems() {
void ScriptEngine::run() {
setupMenuItems();
//setupMenuItems();
QScriptEngine engine;
@ -103,12 +109,14 @@ void ScriptEngine::run() {
}
if (_isFinished) {
qDebug() << "line: " << __LINE__ << " _isFinished... breaking loop\n";
break;
}
QCoreApplication::processEvents();
if (_isFinished) {
qDebug() << "line: " << __LINE__ << " _isFinished... breaking loop\n";
break;
}
@ -146,6 +154,23 @@ void ScriptEngine::run() {
}
}
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();
}
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

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

View file

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

View file

@ -41,6 +41,11 @@ PacketSender::PacketSender(PacketSenderNotify* notify, int packetsPerSecond) :
_totalPacketsQueued(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)) {
lock();
NetworkPacket& packet = _packets.front();
printf("PacketSender[%p], copying packet... \n", this);
NetworkPacket temporary = packet; // make a copy
_packets.erase(_packets.begin());
packetsLeft = _packets.size();

View file

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