Backed out changeset 5f819082a015 (bug 1936189) for causing reftest failures @ native...
[gecko.git] / xpcom / ds / nsObserverList.cpp
blob4f21c4fcc9aecfcca849b55f6e9116e1e82060f3
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "nsObserverList.h"
9 #include "mozilla/ResultExtensions.h"
10 #include "mozilla/Try.h"
11 #include "nsCOMArray.h"
12 #include "xpcpublic.h"
14 nsresult nsObserverList::AddObserver(nsIObserver* anObserver, bool ownsWeak) {
15 NS_ASSERTION(anObserver, "Null input");
17 MOZ_TRY(mObservers.AppendWeakElement(anObserver, ownsWeak));
18 return NS_OK;
21 nsresult nsObserverList::RemoveObserver(nsIObserver* anObserver) {
22 NS_ASSERTION(anObserver, "Null input");
24 MOZ_TRY(mObservers.RemoveWeakElement(anObserver));
25 return NS_OK;
28 void nsObserverList::GetObserverList(nsISimpleEnumerator** anEnumerator) {
29 RefPtr<nsObserverEnumerator> e(new nsObserverEnumerator(this));
30 e.forget(anEnumerator);
33 nsCOMArray<nsIObserver> nsObserverList::ReverseCloneObserverArray() {
34 nsCOMArray<nsIObserver> array;
35 array.SetCapacity(mObservers.Length());
37 // XXX This could also use RemoveElementsBy if we lifted the promise to fill
38 // aArray in reverse order. Although there shouldn't be anyone explicitly
39 // relying on the order, changing this might cause subtle problems, so we
40 // better leave it as it is.
42 for (int32_t i = mObservers.Length() - 1; i >= 0; --i) {
43 nsCOMPtr<nsIObserver> observer = mObservers[i].GetValue();
44 if (observer) {
45 array.AppendElement(observer.forget());
46 } else {
47 // the object has gone away, remove the weakref
48 mObservers.RemoveElementAt(i);
52 return array;
55 void nsObserverList::AppendStrongObservers(nsCOMArray<nsIObserver>& aArray) {
56 aArray.SetCapacity(aArray.Length() + mObservers.Length());
58 for (int32_t i = mObservers.Length() - 1; i >= 0; --i) {
59 if (!mObservers[i].IsWeak()) {
60 nsCOMPtr<nsIObserver> observer = mObservers[i].GetValue();
61 aArray.AppendObject(observer);
66 void nsObserverList::NotifyObservers(nsISupports* aSubject, const char* aTopic,
67 const char16_t* someData) {
68 const nsCOMArray<nsIObserver> observers = ReverseCloneObserverArray();
70 for (int32_t i = 0; i < observers.Count(); ++i) {
71 observers[i]->Observe(aSubject, aTopic, someData);
75 nsObserverEnumerator::nsObserverEnumerator(nsObserverList* aObserverList)
76 : mIndex(0), mObservers(aObserverList->ReverseCloneObserverArray()) {}
78 NS_IMETHODIMP
79 nsObserverEnumerator::HasMoreElements(bool* aResult) {
80 *aResult = (mIndex < mObservers.Count());
81 return NS_OK;
84 NS_IMETHODIMP
85 nsObserverEnumerator::GetNext(nsISupports** aResult) {
86 if (mIndex == mObservers.Count()) {
87 return NS_ERROR_FAILURE;
90 NS_ADDREF(*aResult = mObservers[mIndex]);
91 ++mIndex;
92 return NS_OK;