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,108 @@ nsObserverList::AddObserver(nsIObserver* anObserver, PRBool ownsWeak)
9268nsresult
9369nsObserverList::RemoveObserver (nsIObserver* anObserver)
9470{
95- NS_ENSURE_ARG (anObserver);
96-
97- nsAutoLock lock (mLock );
71+ NS_ASSERTION (anObserver, " Null input" );
9872
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::EnumerateObservers (EnumObserversFunc aFunc, void *aClosure)
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+ for (PRInt32 i = mObservers .Length () - 1 ; i >= 0 ; --i) {
101+ if (mObservers [i].isWeakRef ) {
102+ nsCOMPtr<nsIObserver> o (do_QueryReferent (mObservers [i].asWeak ()));
103+ if (o) {
104+ aFunc (o, aClosure);
105+ }
106+ else {
107+ // the object has gone away, remove the weakref
108+ mObservers .RemoveElementAt (i);
109+ }
155110 }
156111 else {
157- mObservers . AppendObject (aObservers [i]);
112+ aFunc ( mObservers [i]. asObserver (), aClosure );
158113 }
159114 }
115+ }
116+
117+ struct NotifyData
118+ {
119+ nsISupports* aSubject;
120+ const char *aTopic;
121+ const PRUnichar *someData;
122+ };
123+
124+ void
125+ nsObserverList::NotifyObservers (nsISupports *aSubject,
126+ const char *aTopic,
127+ const PRUnichar *someData)
128+ {
129+ NotifyData nd = { aSubject, aTopic, someData };
130+ EnumerateObservers (Notify, &nd);
131+ }
160132
161- mIndex = mObservers .Count ();
133+ void
134+ nsObserverList::Notify (nsIObserver* aObserver, void *aClosure)
135+ {
136+ NotifyData *nd = NS_REINTERPRET_CAST(NotifyData*, aClosure);
137+ aObserver->Observe (nd->aSubject , nd->aTopic , nd->someData );
162138}
163139
164140NS_IMPL_ISUPPORTS1 (nsObserverEnumerator, nsISimpleEnumerator)
165141
142+ void
143+ nsObserverEnumerator::Fill(nsIObserver* aObserver, void *aClosure)
144+ {
145+ nsObserverEnumerator* e =
146+ NS_REINTERPRET_CAST (nsObserverEnumerator*, aClosure);
147+ e->mObservers .AppendObject (aObserver);
148+ }
149+
150+ nsObserverEnumerator::nsObserverEnumerator (nsObserverList* aObserverList)
151+ : mIndex(0 )
152+ {
153+ mObservers .SetCapacity (aObserverList->mObservers .Length ());
154+ aObserverList->EnumerateObservers (Fill, this );
155+ }
156+
166157NS_IMETHODIMP
167158nsObserverEnumerator::HasMoreElements (PRBool *aResult)
168159{
169- *aResult = (mIndex > 0 );
160+ *aResult = (mIndex < mObservers . Count () );
170161 return NS_OK;
171162}
172163
173164NS_IMETHODIMP
174165nsObserverEnumerator::GetNext (nsISupports* *aResult)
175166{
176- if (! mIndex ) {
167+ if (mIndex == mObservers . Count () ) {
177168 NS_ERROR (" Enumerating after HasMoreElements returned false." );
178169 return NS_ERROR_UNEXPECTED;
179170 }
180171
181- --mIndex ;
182172 NS_ADDREF (*aResult = mObservers [mIndex ]);
173+ ++mIndex ;
183174 return NS_OK;
184175}
0 commit comments