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 "nsCOMArray.h"
11 #include "xpcpublic.h"
13 nsresult
nsObserverList::AddObserver(nsIObserver
* anObserver
, bool ownsWeak
) {
14 NS_ASSERTION(anObserver
, "Null input");
16 MOZ_TRY(mObservers
.AppendWeakElement(anObserver
, ownsWeak
));
20 nsresult
nsObserverList::RemoveObserver(nsIObserver
* anObserver
) {
21 NS_ASSERTION(anObserver
, "Null input");
23 MOZ_TRY(mObservers
.RemoveWeakElement(anObserver
));
27 void nsObserverList::GetObserverList(nsISimpleEnumerator
** anEnumerator
) {
28 RefPtr
<nsObserverEnumerator
> e(new nsObserverEnumerator(this));
29 e
.forget(anEnumerator
);
32 nsCOMArray
<nsIObserver
> nsObserverList::ReverseCloneObserverArray() {
33 nsCOMArray
<nsIObserver
> array
;
34 array
.SetCapacity(mObservers
.Length());
36 // XXX This could also use RemoveElementsBy if we lifted the promise to fill
37 // aArray in reverse order. Although there shouldn't be anyone explicitly
38 // relying on the order, changing this might cause subtle problems, so we
39 // better leave it as it is.
41 for (int32_t i
= mObservers
.Length() - 1; i
>= 0; --i
) {
42 nsCOMPtr
<nsIObserver
> observer
= mObservers
[i
].GetValue();
44 array
.AppendElement(observer
.forget());
46 // the object has gone away, remove the weakref
47 mObservers
.RemoveElementAt(i
);
54 void nsObserverList::AppendStrongObservers(nsCOMArray
<nsIObserver
>& aArray
) {
55 aArray
.SetCapacity(aArray
.Length() + mObservers
.Length());
57 for (int32_t i
= mObservers
.Length() - 1; i
>= 0; --i
) {
58 if (!mObservers
[i
].IsWeak()) {
59 nsCOMPtr
<nsIObserver
> observer
= mObservers
[i
].GetValue();
60 aArray
.AppendObject(observer
);
65 void nsObserverList::NotifyObservers(nsISupports
* aSubject
, const char* aTopic
,
66 const char16_t
* someData
) {
67 const nsCOMArray
<nsIObserver
> observers
= ReverseCloneObserverArray();
69 for (int32_t i
= 0; i
< observers
.Count(); ++i
) {
70 observers
[i
]->Observe(aSubject
, aTopic
, someData
);
74 nsObserverEnumerator::nsObserverEnumerator(nsObserverList
* aObserverList
)
75 : mIndex(0), mObservers(aObserverList
->ReverseCloneObserverArray()) {}
78 nsObserverEnumerator::HasMoreElements(bool* aResult
) {
79 *aResult
= (mIndex
< mObservers
.Count());
84 nsObserverEnumerator::GetNext(nsISupports
** aResult
) {
85 if (mIndex
== mObservers
.Count()) {
86 return NS_ERROR_FAILURE
;
89 NS_ADDREF(*aResult
= mObservers
[mIndex
]);