diff --git a/indra/llcommon/llsingleton.h b/indra/llcommon/llsingleton.h index 45aae60e8..78b8f95be 100644 --- a/indra/llcommon/llsingleton.h +++ b/indra/llcommon/llsingleton.h @@ -226,7 +226,7 @@ void LLSingleton::createInstance(SingletonInstanceData& data) if (data.mInitState == INITIALIZING) { - lldebugs << "Tried to access singleton " << typeid(DERIVED_TYPE).name() << " from initSingleton(), using half-initialized object" << llendl; + llerrs << "Tried to access singleton " << typeid(DERIVED_TYPE).name() << " from initSingleton(), using half-initialized object" << llendl; return; } diff --git a/indra/llui/llalertdialog.cpp b/indra/llui/llalertdialog.cpp index 27700ca20..712683021 100644 --- a/indra/llui/llalertdialog.cpp +++ b/indra/llui/llalertdialog.cpp @@ -315,11 +315,11 @@ LLAlertDialog::LLAlertDialog( LLNotificationPtr notification, bool modal) if (form->getIgnoreType() == LLNotificationForm::IGNORE_WITH_DEFAULT_RESPONSE) { - setCheckBox(LLNotifications::instance().getGlobalString("skipnexttime"), ignore_label); + setCheckBox(LLNotificationTemplates::instance().getGlobalString("skipnexttime"), ignore_label); } else if (form->getIgnoreType() == LLNotificationForm::IGNORE_WITH_LAST_RESPONSE) { - setCheckBox(LLNotifications::instance().getGlobalString("alwayschoose"), ignore_label); + setCheckBox(LLNotificationTemplates::instance().getGlobalString("alwayschoose"), ignore_label); } } diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp index 89b43f212..8c11a50b8 100644 --- a/indra/llui/llnotifications.cpp +++ b/indra/llui/llnotifications.cpp @@ -100,10 +100,10 @@ private: for (LLNotificationSet::iterator it = mItems.begin(); it != mItems.end(); ++it) { - if (!LLNotifications::instance().templateExists((*it)->getName())) continue; + if (!LLNotificationTemplates::instance().templateExists((*it)->getName())) continue; // only store notifications flagged as persisting - LLNotificationTemplatePtr templatep = LLNotifications::instance().getTemplate((*it)->getName()); + LLNotificationTemplatePtr templatep = LLNotificationTemplates::instance().getTemplate((*it)->getName()); if (!templatep->mPersist) continue; data.append((*it)->asLLSD()); @@ -228,7 +228,7 @@ LLNotificationForm::LLNotificationForm(const std::string& name, const LLXMLNodeP LLXMLNodePtr child = xml_node->getFirstChild(); while(child) { - child = LLNotifications::instance().checkForXMLTemplate(child); + child = LLNotificationTemplates::instance().checkForXMLTemplate(child); LLSD item_entry; std::string element_name = child->getName()->mString; @@ -662,7 +662,7 @@ bool LLNotification::isEquivalentTo(LLNotificationPtr that) const void LLNotification::init(const std::string& template_name, const LLSD& form_elements) { - mTemplatep = LLNotifications::instance().getTemplate(template_name); + mTemplatep = LLNotificationTemplates::instance().getTemplate(template_name); if (!mTemplatep) return; const LLStringUtil::format_map_t& default_args = LLTrans::getDefaultArgs(); @@ -1098,12 +1098,19 @@ LLNotificationChannelPtr LLNotifications::getChannel(const std::string& channelN return p->second; } +// this function is called once at construction time, after the object is constructed. +void LLNotificationTemplates::initSingleton() +{ + loadTemplates(); +} // this function is called once at construction time, after the object is constructed. void LLNotifications::initSingleton() { - loadTemplates(); - createDefaultChannels(); + loadNotifications(); + // Cannot create default channels here, since that recursively accesses the singleton. + // Instead we call createDefaultChannels() from LLAppViewer::init(). + //createDefaultChannels(); } void LLNotifications::createDefaultChannels() @@ -1142,7 +1149,7 @@ void LLNotifications::createDefaultChannels() static std::string sStringSkipNextTime("Skip this dialog next time"); static std::string sStringAlwaysChoose("Always choose this option"); -bool LLNotifications::addTemplate(const std::string &name, +bool LLNotificationTemplates::addTemplate(const std::string &name, LLNotificationTemplatePtr theTemplate) { if (mTemplates.count(name)) @@ -1154,7 +1161,7 @@ bool LLNotifications::addTemplate(const std::string &name, return true; } -LLNotificationTemplatePtr LLNotifications::getTemplate(const std::string& name) +LLNotificationTemplatePtr LLNotificationTemplates::getTemplate(const std::string& name) { if (mTemplates.count(name)) { @@ -1166,12 +1173,12 @@ LLNotificationTemplatePtr LLNotifications::getTemplate(const std::string& name) } } -bool LLNotifications::templateExists(const std::string& name) +bool LLNotificationTemplates::templateExists(const std::string& name) { return (mTemplates.count(name) != 0); } -void LLNotifications::clearTemplates() +void LLNotificationTemplates::clearTemplates() { mTemplates.clear(); } @@ -1192,7 +1199,7 @@ void LLNotifications::forceResponse(const LLNotification::Params& params, S32 op temp_notify->respond(response); } -LLNotifications::TemplateNames LLNotifications::getTemplateNames() const +LLNotificationTemplates::TemplateNames LLNotificationTemplates::getTemplateNames() const { TemplateNames names; for (TemplateMap::const_iterator it = mTemplates.begin(); it != mTemplates.end(); ++it) @@ -1242,7 +1249,7 @@ void replaceSubstitutionStrings(LLXMLNodePtr node, StringMap& replacements) // returns true if the template request was invalid and there's nothing else we // can do with this node, false if you should keep processing (it may have // replaced the contents of the node referred to) -LLXMLNodePtr LLNotifications::checkForXMLTemplate(LLXMLNodePtr item) +LLXMLNodePtr LLNotificationTemplates::checkForXMLTemplate(LLXMLNodePtr item) { if (item->hasName("usetemplate")) { @@ -1271,7 +1278,7 @@ LLXMLNodePtr LLNotifications::checkForXMLTemplate(LLXMLNodePtr item) return item; } -bool LLNotifications::loadTemplates() +bool LLNotificationTemplates::loadTemplates() { const std::string xml_filename = "notifications.xml"; LLXMLNodePtr root; @@ -1289,11 +1296,6 @@ bool LLNotifications::loadTemplates() for (LLXMLNodePtr item = root->getFirstChild(); item.notNull(); item = item->getNextSibling()) { - // we do this FIRST so that item can be changed if we - // encounter a usetemplate -- we just replace the - // current xml node and keep processing - item = checkForXMLTemplate(item); - if (item->hasName("global")) { std::string global_name; @@ -1321,7 +1323,35 @@ bool LLNotifications::loadTemplates() " found in " << xml_filename << llendl; continue; } + } + + return true; +} +bool LLNotifications::loadNotifications() +{ + const std::string xml_filename = "notifications.xml"; + LLXMLNodePtr root; + + BOOL success = LLUICtrlFactory::getLayeredXMLNode(xml_filename, root); + + if (!success || root.isNull() || !root->hasName( "notifications" )) + { + llerrs << "Problem reading UI Notifications file: " << xml_filename << llendl; + return false; + } + + for (LLXMLNodePtr item = root->getFirstChild(); + item.notNull(); item = item->getNextSibling()) + { + // we do this FIRST so that item can be changed if we + // encounter a usetemplate -- we just replace the + // current xml node and keep processing + item = LLNotificationTemplates::instance().checkForXMLTemplate(item); + + if (!item->hasName("notification")) + continue; + // now we know we have a notification entry, so let's build it LLNotificationTemplatePtr pTemplate(new LLNotificationTemplate()); @@ -1369,7 +1399,7 @@ bool LLNotifications::loadTemplates() for (LLXMLNodePtr child = item->getFirstChild(); !child.isNull(); child = child->getNextSibling()) { - child = checkForXMLTemplate(child); + child = LLNotificationTemplates::instance().checkForXMLTemplate(child); // if (child->hasName("url")) @@ -1405,7 +1435,7 @@ bool LLNotifications::loadTemplates() pTemplate->mForm = LLNotificationFormPtr(new LLNotificationForm(pTemplate->mName, child)); } } - addTemplate(pTemplate->mName, pTemplate); + LLNotificationTemplates::instance().addTemplate(pTemplate->mName, pTemplate); } //std::ostringstream ostream; @@ -1485,7 +1515,7 @@ void LLNotifications::update(const LLNotificationPtr pNotif) } -LLNotificationPtr LLNotifications::find(LLUUID uuid) +LLNotificationPtr LLNotifications::find(LLUUID const& uuid) { LLNotificationPtr target = LLNotificationPtr(new LLNotification(uuid)); LLNotificationSet::iterator it=mItems.find(target); @@ -1505,7 +1535,7 @@ void LLNotifications::forEachNotification(NotificationProcess process) std::for_each(mItems.begin(), mItems.end(), process); } -std::string LLNotifications::getGlobalString(const std::string& key) const +std::string LLNotificationTemplates::getGlobalString(const std::string& key) const { GlobalStringMap::const_iterator it = mGlobalStrings.find(key); if (it != mGlobalStrings.end()) diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h index b6ee760f3..1585f35f4 100644 --- a/indra/llui/llnotifications.h +++ b/indra/llui/llnotifications.h @@ -679,45 +679,20 @@ private: LLNotificationComparator mComparator; }; - - -class LLNotifications : - public LLSingleton, - public LLNotificationChannelBase +class LLNotificationTemplates : + public LLSingleton { - LOG_CLASS(LLNotifications); + LOG_CLASS(LLNotificationTemplates); + + friend class LLSingleton; + + // This class may not use LLNotifications. + typedef char LLNotifications; - friend class LLSingleton; public: - // load notification descriptions from file; - // OK to call more than once because it will reload bool loadTemplates(); LLXMLNodePtr checkForXMLTemplate(LLXMLNodePtr item); - // we provide a collection of simple add notification functions so that it's reasonable to create notifications in one line - LLNotificationPtr add(const std::string& name, - const LLSD& substitutions = LLSD(), - const LLSD& payload = LLSD()); - LLNotificationPtr add(const std::string& name, - const LLSD& substitutions, - const LLSD& payload, - const std::string& functor_name); - LLNotificationPtr add(const std::string& name, - const LLSD& substitutions, - const LLSD& payload, - LLNotificationFunctorRegistry::ResponseFunctor functor); - LLNotificationPtr add(const LLNotification::Params& p); - - void add(const LLNotificationPtr pNotif); - void cancel(LLNotificationPtr pNotif); - void update(const LLNotificationPtr pNotif); - - LLNotificationPtr find(LLUUID uuid); - - typedef boost::function NotificationProcess; - - void forEachNotification(NotificationProcess process); - // This is all stuff for managing the templates // take your template out LLNotificationTemplatePtr getTemplate(const std::string& name); @@ -736,17 +711,67 @@ public: // useful if you're reloading the file void clearTemplates(); // erase all templates - void forceResponse(const LLNotification::Params& params, S32 option); + // put your template in (should only be called from LLNotifications). + bool addTemplate(const std::string& name, LLNotificationTemplatePtr theTemplate); + std::string getGlobalString(const std::string& key) const; + +private: + // we're a singleton, so we don't have a public constructor + LLNotificationTemplates() { } + /*virtual*/ void initSingleton(); + + TemplateMap mTemplates; + + typedef std::map XMLTemplateMap; + XMLTemplateMap mXmlTemplates; + + typedef std::map GlobalStringMap; + GlobalStringMap mGlobalStrings; +}; + +class LLNotifications : + public LLSingleton, + public LLNotificationChannelBase +{ + LOG_CLASS(LLNotifications); + + friend class LLSingleton; +public: + // load notification descriptions from file; + // OK to call more than once because it will reload + bool loadNotifications(); void createDefaultChannels(); + // we provide a collection of simple add notification functions so that it's reasonable to create notifications in one line + LLNotificationPtr add(const std::string& name, + const LLSD& substitutions = LLSD(), + const LLSD& payload = LLSD()); + LLNotificationPtr add(const std::string& name, + const LLSD& substitutions, + const LLSD& payload, + const std::string& functor_name); + LLNotificationPtr add(const std::string& name, + const LLSD& substitutions, + const LLSD& payload, + LLNotificationFunctorRegistry::ResponseFunctor functor); + LLNotificationPtr add(const LLNotification::Params& p); + + void forceResponse(const LLNotification::Params& params, S32 option); + typedef std::map ChannelMap; ChannelMap mChannels; void addChannel(LLNotificationChannelPtr pChan); LLNotificationChannelPtr getChannel(const std::string& channelName); + + void add(const LLNotificationPtr pNotif); + void cancel(LLNotificationPtr pNotif); + void update(const LLNotificationPtr pNotif); + LLNotificationPtr find(LLUUID const& uuid); - std::string getGlobalString(const std::string& key) const; + typedef boost::function NotificationProcess; + void forEachNotification(NotificationProcess process); private: // we're a singleton, so we don't have a public constructor @@ -760,22 +785,11 @@ private: bool uniqueFilter(LLNotificationPtr pNotification); bool uniqueHandler(const LLSD& payload); bool failedUniquenessTest(const LLSD& payload); + LLNotificationChannelPtr pHistoryChannel; LLNotificationChannelPtr pExpirationChannel; - - // put your template in - bool addTemplate(const std::string& name, LLNotificationTemplatePtr theTemplate); - TemplateMap mTemplates; - - std::string mFileName; - - typedef std::map XMLTemplateMap; - XMLTemplateMap mXmlTemplates; LLNotificationMap mUniqueNotifications; - - typedef std::map GlobalStringMap; - GlobalStringMap mGlobalStrings; }; diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 3f5c7480e..bb0f14b1f 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -770,7 +770,7 @@ bool LLAppViewer::init() ); // Setup notifications after LLUI::initClass() has been called. - LLNotifications::instance(); + LLNotifications::instance().createDefaultChannels(); LL_INFOS("InitInfo") << "Notifications initialized." << LL_ENDL ; LLWeb::initClass(); // do this after LLUI @@ -888,7 +888,7 @@ bool LLAppViewer::init() { // can't use an alert here since we're exiting and // all hell breaks lose. - std::string msg = LLNotifications::instance().getGlobalString("UnsupportedGLRequirements"); + std::string msg = LLNotificationTemplates::instance().getGlobalString("UnsupportedGLRequirements"); LLStringUtil::format(msg,LLTrans::getDefaultArgs()); OSMessageBox( msg, @@ -903,7 +903,7 @@ bool LLAppViewer::init() { // can't use an alert here since we're exiting and // all hell breaks lose. - std::string msg = LLNotifications::instance().getGlobalString("UnsupportedCPUSSE2"); + std::string msg = LLNotificationTemplates::instance().getGlobalString("UnsupportedCPUSSE2"); LLStringUtil::format(msg,LLTrans::getDefaultArgs()); OSMessageBox( msg, @@ -917,7 +917,7 @@ bool LLAppViewer::init() { // can't use an alert here since we're exiting and // all hell breaks lose. - std::string msg = LNotifications::instance().getGlobalString("UnsupportedCPUSSE2"); + std::string msg = LNotificationTemplates::instance().getGlobalString("UnsupportedCPUSSE2"); LLStringUtil::format(msg,LLTrans::getDefaultArgs()); OSMessageBox( msg, @@ -935,31 +935,31 @@ bool LLAppViewer::init() std::string minSpecs; // get cpu data from xml - std::stringstream minCPUString(LLNotifications::instance().getGlobalString("UnsupportedCPUAmount")); + std::stringstream minCPUString(LLNotificationTemplates::instance().getGlobalString("UnsupportedCPUAmount")); S32 minCPU = 0; minCPUString >> minCPU; // get RAM data from XML - std::stringstream minRAMString(LLNotifications::instance().getGlobalString("UnsupportedRAMAmount")); + std::stringstream minRAMString(LLNotificationTemplates::instance().getGlobalString("UnsupportedRAMAmount")); U64 minRAM = 0; minRAMString >> minRAM; minRAM = minRAM * 1024 * 1024; if(!LLFeatureManager::getInstance()->isGPUSupported() && LLFeatureManager::getInstance()->getGPUClass() != GPU_CLASS_UNKNOWN) { - minSpecs += LLNotifications::instance().getGlobalString("UnsupportedGPU"); + minSpecs += LLNotificationTemplates::instance().getGlobalString("UnsupportedGPU"); minSpecs += "\n"; unsupported = true; } if(gSysCPU.getMHz() < minCPU) { - minSpecs += LLNotifications::instance().getGlobalString("UnsupportedCPU"); + minSpecs += LLNotificationTemplates::instance().getGlobalString("UnsupportedCPU"); minSpecs += "\n"; unsupported = true; } if(gSysMemory.getPhysicalMemoryClamped() < minRAM) { - minSpecs += LLNotifications::instance().getGlobalString("UnsupportedRAM"); + minSpecs += LLNotificationTemplates::instance().getGlobalString("UnsupportedRAM"); minSpecs += "\n"; unsupported = true; } diff --git a/indra/newview/llfloaterdisplayname.cpp b/indra/newview/llfloaterdisplayname.cpp index 1eb0ca856..6d97faf93 100644 --- a/indra/newview/llfloaterdisplayname.cpp +++ b/indra/newview/llfloaterdisplayname.cpp @@ -167,7 +167,7 @@ void LLFloaterDisplayName::onCacheSetName(bool success, // We might have a localized string for this message // error_args will usually be empty from the server. if (!error_tag.empty() - && LLNotifications::getInstance()->templateExists(error_tag)) + && LLNotificationTemplates::getInstance()->templateExists(error_tag)) { LLNotifications::instance().add(error_tag); return; diff --git a/indra/newview/llfloaternotificationsconsole.cpp b/indra/newview/llfloaternotificationsconsole.cpp index 5d6b771d5..ec9bf09b0 100644 --- a/indra/newview/llfloaternotificationsconsole.cpp +++ b/indra/newview/llfloaternotificationsconsole.cpp @@ -187,8 +187,8 @@ BOOL LLFloaterNotificationConsole::postBuild() getChild("add_notification")->setClickedCallback(onClickAdd, this); LLComboBox* notifications = getChild("notification_types"); - LLNotifications::TemplateNames names = LLNotifications::instance().getTemplateNames(); - for (LLNotifications::TemplateNames::iterator template_it = names.begin(); + LLNotificationTemplates::TemplateNames names = LLNotificationTemplates::instance().getTemplateNames(); + for (LLNotificationTemplates::TemplateNames::iterator template_it = names.begin(); template_it != names.end(); ++template_it) { diff --git a/indra/newview/llpanelmsgs.cpp b/indra/newview/llpanelmsgs.cpp index 54e2f7dbe..e1afe8a1f 100644 --- a/indra/newview/llpanelmsgs.cpp +++ b/indra/newview/llpanelmsgs.cpp @@ -83,8 +83,8 @@ void LLPanelMsgs::buildLists() //void LLFloaterPreference::buildPopupLists() in disabled_popups.deleteAllItems(); enabled_popups.deleteAllItems(); - for (LLNotifications::TemplateMap::const_iterator iter = LLNotifications::instance().templatesBegin(); - iter != LLNotifications::instance().templatesEnd(); + for (LLNotificationTemplates::TemplateMap::const_iterator iter = LLNotificationTemplates::instance().templatesBegin(); + iter != LLNotificationTemplates::instance().templatesEnd(); ++iter) { LLNotificationTemplatePtr templatep = iter->second; @@ -175,8 +175,8 @@ void LLPanelMsgs::cancel() void LLPanelMsgs::resetAllIgnored() { - for (LLNotifications::TemplateMap::const_iterator iter = LLNotifications::instance().templatesBegin(); - iter != LLNotifications::instance().templatesEnd(); + for (LLNotificationTemplates::TemplateMap::const_iterator iter = LLNotificationTemplates::instance().templatesBegin(); + iter != LLNotificationTemplates::instance().templatesEnd(); ++iter) { if (iter->second->mForm->getIgnoreType() != LLNotificationForm::IGNORE_NO) @@ -188,8 +188,8 @@ void LLPanelMsgs::resetAllIgnored() void LLPanelMsgs::setAllIgnored() { - for (LLNotifications::TemplateMap::const_iterator iter = LLNotifications::instance().templatesBegin(); - iter != LLNotifications::instance().templatesEnd(); + for (LLNotificationTemplates::TemplateMap::const_iterator iter = LLNotificationTemplates::instance().templatesBegin(); + iter != LLNotificationTemplates::instance().templatesEnd(); ++iter) { if (iter->second->mForm->getIgnoreType() != LLNotificationForm::IGNORE_NO) @@ -210,7 +210,7 @@ void LLPanelMsgs::onClickEnablePopup(void* user_data) std::vector::iterator itor; for (itor = items.begin(); itor != items.end(); ++itor) { - LLNotificationTemplatePtr templatep = LLNotifications::instance().getTemplate(*(std::string*)((*itor)->getUserdata())); + LLNotificationTemplatePtr templatep = LLNotificationTemplates::instance().getTemplate(*(std::string*)((*itor)->getUserdata())); gSavedSettings.setWarning(templatep->mName, TRUE); } diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index c66a706d8..0cd77eb92 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -6149,7 +6149,7 @@ bool attempt_standard_notification(LLMessageSystem* msgsystem) // notification was specified using the new mechanism, so we can just handle it here std::string notificationID; msgsystem->getStringFast(_PREHASH_AlertInfo, _PREHASH_Message, notificationID); - if (!LLNotifications::getInstance()->templateExists(notificationID)) + if (!LLNotificationTemplates::getInstance()->templateExists(notificationID)) { return false; } @@ -6327,7 +6327,7 @@ void process_alert_core(const std::string& message, BOOL modal) } else { - std::string new_msg =LLNotifications::instance().getGlobalString(text); + std::string new_msg =LLNotificationTemplates::instance().getGlobalString(text); args["MESSAGE"] = new_msg; LLNotificationsUtil::add("SystemMessage", args); } @@ -6335,7 +6335,7 @@ void process_alert_core(const std::string& message, BOOL modal) else if (modal) { LLSD args; - std::string new_msg =LLNotifications::instance().getGlobalString(message); + std::string new_msg =LLNotificationTemplates::instance().getGlobalString(message); args["ERROR_MESSAGE"] = new_msg; LLNotificationsUtil::add("ErrorMessage", args); } @@ -6346,7 +6346,7 @@ void process_alert_core(const std::string& message, BOOL modal) if (message.find(AUTOPILOT_CANCELED_MSG) == std::string::npos ) { LLSD args; - std::string new_msg =LLNotifications::instance().getGlobalString(message); + std::string new_msg =LLNotificationTemplates::instance().getGlobalString(message); std::string localized_msg; bool is_message_localized = LLTrans::findString(localized_msg, new_msg);