3737
3838#include " nsObserverList.h"
3939
40- #include " pratom.h"
41- #include " nsAutoLock.h"
4240#include " nsAutoPtr.h"
43- #include " nsCOMPtr.h"
44- #include " nsIObserver.h"
41+ #include " nsCOMArray.h"
4542#include " nsISimpleEnumerator.h"
46- #include " nsIWeakReference.h"
47-
48- nsObserverList::nsObserverList (nsresult &rv)
49- {
50- MOZ_COUNT_CTOR (nsObserverList);
51- mLock = PR_NewLock ();
52- if (!mLock )
53- rv = NS_ERROR_OUT_OF_MEMORY;
54- }
55-
56- nsObserverList::~nsObserverList (void )
57- {
58- MOZ_COUNT_DTOR (nsObserverList);
59- if (mLock )
60- PR_DestroyLock (mLock );
61- }
6243
6344nsresult
6445nsObserverList::AddObserver (nsIObserver* anObserver, PRBool ownsWeak)
6546{
66- NS_ENSURE_ARG (anObserver);
67-
68- nsAutoLock lock (mLock );
69-
70- nsCOMPtr<nsISupports> observerRef;
71- if (ownsWeak) {
72- nsCOMPtr<nsISupportsWeakReference>
73- weakRefFactory (do_QueryInterface (anObserver));
74- NS_ASSERTION (weakRefFactory,
75- " Doesn't implement nsISupportsWeakReference" );
76- if (weakRefFactory)
77- weakRefFactory->
78- GetWeakReference ((nsIWeakReference**)(nsISupports**)
79- getter_AddRefs (observerRef));
80- } else {
81- observerRef = anObserver;
47+ NS_ASSERTION (anObserver, " Null input" );
48+
49+ if (!ownsWeak) {
50+ ObserverRef* o = mObservers .AppendElement (anObserver);
51+ if (!o)
52+ return NS_ERROR_OUT_OF_MEMORY;
53+
54+ return NS_OK;
8255 }
83- if (!observerRef)
84- return NS_ERROR_FAILURE;
56+
57+ nsCOMPtr<nsIWeakReference> weak = do_GetWeakReference (anObserver);
58+ if (!weak)
59+ return NS_NOINTERFACE;
8560
86- if (!mObservers .AppendObject (observerRef))
61+ ObserverRef *o = mObservers .AppendElement (weak);
62+ if (!o)
8763 return NS_ERROR_OUT_OF_MEMORY;
8864
8965 return NS_OK;
@@ -92,93 +68,91 @@ nsObserverList::AddObserver(nsIObserver* anObserver, PRBool ownsWeak)
9268nsresult
9369nsObserverList::RemoveObserver (nsIObserver* anObserver)
9470{
95- NS_ENSURE_ARG (anObserver);
71+ NS_ASSERTION (anObserver, " Null input " );
9672
97- nsAutoLock lock (mLock );
98-
99- if (mObservers .RemoveObject (anObserver))
73+ if (mObservers .RemoveElement (NS_STATIC_CAST(nsISupports*, anObserver)))
10074 return NS_OK;
10175
102- nsCOMPtr<nsISupportsWeakReference>
103- weakRefFactory (do_QueryInterface (anObserver));
104- if (!weakRefFactory)
105- return NS_ERROR_FAILURE;
106-
107- nsCOMPtr<nsIWeakReference> observerRef;
108- weakRefFactory->GetWeakReference (getter_AddRefs (observerRef));
109-
76+ nsCOMPtr<nsIWeakReference> observerRef = do_GetWeakReference (anObserver);
11077 if (!observerRef)
11178 return NS_ERROR_FAILURE;
11279
113- if (!mObservers .RemoveObject (observerRef))
80+ if (!mObservers .RemoveElement (observerRef))
11481 return NS_ERROR_FAILURE;
11582
11683 return NS_OK;
11784}
11885
119- class nsObserverEnumerator : public nsISimpleEnumerator
120- {
121- public:
122- NS_DECL_ISUPPORTS
123- NS_DECL_NSISIMPLEENUMERATOR
124-
125- nsObserverEnumerator (nsCOMArray<nsISupports> &aObservers);
126-
127- private:
128- ~nsObserverEnumerator () { }
129-
130- PRUint32 mIndex ; // Counts down, ends at 0
131- nsCOMArray<nsISupports> mObservers ;
132- };
133-
13486nsresult
13587nsObserverList::GetObserverList (nsISimpleEnumerator** anEnumerator)
13688{
137- nsAutoLock lock (mLock );
138-
139- nsRefPtr<nsObserverEnumerator> e (new nsObserverEnumerator (mObservers ));
89+ nsRefPtr<nsObserverEnumerator> e (new nsObserverEnumerator (this ));
14090 if (!e)
14191 return NS_ERROR_OUT_OF_MEMORY;
14292
14393 NS_ADDREF (*anEnumerator = e);
14494 return NS_OK;
14595}
14696
147- nsObserverEnumerator::nsObserverEnumerator (nsCOMArray<nsISupports> &aObservers)
97+ void
98+ nsObserverList::FillObserverArray (nsCOMArray<nsIObserver> &aArray)
14899{
149- for (PRInt32 i = 0 ; i < aObservers.Count (); ++i) {
150- nsCOMPtr<nsIWeakReference> weak (do_QueryInterface (aObservers[i]));
151- if (weak) {
152- nsCOMPtr<nsISupports> strong (do_QueryReferent (weak));
153- if (strong)
154- mObservers .AppendObject (strong);
100+ aArray.SetCapacity (mObservers .Length ());
101+
102+ for (PRInt32 i = mObservers .Length () - 1 ; i >= 0 ; --i) {
103+ if (mObservers [i].isWeakRef ) {
104+ nsCOMPtr<nsIObserver> o (do_QueryReferent (mObservers [i].asWeak ()));
105+ if (o) {
106+ aArray.AppendObject (o);
107+ }
108+ else {
109+ // the object has gone away, remove the weakref
110+ mObservers .RemoveElementAt (i);
111+ }
155112 }
156113 else {
157- mObservers .AppendObject (aObservers [i]);
114+ aArray .AppendObject (mObservers [i]. asObserver () );
158115 }
159116 }
117+ }
118+
119+ void
120+ nsObserverList::NotifyObservers (nsISupports *aSubject,
121+ const char *aTopic,
122+ const PRUnichar *someData)
123+ {
124+ nsCOMArray<nsIObserver> observers;
125+ FillObserverArray (observers);
160126
161- mIndex = mObservers .Count ();
127+ for (PRInt32 i = 0 ; i < observers.Count (); ++i) {
128+ observers[i]->Observe (aSubject, aTopic, someData);
129+ }
162130}
163131
164132NS_IMPL_ISUPPORTS1 (nsObserverEnumerator, nsISimpleEnumerator)
165133
134+ nsObserverEnumerator::nsObserverEnumerator(nsObserverList* aObserverList)
135+ : mIndex(0 )
136+ {
137+ aObserverList->FillObserverArray (mObservers );
138+ }
139+
166140NS_IMETHODIMP
167141nsObserverEnumerator::HasMoreElements (PRBool *aResult)
168142{
169- *aResult = (mIndex > 0 );
143+ *aResult = (mIndex < mObservers . Count () );
170144 return NS_OK;
171145}
172146
173147NS_IMETHODIMP
174148nsObserverEnumerator::GetNext (nsISupports* *aResult)
175149{
176- if (! mIndex ) {
150+ if (mIndex == mObservers . Count () ) {
177151 NS_ERROR (" Enumerating after HasMoreElements returned false." );
178152 return NS_ERROR_UNEXPECTED;
179153 }
180154
181- --mIndex ;
182155 NS_ADDREF (*aResult = mObservers [mIndex ]);
156+ ++mIndex ;
183157 return NS_OK;
184158}
0 commit comments