OLD | NEW |
---|---|
(Empty) | |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 #ifndef SKIA_EXT_REFPTR_H_ | |
6 #define SKIA_EXT_REFPTR_H_ | |
7 | |
8 #include "third_party/skia/include/core/SkRefCnt.h" | |
9 | |
10 namespace skia { | |
11 | |
12 // 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 | |
14 // due to ref-counting bugs. | |
15 // | |
16 // Example of Creating an SkShader* and setting it on a SkPaint: | |
17 // skia::RefPtr<SkShader> shader = skia::AdoptRef(SkGradientShader::Create()); | |
18 // paint.setShader(shader.get()); | |
19 // | |
20 // When passing around a ref-counted pointer to methods outside of Skia, always | |
21 // pass around the skia::RefPtr instead of the raw pointer. An example method | |
22 // that takes a SkShader* parameter and saves the SkShader* in the class. | |
23 // void AMethodThatSavesAShader(const skia::RefPtr<SkShader>& shader) { | |
24 // member_refptr_ = shader; | |
25 // } | |
26 // skia::RefPtr<SkShader> member_refptr_; | |
27 // | |
28 // When returning a ref-counted ponter, also return the skia::RefPtr instead. An | |
29 // example method that creates an SkShader* and returns it: | |
30 // skia::RefPtr<SkShader> MakeAShader() { | |
31 // return skia::AdoptRef(SkGradientShader::Create()); | |
32 // } | |
33 // | |
34 // Never call ref() or unref() on the underlying ref-counted pointer. If you | |
35 // wrap the raw pointer immediately in a skia::RefPtr and always work with | |
36 // skia::RefPtr instances instead, the ref-counting will be taken care of for | |
37 // you. | |
38 template<typename T> | |
39 class RefPtr { | |
40 public: | |
41 RefPtr() : ptr_(NULL) {} | |
42 | |
43 RefPtr(const RefPtr<T>& other) | |
awong
2012/11/30 00:10:25
Remove the <T>
danakj
2012/11/30 00:25:09
Done.
| |
44 : ptr_(other.get()) { | |
45 SkSafeRef(ptr_); | |
46 } | |
47 | |
48 template<typename U> | |
49 RefPtr(const RefPtr<U>& other) | |
50 : ptr_(other.get()) { | |
51 SkSafeRef(ptr_); | |
52 } | |
53 | |
54 ~RefPtr() { | |
55 clear(); | |
56 } | |
57 | |
58 RefPtr& operator=(const RefPtr<T>& other) { | |
awong
2012/11/30 00:10:25
Remove the <T>
danakj
2012/11/30 00:25:09
Done.
| |
59 SkRefCnt_SafeAssign(ptr_, other.get()); | |
60 return *this; | |
61 } | |
62 | |
63 template<typename U> | |
64 RefPtr& operator=(const RefPtr<U>& other) { | |
65 SkRefCnt_SafeAssign(ptr_, other.get()); | |
66 return *this; | |
67 } | |
68 | |
69 void clear() { | |
70 T* to_unref = ptr_; | |
71 ptr_ = NULL; | |
72 SkSafeUnref(to_unref); | |
73 } | |
74 | |
75 T* get() const { return ptr_; } | |
76 T& operator*() const { return static_cast<T&>(*ptr_); } | |
awong
2012/11/30 00:10:25
Why are we doing a static_cast<>?
danakj
2012/11/30 00:25:09
oh, i was toying with hiding ref() and unref() in
| |
77 T* operator->() const { return static_cast<T*>(ptr_); } | |
78 | |
79 typedef T* RefPtr::*unspecified_bool_type; | |
80 operator unspecified_bool_type() const { | |
81 return ptr_ ? &RefPtr::ptr_ : NULL; | |
82 } | |
83 | |
84 private: | |
85 T* ptr_; | |
86 | |
87 explicit RefPtr(T* ptr) : ptr_(ptr) {} | |
88 | |
89 template<typename U> | |
90 friend RefPtr<U> AdoptRef(U* ptr); | |
91 }; | |
92 | |
93 template<typename T> | |
94 RefPtr<T> AdoptRef(T* ptr) { return RefPtr<T>(ptr); } | |
95 | |
96 } // namespace skia | |
97 | |
98 #endif // SKIA_EXT_REFPTR_H_ | |
OLD | NEW |