Chromium Code Reviews| 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 |