1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "nsObserverList.h"
9 #include "nsCOMArray.h"
10 #include "nsISimpleEnumerator.h"
11 #include "xpcpublic.h"
14 nsObserverList::AddObserver(nsIObserver
* anObserver
, bool ownsWeak
)
16 NS_ASSERTION(anObserver
, "Null input");
19 ObserverRef
* o
= mObservers
.AppendElement(anObserver
);
21 return NS_ERROR_OUT_OF_MEMORY
;
26 nsCOMPtr
<nsIWeakReference
> weak
= do_GetWeakReference(anObserver
);
28 return NS_NOINTERFACE
;
30 ObserverRef
*o
= mObservers
.AppendElement(weak
);
32 return NS_ERROR_OUT_OF_MEMORY
;
38 nsObserverList::RemoveObserver(nsIObserver
* anObserver
)
40 NS_ASSERTION(anObserver
, "Null input");
42 if (mObservers
.RemoveElement(static_cast<nsISupports
*>(anObserver
)))
45 nsCOMPtr
<nsIWeakReference
> observerRef
= do_GetWeakReference(anObserver
);
47 return NS_ERROR_FAILURE
;
49 if (!mObservers
.RemoveElement(observerRef
))
50 return NS_ERROR_FAILURE
;
56 nsObserverList::GetObserverList(nsISimpleEnumerator
** anEnumerator
)
58 nsRefPtr
<nsObserverEnumerator
> e(new nsObserverEnumerator(this));
59 e
.forget(anEnumerator
);
64 nsObserverList::FillObserverArray(nsCOMArray
<nsIObserver
> &aArray
)
66 aArray
.SetCapacity(mObservers
.Length());
68 nsTArray
<ObserverRef
> observers(mObservers
);
70 for (int32_t i
= observers
.Length() - 1; i
>= 0; --i
) {
71 if (observers
[i
].isWeakRef
) {
72 nsCOMPtr
<nsIObserver
> o(do_QueryReferent(observers
[i
].asWeak()));
74 aArray
.AppendObject(o
);
77 // the object has gone away, remove the weakref
78 mObservers
.RemoveElement(observers
[i
].asWeak());
82 aArray
.AppendObject(observers
[i
].asObserver());
88 nsObserverList::NotifyObservers(nsISupports
*aSubject
,
90 const char16_t
*someData
)
92 nsCOMArray
<nsIObserver
> observers
;
93 FillObserverArray(observers
);
95 for (int32_t i
= 0; i
< observers
.Count(); ++i
) {
96 observers
[i
]->Observe(aSubject
, aTopic
, someData
);
101 nsObserverList::UnmarkGrayStrongObservers()
103 for (uint32_t i
= 0; i
< mObservers
.Length(); ++i
) {
104 if (!mObservers
[i
].isWeakRef
) {
105 xpc_TryUnmarkWrappedGrayObject(mObservers
[i
].asObserver());
110 NS_IMPL_ISUPPORTS1(nsObserverEnumerator
, nsISimpleEnumerator
)
112 nsObserverEnumerator::nsObserverEnumerator(nsObserverList
* aObserverList
)
115 aObserverList
->FillObserverArray(mObservers
);
119 nsObserverEnumerator::HasMoreElements(bool *aResult
)
121 *aResult
= (mIndex
< mObservers
.Count());
126 nsObserverEnumerator::GetNext(nsISupports
* *aResult
)
128 if (mIndex
== mObservers
.Count()) {
129 NS_ERROR("Enumerating after HasMoreElements returned false.");
130 return NS_ERROR_UNEXPECTED
;
133 NS_ADDREF(*aResult
= mObservers
[mIndex
]);