michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef nsObserverList_h___ michael@0: #define nsObserverList_h___ michael@0: michael@0: #include "nsISupports.h" michael@0: #include "nsTArray.h" michael@0: #include "nsCOMPtr.h" michael@0: #include "nsCOMArray.h" michael@0: #include "nsIObserver.h" michael@0: #include "nsIWeakReference.h" michael@0: #include "nsHashKeys.h" michael@0: #include "nsISimpleEnumerator.h" michael@0: #include "mozilla/Attributes.h" michael@0: michael@0: namespace mozilla { michael@0: class ObserverServiceReporter; michael@0: } // namespace mozilla michael@0: michael@0: struct ObserverRef michael@0: { michael@0: ObserverRef(const ObserverRef& o) : michael@0: isWeakRef(o.isWeakRef), ref(o.ref) { } michael@0: michael@0: ObserverRef(nsIObserver* aObserver) : isWeakRef(false), ref(aObserver) { } michael@0: ObserverRef(nsIWeakReference* aWeak) : isWeakRef(true), ref(aWeak) { } michael@0: michael@0: bool isWeakRef; michael@0: nsCOMPtr ref; michael@0: michael@0: nsIObserver* asObserver() { michael@0: NS_ASSERTION(!isWeakRef, "Isn't a strong ref."); michael@0: return static_cast((nsISupports*) ref); michael@0: } michael@0: michael@0: nsIWeakReference* asWeak() { michael@0: NS_ASSERTION(isWeakRef, "Isn't a weak ref."); michael@0: return static_cast((nsISupports*) ref); michael@0: } michael@0: michael@0: bool operator==(nsISupports* b) const { return ref == b; } michael@0: }; michael@0: michael@0: class nsObserverList : public nsCharPtrHashKey michael@0: { michael@0: friend class nsObserverService; michael@0: michael@0: public: michael@0: nsObserverList(const char *key) : nsCharPtrHashKey(key) michael@0: { MOZ_COUNT_CTOR(nsObserverList); } michael@0: michael@0: ~nsObserverList() { MOZ_COUNT_DTOR(nsObserverList); } michael@0: michael@0: nsresult AddObserver(nsIObserver* anObserver, bool ownsWeak); michael@0: nsresult RemoveObserver(nsIObserver* anObserver); michael@0: michael@0: void NotifyObservers(nsISupports *aSubject, michael@0: const char *aTopic, michael@0: const char16_t *someData); michael@0: nsresult GetObserverList(nsISimpleEnumerator** anEnumerator); michael@0: michael@0: // Fill an array with the observers of this category. michael@0: // The array is filled in last-added-first order. michael@0: void FillObserverArray(nsCOMArray &aArray); michael@0: michael@0: // Unmark any strongly held observers implemented in JS so the cycle michael@0: // collector will not traverse them. michael@0: void UnmarkGrayStrongObservers(); michael@0: michael@0: private: michael@0: nsTArray mObservers; michael@0: }; michael@0: michael@0: class nsObserverEnumerator MOZ_FINAL : public nsISimpleEnumerator michael@0: { michael@0: public: michael@0: NS_DECL_ISUPPORTS michael@0: NS_DECL_NSISIMPLEENUMERATOR michael@0: michael@0: nsObserverEnumerator(nsObserverList* aObserverList); michael@0: michael@0: private: michael@0: ~nsObserverEnumerator() { } michael@0: michael@0: int32_t mIndex; // Counts up from 0 michael@0: nsCOMArray mObservers; michael@0: }; michael@0: michael@0: #endif /* nsObserverList_h___ */