|
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
|
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/. */ |
|
5 |
|
6 #ifndef nsMaybeWeakPtr_h_ |
|
7 #define nsMaybeWeakPtr_h_ |
|
8 |
|
9 #include "nsCOMPtr.h" |
|
10 #include "nsWeakReference.h" |
|
11 #include "nsTArray.h" |
|
12 #include "nsCycleCollectionNoteChild.h" |
|
13 |
|
14 // nsMaybeWeakPtr is a helper object to hold a strong-or-weak reference |
|
15 // to the template class. It's pretty minimal, but sufficient. |
|
16 |
|
17 class nsMaybeWeakPtr_base |
|
18 { |
|
19 protected: |
|
20 // Returns an addref'd pointer to the requested interface |
|
21 void* GetValueAs(const nsIID& iid) const; |
|
22 |
|
23 nsCOMPtr<nsISupports> mPtr; |
|
24 }; |
|
25 |
|
26 template<class T> |
|
27 class nsMaybeWeakPtr : private nsMaybeWeakPtr_base |
|
28 { |
|
29 public: |
|
30 nsMaybeWeakPtr(nsISupports *ref) { mPtr = ref; } |
|
31 nsMaybeWeakPtr(const nsCOMPtr<nsIWeakReference> &ref) { mPtr = ref; } |
|
32 nsMaybeWeakPtr(const nsCOMPtr<T> &ref) { mPtr = ref; } |
|
33 |
|
34 bool operator==(const nsMaybeWeakPtr<T> &other) const { |
|
35 return mPtr == other.mPtr; |
|
36 } |
|
37 |
|
38 operator const nsCOMPtr<T>() const { return GetValue(); } |
|
39 |
|
40 protected: |
|
41 const nsCOMPtr<T> GetValue() const { |
|
42 return nsCOMPtr<T>(dont_AddRef(static_cast<T*> |
|
43 (GetValueAs(NS_GET_TEMPLATE_IID(T))))); |
|
44 } |
|
45 }; |
|
46 |
|
47 // nsMaybeWeakPtrArray is an array of MaybeWeakPtr objects, that knows how to |
|
48 // grab a weak reference to a given object if requested. It only allows a |
|
49 // given object to appear in the array once. |
|
50 |
|
51 typedef nsTArray< nsMaybeWeakPtr<nsISupports> > isupports_array_type; |
|
52 nsresult NS_AppendWeakElementBase(isupports_array_type *aArray, |
|
53 nsISupports *aElement, bool aWeak); |
|
54 nsresult NS_RemoveWeakElementBase(isupports_array_type *aArray, |
|
55 nsISupports *aElement); |
|
56 |
|
57 template<class T> |
|
58 class nsMaybeWeakPtrArray : public nsTArray< nsMaybeWeakPtr<T> > |
|
59 { |
|
60 public: |
|
61 nsresult AppendWeakElement(T *aElement, bool aOwnsWeak) |
|
62 { |
|
63 return NS_AppendWeakElementBase( |
|
64 reinterpret_cast<isupports_array_type*>(this), aElement, aOwnsWeak); |
|
65 } |
|
66 |
|
67 nsresult RemoveWeakElement(T *aElement) |
|
68 { |
|
69 return NS_RemoveWeakElementBase( |
|
70 reinterpret_cast<isupports_array_type*>(this), aElement); |
|
71 } |
|
72 }; |
|
73 |
|
74 template <typename T> |
|
75 inline void |
|
76 ImplCycleCollectionUnlink(nsMaybeWeakPtrArray<T>& aField) |
|
77 { |
|
78 aField.Clear(); |
|
79 } |
|
80 |
|
81 template <typename E> |
|
82 inline void |
|
83 ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback, |
|
84 nsMaybeWeakPtrArray<E>& aField, |
|
85 const char* aName, |
|
86 uint32_t aFlags = 0) |
|
87 { |
|
88 aFlags |= CycleCollectionEdgeNameArrayFlag; |
|
89 size_t length = aField.Length(); |
|
90 for (size_t i = 0; i < length; ++i) { |
|
91 CycleCollectionNoteChild(aCallback, aField[i].get(), aName, aFlags); |
|
92 } |
|
93 } |
|
94 |
|
95 // Call a method on each element in the array, but only if the element is |
|
96 // non-null. |
|
97 |
|
98 #define ENUMERATE_WEAKARRAY(array, type, method) \ |
|
99 for (uint32_t array_idx = 0; array_idx < array.Length(); ++array_idx) { \ |
|
100 const nsCOMPtr<type> &e = array.ElementAt(array_idx); \ |
|
101 if (e) \ |
|
102 e->method; \ |
|
103 } |
|
104 |
|
105 #endif |