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.
This commit is contained in:
matsukaze 2014-06-10 22:29:58 -04:00
parent a48f38b1d2
commit 46f2ab73bc
5 changed files with 175 additions and 38 deletions

View file

@ -20,6 +20,10 @@ if (NOT QT_CMAKE_PREFIX_PATH)
set(QT_CMAKE_PREFIX_PATH $ENV{QT_CMAKE_PREFIX_PATH}) set(QT_CMAKE_PREFIX_PATH $ENV{QT_CMAKE_PREFIX_PATH})
endif () endif ()
if (NOT ZLIB_ROOT)
set(ZLIB_ROOT $ENV{ZLIB_ROOT})
endif ()
set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} ${QT_CMAKE_PREFIX_PATH}) set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} ${QT_CMAKE_PREFIX_PATH})
# set our Base SDK to 10.8 # set our Base SDK to 10.8

View file

@ -33,6 +33,64 @@ SharedAssignmentPointer AssignmentClient::_currentAssignment;
int hifiSockAddrMeta = qRegisterMetaType<HifiSockAddr>("HifiSockAddr"); int hifiSockAddrMeta = qRegisterMetaType<HifiSockAddr>("HifiSockAddr");
template <class T>
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<Assignment::Type>::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<Assignment::Type>(value);
}
validateValue(ok);
} else {
valueNotSpecified();
}
}
return isValid();
}
template<>
bool Parse<QUuid>::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<QString>::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) : AssignmentClient::AssignmentClient(int &argc, char **argv) :
QCoreApplication(argc, argv), QCoreApplication(argc, argv),
_assignmentServerHostname(DEFAULT_ASSIGNMENT_SERVER_HOSTNAME) _assignmentServerHostname(DEFAULT_ASSIGNMENT_SERVER_HOSTNAME)
@ -43,40 +101,42 @@ AssignmentClient::AssignmentClient(int &argc, char **argv) :
QSettings::setDefaultFormat(QSettings::IniFormat); QSettings::setDefaultFormat(QSettings::IniFormat);
QStringList argumentList = arguments(); 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>(ASSIGNMENT_TYPE_OVERRIDE_OPTION, false, &requestAssignmentType));
_parsers.insert(ASSIGNMENT_POOL_OPTION, new Parse<QString>(ASSIGNMENT_POOL_OPTION, false, &assignmentPool));
_parsers.insert(ASSIGNMENT_WALLET_DESTINATION_ID_OPTION, new Parse<QUuid>(ASSIGNMENT_WALLET_DESTINATION_ID_OPTION, false, &walletUUID));
_parsers.insert(CUSTOM_ASSIGNMENT_SERVER_HOSTNAME_OPTION, new Parse<QString>(CUSTOM_ASSIGNMENT_SERVER_HOSTNAME_OPTION, false, &_assignmentServerHostname));
// register meta type is required for queued invoke method on Assignment subclasses // register meta type is required for queued invoke method on Assignment subclasses
// set the logging target to the the CHILD_TARGET_NAME // set the logging target to the the CHILD_TARGET_NAME
Logging::setTargetName(ASSIGNMENT_CLIENT_TARGET_NAME); Logging::setTargetName(ASSIGNMENT_CLIENT_TARGET_NAME);
const QString ASSIGNMENT_TYPE_OVVERIDE_OPTION = "-t"; foreach (Parser* option, _parsers) {
int argumentIndex = argumentList.indexOf(ASSIGNMENT_TYPE_OVVERIDE_OPTION); if (option) {
option->parse(argumentList);
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 // setup our _requestAssignment member variable from the passed arguments
_requestAssignment = Assignment(Assignment::RequestCommand, requestAssignmentType, assignmentPool); _requestAssignment = Assignment(Assignment::RequestCommand, requestAssignmentType, assignmentPool);
// check if we were passed a wallet UUID on the command line // check if we were passed a wallet UUID on the command line
// this would represent where the user running AC wants funds sent to // this would represent where the user running AC wants funds sent to
if (_parsers[ASSIGNMENT_WALLET_DESTINATION_ID_OPTION]->exists() &&
const QString ASSIGNMENT_WALLET_DESTINATION_ID_OPTION = "--wallet"; _parsers[ASSIGNMENT_WALLET_DESTINATION_ID_OPTION]->isValid()) {
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); qDebug() << "The destination wallet UUID for credits is" << uuidStringWithoutCurlyBraces(walletUUID);
_requestAssignment.setWalletUUID(walletUUID); _requestAssignment.setWalletUUID(walletUUID);
} }
@ -84,14 +144,9 @@ AssignmentClient::AssignmentClient(int &argc, char **argv) :
// create a NodeList as an unassigned client // create a NodeList as an unassigned client
NodeList* nodeList = NodeList::createInstance(NodeType::Unassigned); NodeList* nodeList = NodeList::createInstance(NodeType::Unassigned);
// check for an overriden assignment server hostname // check for an overriden assignment server hostname
const QString CUSTOM_ASSIGNMENT_SERVER_HOSTNAME_OPTION = "-a"; if (_parsers[CUSTOM_ASSIGNMENT_SERVER_HOSTNAME_OPTION]->exists() &&
_parsers[CUSTOM_ASSIGNMENT_SERVER_HOSTNAME_OPTION]->isValid()) {
argumentIndex = argumentList.indexOf(CUSTOM_ASSIGNMENT_SERVER_HOSTNAME_OPTION);
if (argumentIndex != -1) {
_assignmentServerHostname = argumentList[argumentIndex + 1];
// set the custom assignment socket on our NodeList // set the custom assignment socket on our NodeList
HifiSockAddr customAssignmentSocket = HifiSockAddr(_assignmentServerHostname, DEFAULT_DOMAIN_SERVER_PORT); HifiSockAddr customAssignmentSocket = HifiSockAddr(_assignmentServerHostname, DEFAULT_DOMAIN_SERVER_PORT);
@ -113,6 +168,12 @@ AssignmentClient::AssignmentClient(int &argc, char **argv) :
this, &AssignmentClient::handleAuthenticationRequest); this, &AssignmentClient::handleAuthenticationRequest);
} }
AssignmentClient::~AssignmentClient() {
foreach (Parser* option, _parsers) {
delete option;
}
}
void AssignmentClient::sendAssignmentRequest() { void AssignmentClient::sendAssignmentRequest() {
if (!_currentAssignment) { if (!_currentAssignment) {
NodeList::getInstance()->sendAssignment(_requestAssignment); NodeList::getInstance()->sendAssignment(_requestAssignment);

View file

@ -16,11 +16,57 @@
#include "ThreadedAssignment.h" #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 { class AssignmentClient : public QCoreApplication {
Q_OBJECT Q_OBJECT
public: public:
AssignmentClient(int &argc, char **argv); AssignmentClient(int &argc, char **argv);
~AssignmentClient();
static const SharedAssignmentPointer& getCurrentAssignment() { return _currentAssignment; } static const SharedAssignmentPointer& getCurrentAssignment() { return _currentAssignment; }
private slots: private slots:
void sendAssignmentRequest(); void sendAssignmentRequest();
void readPendingDatagrams(); void readPendingDatagrams();
@ -31,6 +77,8 @@ private:
Assignment _requestAssignment; Assignment _requestAssignment;
static SharedAssignmentPointer _currentAssignment; static SharedAssignmentPointer _currentAssignment;
QString _assignmentServerHostname; QString _assignmentServerHostname;
QMap<QString, Parser*> _parsers;
}; };
#endif // hifi_AssignmentClient_h #endif // hifi_AssignmentClient_h

View file

@ -3483,8 +3483,10 @@ void Application::saveScripts() {
} }
ScriptEngine* Application::loadScript(const QString& scriptName, bool loadScriptFromEditor) { ScriptEngine* Application::loadScript(const QString& scriptName, bool loadScriptFromEditor) {
if(loadScriptFromEditor && _scriptEnginesHash.contains(scriptName) && !_scriptEnginesHash[scriptName]->isFinished()){ QUrl scriptUrl(scriptName);
return _scriptEnginesHash[scriptName]; const QString& scriptURLString = scriptUrl.toString();
if(loadScriptFromEditor && _scriptEnginesHash.contains(scriptURLString) && !_scriptEnginesHash[scriptURLString]->isFinished()){
return _scriptEnginesHash[scriptURLString];
} }
ScriptEngine* scriptEngine; ScriptEngine* scriptEngine;
@ -3492,9 +3494,8 @@ ScriptEngine* Application::loadScript(const QString& scriptName, bool loadScript
scriptEngine = new ScriptEngine(NO_SCRIPT, "", &_controllerScriptingInterface); scriptEngine = new ScriptEngine(NO_SCRIPT, "", &_controllerScriptingInterface);
} else { } else {
// start the script on a new thread... // start the script on a new thread...
QUrl scriptUrl(scriptName);
scriptEngine = new ScriptEngine(scriptUrl, &_controllerScriptingInterface); scriptEngine = new ScriptEngine(scriptUrl, &_controllerScriptingInterface);
_scriptEnginesHash.insert(scriptUrl.toString(), scriptEngine); _scriptEnginesHash.insert(scriptURLString, scriptEngine);
if (!scriptEngine->hasScript()) { if (!scriptEngine->hasScript()) {
qDebug() << "Application::loadScript(), script failed to load..."; qDebug() << "Application::loadScript(), script failed to load...";

View file

@ -219,8 +219,9 @@ QAudioDeviceInfo defaultAudioDeviceForMode(QAudio::Mode mode) {
pPropertyStore->Release(); pPropertyStore->Release();
pPropertyStore = NULL; pPropertyStore = NULL;
//QAudio devices seems to only take the 31 first characters of the Friendly Device Name. //QAudio devices seems to only take the 31 first characters of the Friendly Device Name.
const DWORD QT_WIN_MAX_AUDIO_DEVICENAME_LEN = 31; //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).left(QT_WIN_MAX_AUDIO_DEVICENAME_LEN);
deviceName = QString::fromWCharArray((wchar_t*)pv.pwszVal);
qDebug() << (mode == QAudio::AudioOutput ? "output" : "input") << " device:" << deviceName; qDebug() << (mode == QAudio::AudioOutput ? "output" : "input") << " device:" << deviceName;
PropVariantClear(&pv); 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); _iconBounds = QRect(x, y, MUTE_ICON_SIZE, MUTE_ICON_SIZE);
static quint64 last = 0; // Hold the last time sample
if (!_muted) { if (!_muted) {
last = 0;
glColor3f(1,1,1);
glBindTexture(GL_TEXTURE_2D, _micTextureId); glBindTexture(GL_TEXTURE_2D, _micTextureId);
} else { } 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); glBindTexture(GL_TEXTURE_2D, _muteTextureId);
} }
glColor3f(1,1,1);
glBegin(GL_QUADS); glBegin(GL_QUADS);
glTexCoord2f(1, 1); glTexCoord2f(1, 1);