From d778c4701b5e5ffec54eee51d2427836f4f5c0b1 Mon Sep 17 00:00:00 2001 From: "brettw@google.com" Date: Tue, 16 Sep 2008 20:16:08 +0000 Subject: Remove an explicit call from the NavigationController to the alternate URL fetcher since there is already a notification that does this. I created a class that will automatically unregister for notifications when it goes out of scope and used it here. I think it will be useful for most consumers of notifications. Review URL: http://codereview.chromium.org/2895 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@2276 0039d316-1c4b-4281-b951-d872f2087c98 --- chrome/common/common.vcproj | 8 +++++ chrome/common/notification_registrar.cc | 54 ++++++++++++++++++++++++++++ chrome/common/notification_registrar.h | 63 +++++++++++++++++++++++++++++++++ 3 files changed, 125 insertions(+) create mode 100644 chrome/common/notification_registrar.cc create mode 100644 chrome/common/notification_registrar.h (limited to 'chrome/common') diff --git a/chrome/common/common.vcproj b/chrome/common/common.vcproj index 3cd2809..a09fcba 100644 --- a/chrome/common/common.vcproj +++ b/chrome/common/common.vcproj @@ -510,6 +510,14 @@ > + + + + diff --git a/chrome/common/notification_registrar.cc b/chrome/common/notification_registrar.cc new file mode 100644 index 0000000..fdedde4 --- /dev/null +++ b/chrome/common/notification_registrar.cc @@ -0,0 +1,54 @@ +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include + +#include "chrome/common/notification_registrar.h" + +NotificationRegistrar::NotificationRegistrar() { +} + +NotificationRegistrar::~NotificationRegistrar() { + RemoveAll(); +} + +void NotificationRegistrar::Add(NotificationObserver* observer, + NotificationType type, + NotificationSource source) { + Record record = { observer, type, source }; + DCHECK(std::find(registered_.begin(), registered_.end(), record) == + registered_.end()) << "Duplicate registration."; + registered_.push_back(record); + + NotificationService::current()->AddObserver(observer, type, source); +} + +void NotificationRegistrar::Remove(NotificationObserver* observer, + NotificationType type, + NotificationSource source) { + Record record = { observer, type, source }; + RecordVector::iterator found = std::find( + registered_.begin(), registered_.end(), record); + if (found != registered_.end()) { + registered_.erase(found); + } else { + // Fall through to passing the removal through to the notification service. + // If it really isn't registered, it will also assert and do nothing, but + // we might as well catch the case where the class is trying to unregister + // for something they registered without going through us. + NOTREACHED(); + } + + NotificationService::current()->RemoveObserver(observer, type, source); +} + +void NotificationRegistrar::RemoveAll() { + NotificationService* service = NotificationService::current(); + for (size_t i = 0; i < registered_.size(); i++) { + service->RemoveObserver(registered_[i].observer, + registered_[i].type, + registered_[i].source); + } + registered_.clear(); +} diff --git a/chrome/common/notification_registrar.h b/chrome/common/notification_registrar.h new file mode 100644 index 0000000..e253eb4 --- /dev/null +++ b/chrome/common/notification_registrar.h @@ -0,0 +1,63 @@ +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_COMMON_NOTIFICATION_REGISTRAR_H_ +#define CHROME_COMMON_NOTIFICATION_REGISTRAR_H_ + +#include + +#include "base/basictypes.h" +#include "chrome/common/notification_service.h" + +// Aids in registering for notifications and ensures that all registered +// notifications are unregistered when the class is destroyed. +// +// The intended use is that you make a NotificationRegistrar member in your +// class and use it to register your notifications instead of going through the +// notification service directly. It will automatically unregister them for +// you. +class NotificationRegistrar { + public: + // This class must not be derived from (we don't have a virtual destructor so + // it won't work). Instead, use it as a member in your class. + NotificationRegistrar(); + ~NotificationRegistrar(); + + // Wrappers around NotificationService::[Add|Remove]Observer. + void Add(NotificationObserver* observer, + NotificationType type, + NotificationSource source); + void Remove(NotificationObserver* observer, + NotificationType type, + NotificationSource source); + + // Unregisters all notifications. + void RemoveAll(); + + private: + struct Record { + bool operator==(const Record& other) const { + return observer == other.observer && + type == other.type && + source == other.source; + } + + NotificationObserver* observer; + NotificationType type; + NotificationSource source; + }; + + // We keep registered notifications in a simple vector. This means we'll do + // brute-force searches when removing them individually, but individual + // removal is uncommon, and there will typically only be a couple of + // notifications anyway. + typedef std::vector RecordVector; + + // Lists all notifications we're currently registered for. + RecordVector registered_; + + DISALLOW_COPY_AND_ASSIGN(NotificationRegistrar); +}; + +#endif // CHROME_COMMON_NOTIFICATION_REGISTRAR_H_ -- cgit v1.1