OLD | NEW |
---|---|
1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef SKIA_EXT_REFPTR_H_ | 5 #ifndef SKIA_EXT_REFPTR_H_ |
6 #define SKIA_EXT_REFPTR_H_ | 6 #define SKIA_EXT_REFPTR_H_ |
7 | 7 |
8 #include "base/basictypes.h" | |
9 #include "base/logging.h" | |
8 #include "third_party/skia/include/core/SkRefCnt.h" | 10 #include "third_party/skia/include/core/SkRefCnt.h" |
9 | 11 |
10 namespace skia { | 12 namespace skia { |
11 | 13 |
12 // When creating/receiving a ref-counted pointer from Skia, wrap that pointer in | 14 // When creating/receiving a ref-counted pointer from Skia, wrap that pointer in |
13 // this class to avoid dealing with the ref-counting and prevent leaks/crashes | 15 // this class to avoid dealing with the ref-counting and prevent leaks/crashes |
14 // due to ref-counting bugs. | 16 // due to ref-counting bugs. |
15 // | 17 // |
16 // Example of creating a new SkShader* and setting it on a SkPaint: | 18 // Example of creating a new SkShader* and setting it on a SkPaint: |
17 // skia::RefPtr<SkShader> shader = skia::AdoptRef(SkGradientShader::Create()); | 19 // skia::RefPtr<SkShader> shader = skia::AdoptRef(SkGradientShader::Create()); |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
80 | 82 |
81 T* get() const { return ptr_; } | 83 T* get() const { return ptr_; } |
82 T& operator*() const { return *ptr_; } | 84 T& operator*() const { return *ptr_; } |
83 T* operator->() const { return ptr_; } | 85 T* operator->() const { return ptr_; } |
84 | 86 |
85 typedef T* RefPtr::*unspecified_bool_type; | 87 typedef T* RefPtr::*unspecified_bool_type; |
86 operator unspecified_bool_type() const { | 88 operator unspecified_bool_type() const { |
87 return ptr_ ? &RefPtr::ptr_ : NULL; | 89 return ptr_ ? &RefPtr::ptr_ : NULL; |
88 } | 90 } |
89 | 91 |
92 class Receiver { | |
93 public: | |
94 ~Receiver() { | |
95 DCHECK(!*refptr_) << "RefPtr must be empty."; | |
96 refptr_->ptr_ = ptr_; | |
97 } | |
98 | |
99 operator T**() { return &ptr_; } | |
100 | |
101 private: | |
102 friend class RefPtr; | |
103 | |
104 Receiver(RefPtr* refptr) : refptr_(refptr), ptr_(NULL) { | |
awong
2013/07/17 23:12:59
explicit?
danakj
2013/07/17 23:18:46
Done.
| |
105 DCHECK(!*refptr_) << "RefPtr must be empty."; | |
106 } | |
107 | |
108 RefPtr* refptr_; | |
109 T* ptr_; | |
110 | |
111 DISALLOW_COPY_AND_ASSIGN(Receiver); | |
112 }; | |
113 | |
114 Receiver ReceiveAndAdoptRef() { return Receiver(this); } | |
awong
2013/07/17 23:12:59
Add comment saying to not use this as part of a su
danakj
2013/07/17 23:18:46
Good point! Done, with examples.
| |
115 | |
90 private: | 116 private: |
91 T* ptr_; | 117 T* ptr_; |
92 | 118 |
93 // This function cannot be public because Skia starts its ref-counted | 119 // This function cannot be public because Skia starts its ref-counted |
94 // objects at refcnt=1. This makes it impossible to differentiate | 120 // objects at refcnt=1. This makes it impossible to differentiate |
95 // between a newly created object (that doesn't need to be ref'd) or an | 121 // between a newly created object (that doesn't need to be ref'd) or an |
96 // already existing object with one owner (that does need to be ref'd so that | 122 // already existing object with one owner (that does need to be ref'd so that |
97 // this RefPtr can also manage its lifetime). | 123 // this RefPtr can also manage its lifetime). |
98 explicit RefPtr(T* ptr) : ptr_(ptr) {} | 124 explicit RefPtr(T* ptr) : ptr_(ptr) {} |
99 | 125 |
100 template<typename U> | 126 template<typename U> |
101 friend RefPtr<U> AdoptRef(U* ptr); | 127 friend RefPtr<U> AdoptRef(U* ptr); |
102 | 128 |
103 template<typename U> | 129 template<typename U> |
104 friend RefPtr<U> SharePtr(U* ptr); | 130 friend RefPtr<U> SharePtr(U* ptr); |
105 }; | 131 }; |
106 | 132 |
107 // For objects that have an unowned reference (such as newly created objects). | 133 // For objects that have an unowned reference (such as newly created objects). |
108 template<typename T> | 134 template<typename T> |
109 RefPtr<T> AdoptRef(T* ptr) { return RefPtr<T>(ptr); } | 135 RefPtr<T> AdoptRef(T* ptr) { return RefPtr<T>(ptr); } |
110 | 136 |
111 // For objects that are already owned. This doesn't take ownership of existing | 137 // For objects that are already owned. This doesn't take ownership of existing |
112 // references and adds a new one. | 138 // references and adds a new one. |
113 template<typename T> | 139 template<typename T> |
114 RefPtr<T> SharePtr(T* ptr) { return RefPtr<T>(SkSafeRef(ptr)); } | 140 RefPtr<T> SharePtr(T* ptr) { return RefPtr<T>(SkSafeRef(ptr)); } |
115 | 141 |
116 } // namespace skia | 142 } // namespace skia |
117 | 143 |
118 #endif // SKIA_EXT_REFPTR_H_ | 144 #endif // SKIA_EXT_REFPTR_H_ |
OLD | NEW |