Flutter Impeller
object.h
Go to the documentation of this file.
1 // Copyright 2013 The Flutter 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 FLUTTER_IMPELLER_TOOLKIT_INTEROP_OBJECT_H_
6 #define FLUTTER_IMPELLER_TOOLKIT_INTEROP_OBJECT_H_
7 
8 #include <atomic>
9 #include <utility>
10 
11 #include "flutter/fml/logging.h"
12 
13 namespace impeller::interop {
14 
15 class ObjectBase {
16  public:
17  ObjectBase() = default;
18 
19  virtual ~ObjectBase() = default;
20 
21  ObjectBase(const ObjectBase&) = delete;
22 
23  ObjectBase(ObjectBase&&) = delete;
24 
25  ObjectBase& operator=(const ObjectBase&) = delete;
26 
28 
29  void Retain() { ref_count_++; }
30 
31  void Release() {
32  if (ref_count_-- == 1u) {
33  delete this;
34  }
35  }
36 
37  static void SafeRetain(void* ptr) {
38  if (ptr) {
39  reinterpret_cast<ObjectBase*>(ptr)->Retain();
40  }
41  }
42 
43  static void SafeRelease(void* ptr) {
44  if (ptr) {
45  reinterpret_cast<ObjectBase*>(ptr)->Release();
46  }
47  }
48 
49  uint64_t GetRefCountForTests() const { return ref_count_; }
50 
51  private:
52  std::atomic_uint64_t ref_count_ = {1u};
53 };
54 
55 template <typename Clasz, typename CSibling>
56 class Object : public ObjectBase {
57  public:
58  using InteropClass = Clasz;
59  using InteropCSibling = CSibling;
60 };
61 
62 enum class AdoptTag {
63  kAdopted,
64 };
65 
66 template <typename Object>
67 class ScopedObject final {
68  public:
69  ScopedObject() = default;
70 
71  ScopedObject(std::nullptr_t) // NOLINT(google-explicit-constructor)
72  {}
73 
74  explicit ScopedObject(Object* ptr, AdoptTag) : object_(ptr) {}
75 
76  explicit ScopedObject(Object* ptr) : object_(ptr) {
77  if (object_) {
78  object_->Retain();
79  }
80  }
81 
82  ~ScopedObject() { Release(); }
83 
84  ScopedObject(const ScopedObject& other) : ScopedObject(other.Get()) {}
85 
86  ScopedObject(ScopedObject&& other) { std::swap(object_, other.object_); }
87 
89  // Self assignment.
90  if (object_ == other.object_) {
91  return *this;
92  }
93  if (other.object_) {
94  other.object_->Retain();
95  }
96  Release();
97  FML_DCHECK(object_ == nullptr);
98  object_ = other.object_;
99  return *this;
100  }
101 
103  std::swap(object_, other.object_);
104  return *this;
105  }
106 
107  Object* Get() const { return object_; }
108 
109  typename Object::InteropCSibling* GetC() const {
110  return reinterpret_cast<typename Object::InteropCSibling*>(Get());
111  }
112 
113  Object& operator*() const {
114  FML_DCHECK(object_);
115  return *object_;
116  }
117 
118  Object* operator->() const {
119  FML_DCHECK(object_);
120  return object_;
121  }
122 
123  explicit operator bool() const { return !!object_; }
124 
125  [[nodiscard]]
127  auto to_leak = object_;
128  object_ = nullptr;
129  return reinterpret_cast<typename Object::InteropCSibling*>(to_leak);
130  }
131 
132  private:
133  Object* object_ = nullptr;
134 
135  void Release() {
136  if (object_) {
137  // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDelete)
138  object_->Release();
139  object_ = nullptr;
140  }
141  // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)
142  }
143 };
144 
145 template <typename Object>
147  return ScopedObject<Object>{object};
148 }
149 
150 template <typename Object>
153 }
154 
155 template <typename Object>
157  return Adopt(reinterpret_cast<Object*>(object));
158 }
159 
160 template <typename Object, typename... CtorArgs>
161 ScopedObject<Object> Create(CtorArgs&&... args) {
162  return ScopedObject<Object>{new Object(std::forward<CtorArgs>(args)...),
164 }
165 
166 } // namespace impeller::interop
167 
168 #endif // FLUTTER_IMPELLER_TOOLKIT_INTEROP_OBJECT_H_
ObjectBase(const ObjectBase &)=delete
static void SafeRelease(void *ptr)
Definition: object.h:43
ObjectBase & operator=(ObjectBase &&)=delete
virtual ~ObjectBase()=default
ObjectBase & operator=(const ObjectBase &)=delete
uint64_t GetRefCountForTests() const
Definition: object.h:49
ObjectBase(ObjectBase &&)=delete
static void SafeRetain(void *ptr)
Definition: object.h:37
CSibling InteropCSibling
Definition: object.h:59
ScopedObject & operator=(ScopedObject &&other)
Definition: object.h:102
Object & operator*() const
Definition: object.h:113
Object::InteropCSibling * GetC() const
Definition: object.h:109
ScopedObject(Object *ptr, AdoptTag)
Definition: object.h:74
ScopedObject(std::nullptr_t)
Definition: object.h:71
ScopedObject & operator=(const ScopedObject &other)
Definition: object.h:88
ScopedObject(const ScopedObject &other)
Definition: object.h:84
ScopedObject(ScopedObject &&other)
Definition: object.h:86
Object::InteropCSibling * Leak()
Definition: object.h:126
Object * operator->() const
Definition: object.h:118
Object * Get() const
Definition: object.h:107
ScopedObject< Object > Ref(Object *object)
Definition: object.h:146
ScopedObject< Object > Adopt(Object *object)
Definition: object.h:151
ScopedObject< Object > Create(CtorArgs &&... args)
Definition: object.h:161