summaryrefslogtreecommitdiff
path: root/indra/newview/llnotificationstorage.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llnotificationstorage.cpp')
-rw-r--r--indra/newview/llnotificationstorage.cpp246
1 files changed, 66 insertions, 180 deletions
diff --git a/indra/newview/llnotificationstorage.cpp b/indra/newview/llnotificationstorage.cpp
index 4cad96fdc7..b6184f09bf 100644
--- a/indra/newview/llnotificationstorage.cpp
+++ b/indra/newview/llnotificationstorage.cpp
@@ -25,225 +25,111 @@
*/
#include "llviewerprecompiledheaders.h" // must be first include
+
#include "llnotificationstorage.h"
-#include "llxmlnode.h" // for linux compilers
+#include <string>
+#include <map>
-#include "llchannelmanager.h"
-#include "llscreenchannel.h"
-#include "llscriptfloater.h"
+#include "llerror.h"
+#include "llfile.h"
+#include "llnotifications.h"
+#include "llpointer.h"
+#include "llsd.h"
#include "llsdserialize.h"
-#include "llviewermessage.h"
+#include "llsingleton.h"
+#include "llregistry.h"
+#include "llviewermessage.h"
-//////////////////////////////////////////////////////////////////////////
+typedef boost::function<LLNotificationResponderInterface * (const LLSD& pParams)> responder_constructor_t;
-class LLResponderRegistry
+class LLResponderRegistry : public LLRegistrySingleton<std::string, responder_constructor_t, LLResponderRegistry>
{
-public:
-
- static void registerResponders();
-
- static LLNotificationResponderInterface* createResponder(const std::string& notification_name, const LLSD& params);
-
-private:
-
- template<typename RESPONDER_TYPE>
- static LLNotificationResponderInterface* create(const LLSD& params)
- {
- RESPONDER_TYPE* responder = new RESPONDER_TYPE();
- responder->fromLLSD(params);
- return responder;
- }
-
- typedef boost::function<LLNotificationResponderInterface* (const LLSD& params)> responder_constructor_t;
+ public:
+ template<typename RESPONDER_TYPE> static LLNotificationResponderInterface * create(const LLSD& pParams);
+ LLNotificationResponderInterface * createResponder(const std::string& pNotificationName, const LLSD& pParams);
+};
- static void add(const std::string& notification_name, const responder_constructor_t& ctr);
+template<typename RESPONDER_TYPE> LLNotificationResponderInterface * LLResponderRegistry::create(const LLSD& pParams)
+{
+ RESPONDER_TYPE* responder = new RESPONDER_TYPE();
+ responder->fromLLSD(pParams);
+ return responder;
+}
-private:
- typedef std::map<std::string, responder_constructor_t> build_map_t;
+LLNotificationResponderInterface * LLResponderRegistry::createResponder(const std::string& pNotificationName, const LLSD& pParams)
+{
+ responder_constructor_t * factoryFunc = (LLResponderRegistry::getValue(pNotificationName));
+
+ if(factoryFunc)
+ {
+ return (*factoryFunc)(pParams);
+ }
+
+ return NULL;
+}
- static build_map_t sBuildMap;
-};
+LLResponderRegistry::StaticRegistrar sRegisterObjectGiveItem("ObjectGiveItem", &LLResponderRegistry::create<LLOfferInfo>);
+LLResponderRegistry::StaticRegistrar sRegisterUserGiveItem("UserGiveItem", &LLResponderRegistry::create<LLOfferInfo>);
+LLResponderRegistry::StaticRegistrar sRegisterOfferInfo("offer_info", &LLResponderRegistry::create<LLOfferInfo>);
-//////////////////////////////////////////////////////////////////////////
-LLPersistentNotificationStorage::LLPersistentNotificationStorage()
+LLNotificationStorage::LLNotificationStorage(std::string pFileName)
+ : mFileName(pFileName)
{
- mFileName = gDirUtilp->getExpandedFilename ( LL_PATH_PER_SL_ACCOUNT, "open_notifications.xml" );
}
-bool LLPersistentNotificationStorage::onPersistentChannelChanged(const LLSD& payload)
+LLNotificationStorage::~LLNotificationStorage()
{
- // we ignore "load" messages, but rewrite the persistence file on any other
- const std::string sigtype = payload["sigtype"].asString();
- if ("load" != sigtype)
- {
- saveNotifications();
- }
- return false;
}
-// Storing or loading too many persistent notifications will severely hurt
-// viewer load times, possibly to the point of failing to log in. Example case
-// from MAINT-994 is 821 notifications.
-static const S32 MAX_PERSISTENT_NOTIFICATIONS = 250;
-
-void LLPersistentNotificationStorage::saveNotifications()
+bool LLNotificationStorage::writeNotifications(const LLSD& pNotificationData) const
{
- // TODO - think about save optimization.
- llofstream notify_file(mFileName.c_str());
- if (!notify_file.is_open())
+ llofstream notifyFile(mFileName.c_str());
+ bool didFileOpen = notifyFile.is_open();
+
+ if (!didFileOpen)
{
- llwarns << "Failed to open " << mFileName << llendl;
- return;
+ LL_WARNS("LLNotificationStorage") << "Failed to open file '" << mFileName << "'" << LL_ENDL;
}
-
- LLSD output;
- LLSD& data = output["data"];
-
- LLNotificationChannelPtr history_channel = LLNotifications::instance().getChannel("Persistent");
- LLNotificationSet::iterator it = history_channel->begin();
-
- for ( ; history_channel->end() != it; ++it)
+ else
{
- LLNotificationPtr notification = *it;
-
- // After a notification was placed in Persist channel, it can become
- // responded, expired or canceled - in this case we are should not save it
- if(notification->isRespondedTo() || notification->isCancelled()
- || notification->isExpired())
- {
- continue;
- }
-
- data.append(notification->asLLSD());
-
- if (data.size() >= MAX_PERSISTENT_NOTIFICATIONS)
- {
- llwarns << "Too many persistent notifications."
- << " Saved " << MAX_PERSISTENT_NOTIFICATIONS << " of " << history_channel->size() << " persistent notifications." << llendl;
- break;
- }
+ LLPointer<LLSDFormatter> formatter = new LLSDXMLFormatter();
+ formatter->format(pNotificationData, notifyFile, LLSDFormatter::OPTIONS_PRETTY);
}
- LLPointer<LLSDFormatter> formatter = new LLSDXMLFormatter();
- formatter->format(output, notify_file, LLSDFormatter::OPTIONS_PRETTY);
+ return didFileOpen;
}
-void LLPersistentNotificationStorage::loadNotifications()
+bool LLNotificationStorage::readNotifications(LLSD& pNotificationData) const
{
- LLResponderRegistry::registerResponders();
-
- llifstream notify_file(mFileName.c_str());
- if (!notify_file.is_open())
- {
- llwarns << "Failed to open " << mFileName << llendl;
- return;
- }
+ bool didFileRead;
- LLSD input;
- LLPointer<LLSDParser> parser = new LLSDXMLParser();
- if (parser->parse(notify_file, input, LLSDSerialize::SIZE_UNLIMITED) < 0)
- {
- llwarns << "Failed to parse open notifications" << llendl;
- return;
- }
-
- if (input.isUndefined())
- {
- return;
- }
+ pNotificationData.clear();
- LLSD& data = input["data"];
- if (data.isUndefined())
+ llifstream notifyFile(mFileName.c_str());
+ didFileRead = notifyFile.is_open();
+ if (!didFileRead)
{
- return;
+ LL_WARNS("LLNotificationStorage") << "Failed to open file '" << mFileName << "'" << LL_ENDL;
}
-
- using namespace LLNotificationsUI;
- LLScreenChannel* notification_channel = dynamic_cast<LLScreenChannel*>(LLChannelManager::getInstance()->
- findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID"))));
-
- LLNotifications& instance = LLNotifications::instance();
- S32 processed_notifications = 0;
- for (LLSD::array_const_iterator notification_it = data.beginArray();
- notification_it != data.endArray();
- ++notification_it)
+ else
{
- LLSD notification_params = *notification_it;
-
- if (instance.templateExists(notification_params["name"].asString()))
+ LLPointer<LLSDParser> parser = new LLSDXMLParser();
+ didFileRead = (parser->parse(notifyFile, pNotificationData, LLSDSerialize::SIZE_UNLIMITED) >= 0);
+ if (!didFileRead)
{
- LLNotificationPtr notification(new LLNotification(notification_params));
-
- LLNotificationResponderPtr responder(LLResponderRegistry::
- createResponder(notification_params["name"], notification_params["responder"]));
- notification->setResponseFunctor(responder);
-
- instance.add(notification);
-
- // hide script floaters so they don't confuse the user and don't overlap startup toast
- LLScriptFloaterManager::getInstance()->setFloaterVisible(notification->getID(), false);
-
- if(notification_channel)
- {
- // hide saved toasts so they don't confuse the user
- notification_channel->hideToast(notification->getID());
- }
- }
- else
- {
- llwarns << "Failed to find template for persistent notification " << notification_params["name"].asString() << llendl;
- }
-
- ++processed_notifications;
- if (processed_notifications >= MAX_PERSISTENT_NOTIFICATIONS)
- {
- llwarns << "Too many persistent notifications."
- << " Processed " << MAX_PERSISTENT_NOTIFICATIONS << " of " << data.size() << " persistent notifications." << llendl;
- break;
+ LL_WARNS("LLNotificationStorage") << "Failed to parse open notifications from file '" << mFileName
+ << "'" << LL_ENDL;
}
}
- LLNotifications::instance().getChannel("Persistent")->
- connectChanged(boost::bind(&LLPersistentNotificationStorage::onPersistentChannelChanged, this, _1));
+ return didFileRead;
}
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-
-LLResponderRegistry::build_map_t LLResponderRegistry::sBuildMap;
-
-void LLResponderRegistry::registerResponders()
+LLNotificationResponderInterface * LLNotificationStorage::createResponder(const std::string& pNotificationName, const LLSD& pParams) const
{
- sBuildMap.clear();
-
- add("ObjectGiveItem", &create<LLOfferInfo>);
- add("UserGiveItem", &create<LLOfferInfo>);
+ return LLResponderRegistry::getInstance()->createResponder(pNotificationName, pParams);
}
-
-LLNotificationResponderInterface* LLResponderRegistry::createResponder(const std::string& notification_name, const LLSD& params)
-{
- build_map_t::const_iterator it = sBuildMap.find(notification_name);
- if(sBuildMap.end() == it)
- {
- return NULL;
- }
- responder_constructor_t ctr = it->second;
- return ctr(params);
-}
-
-void LLResponderRegistry::add(const std::string& notification_name, const responder_constructor_t& ctr)
-{
- if(sBuildMap.find(notification_name) != sBuildMap.end())
- {
- llwarns << "Responder is already registered : " << notification_name << llendl;
- llassert(!"Responder already registered");
- }
- sBuildMap[notification_name] = ctr;
-}
-
-// EOF