Fix crash cause when Menu::instance() is before offscreen ui startup

This commit is contained in:
Brad Davis 2015-04-27 22:58:09 -07:00
parent 19ca543c2c
commit b0eccc40c2
4 changed files with 39 additions and 13 deletions

View file

@ -767,6 +767,7 @@ void Application::initializeUi() {
AddressBarDialog::registerType(); AddressBarDialog::registerType();
LoginDialog::registerType(); LoginDialog::registerType();
MessageDialog::registerType(); MessageDialog::registerType();
VrMenu::registerType();
auto offscreenUi = DependencyManager::get<OffscreenUi>(); auto offscreenUi = DependencyManager::get<OffscreenUi>();
offscreenUi->create(_glWidget->context()->contextHandle()); offscreenUi->create(_glWidget->context()->contextHandle());
@ -775,6 +776,8 @@ void Application::initializeUi() {
offscreenUi->setBaseUrl(QUrl::fromLocalFile(PathUtils::resourcesPath() + "/qml/")); offscreenUi->setBaseUrl(QUrl::fromLocalFile(PathUtils::resourcesPath() + "/qml/"));
offscreenUi->load("Root.qml"); offscreenUi->load("Root.qml");
offscreenUi->load("RootMenu.qml"); offscreenUi->load("RootMenu.qml");
VrMenu::load();
VrMenu::executeQueuedLambdas();
offscreenUi->setMouseTranslator([this](const QPointF& p){ offscreenUi->setMouseTranslator([this](const QPointF& p){
if (OculusManager::isConnected()) { if (OculusManager::isConnected()) {
glm::vec2 pos = _applicationOverlay.screenToOverlay(toGlm(p)); glm::vec2 pos = _applicationOverlay.screenToOverlay(toGlm(p));

View file

@ -975,7 +975,9 @@ bool Menu::menuItemExists(const QString& menu, const QString& menuitem) {
MenuWrapper::MenuWrapper(QMenu* menu) : _realMenu(menu) { MenuWrapper::MenuWrapper(QMenu* menu) : _realMenu(menu) {
VrMenu::instance()->addMenu(menu); VrMenu::executeOrQueue([=](VrMenu* vrMenu) {
vrMenu->addMenu(menu);
});
_backMap[menu] = this; _backMap[menu] = this;
} }
@ -997,18 +999,24 @@ void MenuWrapper::addSeparator() {
void MenuWrapper::addAction(QAction* action) { void MenuWrapper::addAction(QAction* action) {
_realMenu->addAction(action); _realMenu->addAction(action);
VrMenu::instance()->addAction(_realMenu, action); VrMenu::executeOrQueue([=](VrMenu* vrMenu) {
vrMenu->addAction(_realMenu, action);
});
} }
QAction* MenuWrapper::addAction(const QString& menuName) { QAction* MenuWrapper::addAction(const QString& menuName) {
QAction* action = _realMenu->addAction(menuName); QAction* action = _realMenu->addAction(menuName);
VrMenu::instance()->addAction(_realMenu, action); VrMenu::executeOrQueue([=](VrMenu* vrMenu) {
vrMenu->addAction(_realMenu, action);
});
return action; return action;
} }
QAction* MenuWrapper::addAction(const QString& menuName, const QObject* receiver, const char* member, const QKeySequence& shortcut) { QAction* MenuWrapper::addAction(const QString& menuName, const QObject* receiver, const char* member, const QKeySequence& shortcut) {
QAction* action = _realMenu->addAction(menuName, receiver, member, shortcut); QAction* action = _realMenu->addAction(menuName, receiver, member, shortcut);
VrMenu::instance()->addAction(_realMenu, action); VrMenu::executeOrQueue([=](VrMenu* vrMenu) {
vrMenu->addAction(_realMenu, action);
});
return action; return action;
} }
@ -1018,7 +1026,9 @@ void MenuWrapper::removeAction(QAction* action) {
void MenuWrapper::insertAction(QAction* before, QAction* action) { void MenuWrapper::insertAction(QAction* before, QAction* action) {
_realMenu->insertAction(before, action); _realMenu->insertAction(before, action);
VrMenu::instance()->insertAction(before, action); VrMenu::executeOrQueue([=](VrMenu* vrMenu) {
vrMenu->insertAction(before, action);
});
} }
QHash<QMenu*, MenuWrapper*> MenuWrapper::_backMap; QHash<QMenu*, MenuWrapper*> MenuWrapper::_backMap;

View file

@ -42,7 +42,7 @@ private:
qmlObject->setUserData(USER_DATA_ID, this); qmlObject->setUserData(USER_DATA_ID, this);
qmlObject->setObjectName(uuid.toString()); qmlObject->setObjectName(uuid.toString());
// Make sure we can find it again in the future // Make sure we can find it again in the future
Q_ASSERT(VrMenu::instance()->findMenuObject(uuid.toString())); Q_ASSERT(VrMenu::_instance->findMenuObject(uuid.toString()));
} }
}; };
@ -57,14 +57,25 @@ HIFI_QML_DEF_LAMBDA(VrMenu, [&](QQmlContext* context, QObject* newItem) {
}); });
VrMenu* VrMenu::_instance{ nullptr }; VrMenu* VrMenu::_instance{ nullptr };
static QQueue<std::function<void(VrMenu*)>> queuedLambdas;
VrMenu* VrMenu::instance() { void VrMenu::executeOrQueue(std::function<void(VrMenu*)> f) {
if (!_instance) { if (_instance) {
VrMenu::registerType(); foreach(std::function<void(VrMenu*)> priorLambda, queuedLambdas) {
VrMenu::load(); priorLambda(_instance);
Q_ASSERT(_instance);
} }
return _instance; f(_instance);
} else {
queuedLambdas.push_back(f);
}
}
void VrMenu::executeQueuedLambdas() {
Q_ASSERT(_instance);
foreach(std::function<void(VrMenu*)> f, queuedLambdas) {
f(_instance);
}
queuedLambdas.clear();
} }
VrMenu::VrMenu(QQuickItem* parent) : QQuickItem(parent) { VrMenu::VrMenu(QQuickItem* parent) : QQuickItem(parent) {
@ -72,6 +83,7 @@ VrMenu::VrMenu(QQuickItem* parent) : QQuickItem(parent) {
this->setEnabled(false); this->setEnabled(false);
} }
// QML helper functions // QML helper functions
QObject* addMenu(QObject* parent, const QString& text) { QObject* addMenu(QObject* parent, const QString& text) {
// FIXME add more checking here to ensure no name conflicts // FIXME add more checking here to ensure no name conflicts

View file

@ -26,7 +26,8 @@ class VrMenu : public QQuickItem {
HIFI_QML_DECL_LAMBDA HIFI_QML_DECL_LAMBDA
public: public:
static VrMenu* instance(); static void executeOrQueue(std::function<void(VrMenu*)> f);
static void executeQueuedLambdas();
VrMenu(QQuickItem* parent = nullptr); VrMenu(QQuickItem* parent = nullptr);
void addMenu(QMenu* menu); void addMenu(QMenu* menu);
void addAction(QMenu* parent, QAction* action); void addAction(QMenu* parent, QAction* action);