From c8c8bccbf3b7768c88791ce2e6f37fe10b2a319a Mon Sep 17 00:00:00 2001 From: matsukaze Date: Mon, 9 Jun 2014 17:52:50 -0400 Subject: [PATCH 1/6] Job #19766 BUG: Stop or reload all scripts crashes interface fixed. QUrl(name).toString() does not equal name, therefore removing name from ScriptEngineHash was failing, and a dangling pointer was left in the script engine hash map. --- interface/src/Application.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 574df09ee2..9fb821bff4 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3494,7 +3494,7 @@ ScriptEngine* Application::loadScript(const QString& scriptName, bool loadScript // start the script on a new thread... QUrl scriptUrl(scriptName); scriptEngine = new ScriptEngine(scriptUrl, &_controllerScriptingInterface); - _scriptEnginesHash.insert(scriptName, scriptEngine); + _scriptEnginesHash.insert(scriptUrl.toString(), scriptEngine); if (!scriptEngine->hasScript()) { qDebug() << "Application::loadScript(), script failed to load..."; From b4e984086505814cbc426226777b74a113da8362 Mon Sep 17 00:00:00 2001 From: matsukaze Date: Mon, 9 Jun 2014 23:15:45 -0400 Subject: [PATCH 2/6] Job #19766 BUG: Stop or reload all scripts crashes interface fix, part 2. Keep the scriptUrl internal to the ScriptEngine class and refer to it externally by the file name string. Change the ScriptEngine constructor to accept a filename QString, instead of a QUrl. Resolve constructor ambiguity in Particle, which creates anonymous ScriptEngine. --- interface/src/Application.cpp | 5 ++--- libraries/particles/src/Particle.cpp | 6 +++--- libraries/script-engine/src/ScriptEngine.cpp | 12 +++++------- libraries/script-engine/src/ScriptEngine.h | 2 +- 4 files changed, 11 insertions(+), 14 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 9fb821bff4..3ec5588c61 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3492,9 +3492,8 @@ ScriptEngine* Application::loadScript(const QString& scriptName, bool loadScript scriptEngine = new ScriptEngine(NO_SCRIPT, "", &_controllerScriptingInterface); } else { // start the script on a new thread... - QUrl scriptUrl(scriptName); - scriptEngine = new ScriptEngine(scriptUrl, &_controllerScriptingInterface); - _scriptEnginesHash.insert(scriptUrl.toString(), scriptEngine); + scriptEngine = new ScriptEngine(scriptName, &_controllerScriptingInterface); + _scriptEnginesHash.insert(scriptName, scriptEngine); if (!scriptEngine->hasScript()) { qDebug() << "Application::loadScript(), script failed to load..."; diff --git a/libraries/particles/src/Particle.cpp b/libraries/particles/src/Particle.cpp index 59265c00dc..90e59b9422 100644 --- a/libraries/particles/src/Particle.cpp +++ b/libraries/particles/src/Particle.cpp @@ -873,7 +873,7 @@ void Particle::endParticleScriptContext(ScriptEngine& engine, ParticleScriptObje void Particle::executeUpdateScripts() { // Only run this particle script if there's a script attached directly to the particle. if (!_script.isEmpty()) { - ScriptEngine engine(_script); + ScriptEngine engine(_script, QString("")); ParticleScriptObject particleScriptable(this); startParticleScriptContext(engine, particleScriptable); particleScriptable.emitUpdate(); @@ -884,7 +884,7 @@ void Particle::executeUpdateScripts() { void Particle::collisionWithParticle(Particle* other, const glm::vec3& penetration) { // Only run this particle script if there's a script attached directly to the particle. if (!_script.isEmpty()) { - ScriptEngine engine(_script); + ScriptEngine engine(_script, QString("")); ParticleScriptObject particleScriptable(this); startParticleScriptContext(engine, particleScriptable); ParticleScriptObject otherParticleScriptable(other); @@ -896,7 +896,7 @@ void Particle::collisionWithParticle(Particle* other, const glm::vec3& penetrati void Particle::collisionWithVoxel(VoxelDetail* voxelDetails, const glm::vec3& penetration) { // Only run this particle script if there's a script attached directly to the particle. if (!_script.isEmpty()) { - ScriptEngine engine(_script); + ScriptEngine engine(_script, QString("")); ParticleScriptObject particleScriptable(this); startParticleScriptContext(engine, particleScriptable); particleScriptable.emitCollisionWithVoxel(*voxelDetails, penetration); diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index a4aae61248..025f316d29 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -93,7 +93,7 @@ ScriptEngine::ScriptEngine(const QString& scriptContents, const QString& fileNam { } -ScriptEngine::ScriptEngine(const QUrl& scriptURL, +ScriptEngine::ScriptEngine(const QString& fileNameString, AbstractControllerScriptingInterface* controllerScriptingInterface) : _scriptContents(), _isFinished(false), @@ -110,21 +110,19 @@ ScriptEngine::ScriptEngine(const QUrl& scriptURL, _controllerScriptingInterface(controllerScriptingInterface), _avatarData(NULL), _scriptName(), - _fileNameString(), + _fileNameString(fileNameString), _quatLibrary(), _vec3Library(), _uuidLibrary(), _animationCache(this) { - QString scriptURLString = scriptURL.toString(); - _fileNameString = scriptURLString; - - QUrl url(scriptURL); + QUrl url(fileNameString); + QString scriptUrlString = url.toString(); // if the scheme length is one or lower, maybe they typed in a file, let's try const int WINDOWS_DRIVE_LETTER_SIZE = 1; if (url.scheme().size() <= WINDOWS_DRIVE_LETTER_SIZE) { - url = QUrl::fromLocalFile(scriptURLString); + url = QUrl::fromLocalFile(scriptUrlString); } // ok, let's see if it's valid... and if so, load it diff --git a/libraries/script-engine/src/ScriptEngine.h b/libraries/script-engine/src/ScriptEngine.h index bf2ac40568..f88017515e 100644 --- a/libraries/script-engine/src/ScriptEngine.h +++ b/libraries/script-engine/src/ScriptEngine.h @@ -40,7 +40,7 @@ const unsigned int SCRIPT_DATA_CALLBACK_USECS = floor(((1.0 / 60.0f) * 1000 * 10 class ScriptEngine : public QObject { Q_OBJECT public: - ScriptEngine(const QUrl& scriptURL, + ScriptEngine(const QString& fileNameString, AbstractControllerScriptingInterface* controllerScriptingInterface = NULL); ScriptEngine(const QString& scriptContents = NO_SCRIPT, From a48f38b1d263a04f0fba5fce7a3502175e2078b9 Mon Sep 17 00:00:00 2001 From: matsukaze Date: Tue, 10 Jun 2014 21:32:23 -0400 Subject: [PATCH 3/6] Revert "Job #19766 BUG: Stop or reload all scripts crashes interface fix, part 2." This reverts commit b4e984086505814cbc426226777b74a113da8362. --- interface/src/Application.cpp | 5 +++-- libraries/particles/src/Particle.cpp | 6 +++--- libraries/script-engine/src/ScriptEngine.cpp | 12 +++++++----- libraries/script-engine/src/ScriptEngine.h | 2 +- 4 files changed, 14 insertions(+), 11 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 3ec5588c61..9fb821bff4 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3492,8 +3492,9 @@ ScriptEngine* Application::loadScript(const QString& scriptName, bool loadScript scriptEngine = new ScriptEngine(NO_SCRIPT, "", &_controllerScriptingInterface); } else { // start the script on a new thread... - scriptEngine = new ScriptEngine(scriptName, &_controllerScriptingInterface); - _scriptEnginesHash.insert(scriptName, scriptEngine); + QUrl scriptUrl(scriptName); + scriptEngine = new ScriptEngine(scriptUrl, &_controllerScriptingInterface); + _scriptEnginesHash.insert(scriptUrl.toString(), scriptEngine); if (!scriptEngine->hasScript()) { qDebug() << "Application::loadScript(), script failed to load..."; diff --git a/libraries/particles/src/Particle.cpp b/libraries/particles/src/Particle.cpp index 90e59b9422..59265c00dc 100644 --- a/libraries/particles/src/Particle.cpp +++ b/libraries/particles/src/Particle.cpp @@ -873,7 +873,7 @@ void Particle::endParticleScriptContext(ScriptEngine& engine, ParticleScriptObje void Particle::executeUpdateScripts() { // Only run this particle script if there's a script attached directly to the particle. if (!_script.isEmpty()) { - ScriptEngine engine(_script, QString("")); + ScriptEngine engine(_script); ParticleScriptObject particleScriptable(this); startParticleScriptContext(engine, particleScriptable); particleScriptable.emitUpdate(); @@ -884,7 +884,7 @@ void Particle::executeUpdateScripts() { void Particle::collisionWithParticle(Particle* other, const glm::vec3& penetration) { // Only run this particle script if there's a script attached directly to the particle. if (!_script.isEmpty()) { - ScriptEngine engine(_script, QString("")); + ScriptEngine engine(_script); ParticleScriptObject particleScriptable(this); startParticleScriptContext(engine, particleScriptable); ParticleScriptObject otherParticleScriptable(other); @@ -896,7 +896,7 @@ void Particle::collisionWithParticle(Particle* other, const glm::vec3& penetrati void Particle::collisionWithVoxel(VoxelDetail* voxelDetails, const glm::vec3& penetration) { // Only run this particle script if there's a script attached directly to the particle. if (!_script.isEmpty()) { - ScriptEngine engine(_script, QString("")); + ScriptEngine engine(_script); ParticleScriptObject particleScriptable(this); startParticleScriptContext(engine, particleScriptable); particleScriptable.emitCollisionWithVoxel(*voxelDetails, penetration); diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index 025f316d29..a4aae61248 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -93,7 +93,7 @@ ScriptEngine::ScriptEngine(const QString& scriptContents, const QString& fileNam { } -ScriptEngine::ScriptEngine(const QString& fileNameString, +ScriptEngine::ScriptEngine(const QUrl& scriptURL, AbstractControllerScriptingInterface* controllerScriptingInterface) : _scriptContents(), _isFinished(false), @@ -110,19 +110,21 @@ ScriptEngine::ScriptEngine(const QString& fileNameString, _controllerScriptingInterface(controllerScriptingInterface), _avatarData(NULL), _scriptName(), - _fileNameString(fileNameString), + _fileNameString(), _quatLibrary(), _vec3Library(), _uuidLibrary(), _animationCache(this) { - QUrl url(fileNameString); - QString scriptUrlString = url.toString(); + QString scriptURLString = scriptURL.toString(); + _fileNameString = scriptURLString; + + QUrl url(scriptURL); // if the scheme length is one or lower, maybe they typed in a file, let's try const int WINDOWS_DRIVE_LETTER_SIZE = 1; if (url.scheme().size() <= WINDOWS_DRIVE_LETTER_SIZE) { - url = QUrl::fromLocalFile(scriptUrlString); + url = QUrl::fromLocalFile(scriptURLString); } // ok, let's see if it's valid... and if so, load it diff --git a/libraries/script-engine/src/ScriptEngine.h b/libraries/script-engine/src/ScriptEngine.h index f88017515e..bf2ac40568 100644 --- a/libraries/script-engine/src/ScriptEngine.h +++ b/libraries/script-engine/src/ScriptEngine.h @@ -40,7 +40,7 @@ const unsigned int SCRIPT_DATA_CALLBACK_USECS = floor(((1.0 / 60.0f) * 1000 * 10 class ScriptEngine : public QObject { Q_OBJECT public: - ScriptEngine(const QString& fileNameString, + ScriptEngine(const QUrl& scriptURL, AbstractControllerScriptingInterface* controllerScriptingInterface = NULL); ScriptEngine(const QString& scriptContents = NO_SCRIPT, From 46f2ab73bccf6fa8669856534f0c20f96ee8c416 Mon Sep 17 00:00:00 2001 From: matsukaze Date: Tue, 10 Jun 2014 22:29:58 -0400 Subject: [PATCH 4/6] Job #19766 BUG: Stop or reload all scripts crashes interface fixed, part 3 Move the conversion of scriptName to QUrl to the beginning of Application::loadScript. Use the scriptURLString to query the _scriptEngineHash map. --- CMakeLists.txt | 4 + assignment-client/src/AssignmentClient.cpp | 123 +++++++++++++++------ assignment-client/src/AssignmentClient.h | 48 ++++++++ interface/src/Application.cpp | 9 +- interface/src/Audio.cpp | 29 ++++- 5 files changed, 175 insertions(+), 38 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index cb1e4224cf..298b9a791e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,6 +20,10 @@ if (NOT QT_CMAKE_PREFIX_PATH) set(QT_CMAKE_PREFIX_PATH $ENV{QT_CMAKE_PREFIX_PATH}) endif () +if (NOT ZLIB_ROOT) + set(ZLIB_ROOT $ENV{ZLIB_ROOT}) +endif () + set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} ${QT_CMAKE_PREFIX_PATH}) # set our Base SDK to 10.8 diff --git a/assignment-client/src/AssignmentClient.cpp b/assignment-client/src/AssignmentClient.cpp index 009bd42e88..a2faaab651 100644 --- a/assignment-client/src/AssignmentClient.cpp +++ b/assignment-client/src/AssignmentClient.cpp @@ -33,6 +33,64 @@ SharedAssignmentPointer AssignmentClient::_currentAssignment; int hifiSockAddrMeta = qRegisterMetaType("HifiSockAddr"); +template +class Parse : public Parser { +public: + Parse(const QString& option, bool required, T* value) : Parser(option, required), _value(value) {} + bool parse(const QStringList& argumentList); +private: + T* _value; +}; + +template<> +bool Parse::parse(const QStringList& argumentList) { + int argumentIndex = findToken(argumentList); + if (argumentIndex != -1) { + argumentIndex++; + if (argumentList.size() > argumentIndex) { + bool ok; + int value = argumentList[argumentIndex].toInt(&ok); + if (ok) { + *_value = static_cast(value); + } + validateValue(ok); + } else { + valueNotSpecified(); + } + } + return isValid(); +} + +template<> +bool Parse::parse(const QStringList& argumentList) { + int argumentIndex = findToken(argumentList); + if (argumentIndex != -1) { + argumentIndex++; + if (argumentList.size() > argumentIndex) { + *_value = QString(argumentList[argumentIndex]); + validateValue(!_value->isNull()); + } else { + valueNotSpecified(); + } + } + return isValid(); +} + +template<> +bool Parse::parse(const QStringList& argumentList) { + int argumentIndex = findToken(argumentList); + if (argumentIndex != -1) { + argumentIndex++; + if (argumentList.size() > argumentIndex) { + *_value = argumentList[argumentIndex]; + validateValue(true); + } else { + valueNotSpecified(); + } + } + return isValid(); +} + AssignmentClient::AssignmentClient(int &argc, char **argv) : QCoreApplication(argc, argv), _assignmentServerHostname(DEFAULT_ASSIGNMENT_SERVER_HOSTNAME) @@ -43,40 +101,42 @@ AssignmentClient::AssignmentClient(int &argc, char **argv) : QSettings::setDefaultFormat(QSettings::IniFormat); QStringList argumentList = arguments(); - + + // Define parser tokens + const QString ASSIGNMENT_TYPE_OVERRIDE_OPTION = "-t"; + const QString ASSIGNMENT_POOL_OPTION = "--pool"; + const QString ASSIGNMENT_WALLET_DESTINATION_ID_OPTION = "--wallet"; + const QString CUSTOM_ASSIGNMENT_SERVER_HOSTNAME_OPTION = "-a"; + + // Define parser results + Assignment::Type requestAssignmentType = Assignment::AllTypes; + QString assignmentPool; + QUuid walletUUID; + + // Define parsers + _parsers.insert(ASSIGNMENT_TYPE_OVERRIDE_OPTION, new Parse(ASSIGNMENT_TYPE_OVERRIDE_OPTION, false, &requestAssignmentType)); + _parsers.insert(ASSIGNMENT_POOL_OPTION, new Parse(ASSIGNMENT_POOL_OPTION, false, &assignmentPool)); + _parsers.insert(ASSIGNMENT_WALLET_DESTINATION_ID_OPTION, new Parse(ASSIGNMENT_WALLET_DESTINATION_ID_OPTION, false, &walletUUID)); + _parsers.insert(CUSTOM_ASSIGNMENT_SERVER_HOSTNAME_OPTION, new Parse(CUSTOM_ASSIGNMENT_SERVER_HOSTNAME_OPTION, false, &_assignmentServerHostname)); + // register meta type is required for queued invoke method on Assignment subclasses // set the logging target to the the CHILD_TARGET_NAME Logging::setTargetName(ASSIGNMENT_CLIENT_TARGET_NAME); - const QString ASSIGNMENT_TYPE_OVVERIDE_OPTION = "-t"; - int argumentIndex = argumentList.indexOf(ASSIGNMENT_TYPE_OVVERIDE_OPTION); - - Assignment::Type requestAssignmentType = Assignment::AllTypes; - - if (argumentIndex != -1) { - requestAssignmentType = (Assignment::Type) argumentList[argumentIndex + 1].toInt(); + foreach (Parser* option, _parsers) { + if (option) { + option->parse(argumentList); + } } - - const QString ASSIGNMENT_POOL_OPTION = "--pool"; - - argumentIndex = argumentList.indexOf(ASSIGNMENT_POOL_OPTION); - - QString assignmentPool; - - if (argumentIndex != -1) { - assignmentPool = argumentList[argumentIndex + 1]; - } - + // setup our _requestAssignment member variable from the passed arguments _requestAssignment = Assignment(Assignment::RequestCommand, requestAssignmentType, assignmentPool); // check if we were passed a wallet UUID on the command line // this would represent where the user running AC wants funds sent to - - const QString ASSIGNMENT_WALLET_DESTINATION_ID_OPTION = "--wallet"; - if ((argumentIndex = argumentList.indexOf(ASSIGNMENT_WALLET_DESTINATION_ID_OPTION)) != -1) { - QUuid walletUUID = QString(argumentList[argumentIndex + 1]); + if (_parsers[ASSIGNMENT_WALLET_DESTINATION_ID_OPTION]->exists() && + _parsers[ASSIGNMENT_WALLET_DESTINATION_ID_OPTION]->isValid()) { qDebug() << "The destination wallet UUID for credits is" << uuidStringWithoutCurlyBraces(walletUUID); _requestAssignment.setWalletUUID(walletUUID); } @@ -84,14 +144,9 @@ AssignmentClient::AssignmentClient(int &argc, char **argv) : // create a NodeList as an unassigned client NodeList* nodeList = NodeList::createInstance(NodeType::Unassigned); - // check for an overriden assignment server hostname - const QString CUSTOM_ASSIGNMENT_SERVER_HOSTNAME_OPTION = "-a"; - - argumentIndex = argumentList.indexOf(CUSTOM_ASSIGNMENT_SERVER_HOSTNAME_OPTION); - - if (argumentIndex != -1) { - _assignmentServerHostname = argumentList[argumentIndex + 1]; - + // check for an overriden assignment server hostname + if (_parsers[CUSTOM_ASSIGNMENT_SERVER_HOSTNAME_OPTION]->exists() && + _parsers[CUSTOM_ASSIGNMENT_SERVER_HOSTNAME_OPTION]->isValid()) { // set the custom assignment socket on our NodeList HifiSockAddr customAssignmentSocket = HifiSockAddr(_assignmentServerHostname, DEFAULT_DOMAIN_SERVER_PORT); @@ -113,6 +168,12 @@ AssignmentClient::AssignmentClient(int &argc, char **argv) : this, &AssignmentClient::handleAuthenticationRequest); } +AssignmentClient::~AssignmentClient() { + foreach (Parser* option, _parsers) { + delete option; + } +} + void AssignmentClient::sendAssignmentRequest() { if (!_currentAssignment) { NodeList::getInstance()->sendAssignment(_requestAssignment); diff --git a/assignment-client/src/AssignmentClient.h b/assignment-client/src/AssignmentClient.h index 9834402dbf..8951d44135 100644 --- a/assignment-client/src/AssignmentClient.h +++ b/assignment-client/src/AssignmentClient.h @@ -16,11 +16,57 @@ #include "ThreadedAssignment.h" +class Parser { +public: + Parser(const QString& option, bool required) : _option(option), _required(required), _exists(false), _isValid(false) {} + virtual bool parse(const QStringList& argumentList) { return false; } + bool exists() { return _exists; } + bool isValid() { return _isValid; } + +protected: + int findToken(const QStringList& argumentList) { + int argumentIndex = argumentList.indexOf(_option); + validateOption(argumentIndex); + return argumentIndex; + } + + void validateOption(int index) { + _exists = true; + if (index == -1) { + _exists = false; + if (_required) { + qDebug() << "Command line option " << _option << " is missing"; + } + } + } + + void valueNotSpecified() { + _isValid = false; + qDebug() << "Command line option " << _option << " value is missing"; + } + + void validateValue(bool ok) { + _isValid = ok; + if (!ok) { + qDebug() << "Command line option " << _option << " value is invalid"; + } + } + +private: + QString _option; + bool _required; + bool _exists; + bool _isValid; +}; + class AssignmentClient : public QCoreApplication { Q_OBJECT public: AssignmentClient(int &argc, char **argv); + ~AssignmentClient(); + static const SharedAssignmentPointer& getCurrentAssignment() { return _currentAssignment; } + private slots: void sendAssignmentRequest(); void readPendingDatagrams(); @@ -31,6 +77,8 @@ private: Assignment _requestAssignment; static SharedAssignmentPointer _currentAssignment; QString _assignmentServerHostname; + + QMap _parsers; }; #endif // hifi_AssignmentClient_h diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 9fb821bff4..25a5ba8007 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3483,8 +3483,10 @@ void Application::saveScripts() { } ScriptEngine* Application::loadScript(const QString& scriptName, bool loadScriptFromEditor) { - if(loadScriptFromEditor && _scriptEnginesHash.contains(scriptName) && !_scriptEnginesHash[scriptName]->isFinished()){ - return _scriptEnginesHash[scriptName]; + QUrl scriptUrl(scriptName); + const QString& scriptURLString = scriptUrl.toString(); + if(loadScriptFromEditor && _scriptEnginesHash.contains(scriptURLString) && !_scriptEnginesHash[scriptURLString]->isFinished()){ + return _scriptEnginesHash[scriptURLString]; } ScriptEngine* scriptEngine; @@ -3492,9 +3494,8 @@ ScriptEngine* Application::loadScript(const QString& scriptName, bool loadScript scriptEngine = new ScriptEngine(NO_SCRIPT, "", &_controllerScriptingInterface); } else { // start the script on a new thread... - QUrl scriptUrl(scriptName); scriptEngine = new ScriptEngine(scriptUrl, &_controllerScriptingInterface); - _scriptEnginesHash.insert(scriptUrl.toString(), scriptEngine); + _scriptEnginesHash.insert(scriptURLString, scriptEngine); if (!scriptEngine->hasScript()) { qDebug() << "Application::loadScript(), script failed to load..."; diff --git a/interface/src/Audio.cpp b/interface/src/Audio.cpp index ebc228a13d..1ecfad9007 100644 --- a/interface/src/Audio.cpp +++ b/interface/src/Audio.cpp @@ -219,8 +219,9 @@ QAudioDeviceInfo defaultAudioDeviceForMode(QAudio::Mode mode) { pPropertyStore->Release(); pPropertyStore = NULL; //QAudio devices seems to only take the 31 first characters of the Friendly Device Name. - const DWORD QT_WIN_MAX_AUDIO_DEVICENAME_LEN = 31; - deviceName = QString::fromWCharArray((wchar_t*)pv.pwszVal).left(QT_WIN_MAX_AUDIO_DEVICENAME_LEN); + //const DWORD QT_WIN_MAX_AUDIO_DEVICENAME_LEN = 31; + // deviceName = QString::fromWCharArray((wchar_t*)pv.pwszVal).left(QT_WIN_MAX_AUDIO_DEVICENAME_LEN); + deviceName = QString::fromWCharArray((wchar_t*)pv.pwszVal); qDebug() << (mode == QAudio::AudioOutput ? "output" : "input") << " device:" << deviceName; PropVariantClear(&pv); } @@ -1077,13 +1078,35 @@ void Audio::renderToolBox(int x, int y, bool boxed) { } _iconBounds = QRect(x, y, MUTE_ICON_SIZE, MUTE_ICON_SIZE); + + static quint64 last = 0; // Hold the last time sample + if (!_muted) { + last = 0; + glColor3f(1,1,1); glBindTexture(GL_TEXTURE_2D, _micTextureId); } else { + quint64 usecTimestampNow(); + static const float CYCLE_DURATION = 3.0f; // Seconds + quint64 now = usecTimestampNow(); + float delta = (float)(now - last) / 1000000.0f; + float from = 1.0f; // Linear fade down (upper bound) + float to = 0.3f; // Linear fade down (lower bound) + + if (delta > CYCLE_DURATION) { + last = now; + delta -= (int)delta; + } else if (delta > (CYCLE_DURATION * 0.5f)) { + // Linear fade up + from = 0.3f; // lower bound + to = 1.0f; // upper bound + } + // Compute a linear ramp to fade the color from full to partial saturation + float linearRamp = (from - to) * delta / CYCLE_DURATION + to; + glColor3f(linearRamp, linearRamp, linearRamp); glBindTexture(GL_TEXTURE_2D, _muteTextureId); } - glColor3f(1,1,1); glBegin(GL_QUADS); glTexCoord2f(1, 1); From 1e1cc69287d8cdaaf304bbfc05da56ae9564016f Mon Sep 17 00:00:00 2001 From: matsukaze Date: Tue, 10 Jun 2014 22:37:34 -0400 Subject: [PATCH 5/6] Revert "Job #19766 BUG: Stop or reload all scripts crashes interface fixed, part 3" This reverts commit 46f2ab73bccf6fa8669856534f0c20f96ee8c416. --- CMakeLists.txt | 4 - assignment-client/src/AssignmentClient.cpp | 123 ++++++--------------- assignment-client/src/AssignmentClient.h | 48 -------- interface/src/Application.cpp | 9 +- interface/src/Audio.cpp | 29 +---- 5 files changed, 38 insertions(+), 175 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 298b9a791e..cb1e4224cf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,10 +20,6 @@ if (NOT QT_CMAKE_PREFIX_PATH) set(QT_CMAKE_PREFIX_PATH $ENV{QT_CMAKE_PREFIX_PATH}) endif () -if (NOT ZLIB_ROOT) - set(ZLIB_ROOT $ENV{ZLIB_ROOT}) -endif () - set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} ${QT_CMAKE_PREFIX_PATH}) # set our Base SDK to 10.8 diff --git a/assignment-client/src/AssignmentClient.cpp b/assignment-client/src/AssignmentClient.cpp index a2faaab651..009bd42e88 100644 --- a/assignment-client/src/AssignmentClient.cpp +++ b/assignment-client/src/AssignmentClient.cpp @@ -33,64 +33,6 @@ SharedAssignmentPointer AssignmentClient::_currentAssignment; int hifiSockAddrMeta = qRegisterMetaType("HifiSockAddr"); -template -class Parse : public Parser { -public: - Parse(const QString& option, bool required, T* value) : Parser(option, required), _value(value) {} - bool parse(const QStringList& argumentList); -private: - T* _value; -}; - -template<> -bool Parse::parse(const QStringList& argumentList) { - int argumentIndex = findToken(argumentList); - if (argumentIndex != -1) { - argumentIndex++; - if (argumentList.size() > argumentIndex) { - bool ok; - int value = argumentList[argumentIndex].toInt(&ok); - if (ok) { - *_value = static_cast(value); - } - validateValue(ok); - } else { - valueNotSpecified(); - } - } - return isValid(); -} - -template<> -bool Parse::parse(const QStringList& argumentList) { - int argumentIndex = findToken(argumentList); - if (argumentIndex != -1) { - argumentIndex++; - if (argumentList.size() > argumentIndex) { - *_value = QString(argumentList[argumentIndex]); - validateValue(!_value->isNull()); - } else { - valueNotSpecified(); - } - } - return isValid(); -} - -template<> -bool Parse::parse(const QStringList& argumentList) { - int argumentIndex = findToken(argumentList); - if (argumentIndex != -1) { - argumentIndex++; - if (argumentList.size() > argumentIndex) { - *_value = argumentList[argumentIndex]; - validateValue(true); - } else { - valueNotSpecified(); - } - } - return isValid(); -} - AssignmentClient::AssignmentClient(int &argc, char **argv) : QCoreApplication(argc, argv), _assignmentServerHostname(DEFAULT_ASSIGNMENT_SERVER_HOSTNAME) @@ -101,42 +43,40 @@ AssignmentClient::AssignmentClient(int &argc, char **argv) : QSettings::setDefaultFormat(QSettings::IniFormat); QStringList argumentList = arguments(); - - // Define parser tokens - const QString ASSIGNMENT_TYPE_OVERRIDE_OPTION = "-t"; - const QString ASSIGNMENT_POOL_OPTION = "--pool"; - const QString ASSIGNMENT_WALLET_DESTINATION_ID_OPTION = "--wallet"; - const QString CUSTOM_ASSIGNMENT_SERVER_HOSTNAME_OPTION = "-a"; - - // Define parser results - Assignment::Type requestAssignmentType = Assignment::AllTypes; - QString assignmentPool; - QUuid walletUUID; - - // Define parsers - _parsers.insert(ASSIGNMENT_TYPE_OVERRIDE_OPTION, new Parse(ASSIGNMENT_TYPE_OVERRIDE_OPTION, false, &requestAssignmentType)); - _parsers.insert(ASSIGNMENT_POOL_OPTION, new Parse(ASSIGNMENT_POOL_OPTION, false, &assignmentPool)); - _parsers.insert(ASSIGNMENT_WALLET_DESTINATION_ID_OPTION, new Parse(ASSIGNMENT_WALLET_DESTINATION_ID_OPTION, false, &walletUUID)); - _parsers.insert(CUSTOM_ASSIGNMENT_SERVER_HOSTNAME_OPTION, new Parse(CUSTOM_ASSIGNMENT_SERVER_HOSTNAME_OPTION, false, &_assignmentServerHostname)); - + // register meta type is required for queued invoke method on Assignment subclasses // set the logging target to the the CHILD_TARGET_NAME Logging::setTargetName(ASSIGNMENT_CLIENT_TARGET_NAME); - foreach (Parser* option, _parsers) { - if (option) { - option->parse(argumentList); - } + const QString ASSIGNMENT_TYPE_OVVERIDE_OPTION = "-t"; + int argumentIndex = argumentList.indexOf(ASSIGNMENT_TYPE_OVVERIDE_OPTION); + + Assignment::Type requestAssignmentType = Assignment::AllTypes; + + if (argumentIndex != -1) { + requestAssignmentType = (Assignment::Type) argumentList[argumentIndex + 1].toInt(); } - + + const QString ASSIGNMENT_POOL_OPTION = "--pool"; + + argumentIndex = argumentList.indexOf(ASSIGNMENT_POOL_OPTION); + + QString assignmentPool; + + if (argumentIndex != -1) { + assignmentPool = argumentList[argumentIndex + 1]; + } + // setup our _requestAssignment member variable from the passed arguments _requestAssignment = Assignment(Assignment::RequestCommand, requestAssignmentType, assignmentPool); // check if we were passed a wallet UUID on the command line // this would represent where the user running AC wants funds sent to - if (_parsers[ASSIGNMENT_WALLET_DESTINATION_ID_OPTION]->exists() && - _parsers[ASSIGNMENT_WALLET_DESTINATION_ID_OPTION]->isValid()) { + + const QString ASSIGNMENT_WALLET_DESTINATION_ID_OPTION = "--wallet"; + if ((argumentIndex = argumentList.indexOf(ASSIGNMENT_WALLET_DESTINATION_ID_OPTION)) != -1) { + QUuid walletUUID = QString(argumentList[argumentIndex + 1]); qDebug() << "The destination wallet UUID for credits is" << uuidStringWithoutCurlyBraces(walletUUID); _requestAssignment.setWalletUUID(walletUUID); } @@ -144,9 +84,14 @@ AssignmentClient::AssignmentClient(int &argc, char **argv) : // create a NodeList as an unassigned client NodeList* nodeList = NodeList::createInstance(NodeType::Unassigned); - // check for an overriden assignment server hostname - if (_parsers[CUSTOM_ASSIGNMENT_SERVER_HOSTNAME_OPTION]->exists() && - _parsers[CUSTOM_ASSIGNMENT_SERVER_HOSTNAME_OPTION]->isValid()) { + // check for an overriden assignment server hostname + const QString CUSTOM_ASSIGNMENT_SERVER_HOSTNAME_OPTION = "-a"; + + argumentIndex = argumentList.indexOf(CUSTOM_ASSIGNMENT_SERVER_HOSTNAME_OPTION); + + if (argumentIndex != -1) { + _assignmentServerHostname = argumentList[argumentIndex + 1]; + // set the custom assignment socket on our NodeList HifiSockAddr customAssignmentSocket = HifiSockAddr(_assignmentServerHostname, DEFAULT_DOMAIN_SERVER_PORT); @@ -168,12 +113,6 @@ AssignmentClient::AssignmentClient(int &argc, char **argv) : this, &AssignmentClient::handleAuthenticationRequest); } -AssignmentClient::~AssignmentClient() { - foreach (Parser* option, _parsers) { - delete option; - } -} - void AssignmentClient::sendAssignmentRequest() { if (!_currentAssignment) { NodeList::getInstance()->sendAssignment(_requestAssignment); diff --git a/assignment-client/src/AssignmentClient.h b/assignment-client/src/AssignmentClient.h index 8951d44135..9834402dbf 100644 --- a/assignment-client/src/AssignmentClient.h +++ b/assignment-client/src/AssignmentClient.h @@ -16,57 +16,11 @@ #include "ThreadedAssignment.h" -class Parser { -public: - Parser(const QString& option, bool required) : _option(option), _required(required), _exists(false), _isValid(false) {} - virtual bool parse(const QStringList& argumentList) { return false; } - bool exists() { return _exists; } - bool isValid() { return _isValid; } - -protected: - int findToken(const QStringList& argumentList) { - int argumentIndex = argumentList.indexOf(_option); - validateOption(argumentIndex); - return argumentIndex; - } - - void validateOption(int index) { - _exists = true; - if (index == -1) { - _exists = false; - if (_required) { - qDebug() << "Command line option " << _option << " is missing"; - } - } - } - - void valueNotSpecified() { - _isValid = false; - qDebug() << "Command line option " << _option << " value is missing"; - } - - void validateValue(bool ok) { - _isValid = ok; - if (!ok) { - qDebug() << "Command line option " << _option << " value is invalid"; - } - } - -private: - QString _option; - bool _required; - bool _exists; - bool _isValid; -}; - class AssignmentClient : public QCoreApplication { Q_OBJECT public: AssignmentClient(int &argc, char **argv); - ~AssignmentClient(); - static const SharedAssignmentPointer& getCurrentAssignment() { return _currentAssignment; } - private slots: void sendAssignmentRequest(); void readPendingDatagrams(); @@ -77,8 +31,6 @@ private: Assignment _requestAssignment; static SharedAssignmentPointer _currentAssignment; QString _assignmentServerHostname; - - QMap _parsers; }; #endif // hifi_AssignmentClient_h diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 25a5ba8007..9fb821bff4 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3483,10 +3483,8 @@ void Application::saveScripts() { } ScriptEngine* Application::loadScript(const QString& scriptName, bool loadScriptFromEditor) { - QUrl scriptUrl(scriptName); - const QString& scriptURLString = scriptUrl.toString(); - if(loadScriptFromEditor && _scriptEnginesHash.contains(scriptURLString) && !_scriptEnginesHash[scriptURLString]->isFinished()){ - return _scriptEnginesHash[scriptURLString]; + if(loadScriptFromEditor && _scriptEnginesHash.contains(scriptName) && !_scriptEnginesHash[scriptName]->isFinished()){ + return _scriptEnginesHash[scriptName]; } ScriptEngine* scriptEngine; @@ -3494,8 +3492,9 @@ ScriptEngine* Application::loadScript(const QString& scriptName, bool loadScript scriptEngine = new ScriptEngine(NO_SCRIPT, "", &_controllerScriptingInterface); } else { // start the script on a new thread... + QUrl scriptUrl(scriptName); scriptEngine = new ScriptEngine(scriptUrl, &_controllerScriptingInterface); - _scriptEnginesHash.insert(scriptURLString, scriptEngine); + _scriptEnginesHash.insert(scriptUrl.toString(), scriptEngine); if (!scriptEngine->hasScript()) { qDebug() << "Application::loadScript(), script failed to load..."; diff --git a/interface/src/Audio.cpp b/interface/src/Audio.cpp index 1ecfad9007..ebc228a13d 100644 --- a/interface/src/Audio.cpp +++ b/interface/src/Audio.cpp @@ -219,9 +219,8 @@ QAudioDeviceInfo defaultAudioDeviceForMode(QAudio::Mode mode) { pPropertyStore->Release(); pPropertyStore = NULL; //QAudio devices seems to only take the 31 first characters of the Friendly Device Name. - //const DWORD QT_WIN_MAX_AUDIO_DEVICENAME_LEN = 31; - // deviceName = QString::fromWCharArray((wchar_t*)pv.pwszVal).left(QT_WIN_MAX_AUDIO_DEVICENAME_LEN); - deviceName = QString::fromWCharArray((wchar_t*)pv.pwszVal); + const DWORD QT_WIN_MAX_AUDIO_DEVICENAME_LEN = 31; + deviceName = QString::fromWCharArray((wchar_t*)pv.pwszVal).left(QT_WIN_MAX_AUDIO_DEVICENAME_LEN); qDebug() << (mode == QAudio::AudioOutput ? "output" : "input") << " device:" << deviceName; PropVariantClear(&pv); } @@ -1078,35 +1077,13 @@ void Audio::renderToolBox(int x, int y, bool boxed) { } _iconBounds = QRect(x, y, MUTE_ICON_SIZE, MUTE_ICON_SIZE); - - static quint64 last = 0; // Hold the last time sample - if (!_muted) { - last = 0; - glColor3f(1,1,1); glBindTexture(GL_TEXTURE_2D, _micTextureId); } else { - quint64 usecTimestampNow(); - static const float CYCLE_DURATION = 3.0f; // Seconds - quint64 now = usecTimestampNow(); - float delta = (float)(now - last) / 1000000.0f; - float from = 1.0f; // Linear fade down (upper bound) - float to = 0.3f; // Linear fade down (lower bound) - - if (delta > CYCLE_DURATION) { - last = now; - delta -= (int)delta; - } else if (delta > (CYCLE_DURATION * 0.5f)) { - // Linear fade up - from = 0.3f; // lower bound - to = 1.0f; // upper bound - } - // Compute a linear ramp to fade the color from full to partial saturation - float linearRamp = (from - to) * delta / CYCLE_DURATION + to; - glColor3f(linearRamp, linearRamp, linearRamp); glBindTexture(GL_TEXTURE_2D, _muteTextureId); } + glColor3f(1,1,1); glBegin(GL_QUADS); glTexCoord2f(1, 1); From 679846267e32a0929045dd86cd914f8c4c80ff91 Mon Sep 17 00:00:00 2001 From: matsukaze Date: Tue, 10 Jun 2014 22:42:01 -0400 Subject: [PATCH 6/6] Job #19766 BUG: Stop or reload all scripts crashes interface fixed, part 3 Same comments as before, but without the local files changes mistakenly checked in. --- interface/src/Application.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 9fb821bff4..25a5ba8007 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3483,8 +3483,10 @@ void Application::saveScripts() { } ScriptEngine* Application::loadScript(const QString& scriptName, bool loadScriptFromEditor) { - if(loadScriptFromEditor && _scriptEnginesHash.contains(scriptName) && !_scriptEnginesHash[scriptName]->isFinished()){ - return _scriptEnginesHash[scriptName]; + QUrl scriptUrl(scriptName); + const QString& scriptURLString = scriptUrl.toString(); + if(loadScriptFromEditor && _scriptEnginesHash.contains(scriptURLString) && !_scriptEnginesHash[scriptURLString]->isFinished()){ + return _scriptEnginesHash[scriptURLString]; } ScriptEngine* scriptEngine; @@ -3492,9 +3494,8 @@ ScriptEngine* Application::loadScript(const QString& scriptName, bool loadScript scriptEngine = new ScriptEngine(NO_SCRIPT, "", &_controllerScriptingInterface); } else { // start the script on a new thread... - QUrl scriptUrl(scriptName); scriptEngine = new ScriptEngine(scriptUrl, &_controllerScriptingInterface); - _scriptEnginesHash.insert(scriptUrl.toString(), scriptEngine); + _scriptEnginesHash.insert(scriptURLString, scriptEngine); if (!scriptEngine->hasScript()) { qDebug() << "Application::loadScript(), script failed to load...";