| 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
27 ObjectBase& operator=(ObjectBase&&) = delete;
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
88 ScopedObject& operator=(const ScopedObject& other) {
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
102 ScopedObject& operator=(ScopedObject&& other) {
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]]
126 typename Object::InteropCSibling* Leak() {
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>
146 ScopedObject<Object> Ref(Object* object) {
147 return ScopedObject<Object>{object};
148 }
149
150 template <typename Object>
151 ScopedObject<Object> Adopt(Object* object) {
152 return ScopedObject<Object>{object, AdoptTag::kAdopted};
153 }
154
155 template <typename Object>
156 ScopedObject<Object> Adopt(typename Object::InteropCSibling* 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)...),
163 AdoptTag::kAdopted};
164 }
165
166 } // namespace impeller::interop
167
168 #endif // FLUTTER_IMPELLER_TOOLKIT_INTEROP_OBJECT_H_
impeller::interop::ObjectBase
Definition: object.h:15
impeller::interop::ObjectBase::ObjectBase
ObjectBase(const ObjectBase &)=delete
impeller::interop::ObjectBase::SafeRelease
static void SafeRelease(void *ptr)
Definition: object.h:43
impeller::interop::ObjectBase::operator=
ObjectBase & operator=(ObjectBase &&)=delete
impeller::interop::ObjectBase::~ObjectBase
virtual ~ObjectBase()=default
impeller::interop::ObjectBase::operator=
ObjectBase & operator=(const ObjectBase &)=delete
impeller::interop::ObjectBase::GetRefCountForTests
uint64_t GetRefCountForTests() const
Definition: object.h:49
impeller::interop::ObjectBase::Release
void Release()
Definition: object.h:31
impeller::interop::ObjectBase::ObjectBase
ObjectBase()=default
impeller::interop::ObjectBase::ObjectBase
ObjectBase(ObjectBase &&)=delete
impeller::interop::ObjectBase::SafeRetain
static void SafeRetain(void *ptr)
Definition: object.h:37
impeller::interop::ObjectBase::Retain
void Retain()
Definition: object.h:29
impeller::interop::Object
Definition: object.h:56
impeller::interop::Object::InteropClass
Clasz InteropClass
Definition: object.h:58
impeller::interop::Object::InteropCSibling
CSibling InteropCSibling
Definition: object.h:59
impeller::interop::ScopedObject
Definition: object.h:67
impeller::interop::ScopedObject::~ScopedObject
~ScopedObject()
Definition: object.h:82
impeller::interop::ScopedObject::ScopedObject
ScopedObject()=default
impeller::interop::ScopedObject::operator=
ScopedObject & operator=(ScopedObject &&other)
Definition: object.h:102
impeller::interop::ScopedObject::operator*
Object & operator*() const
Definition: object.h:113
impeller::interop::ScopedObject::GetC
Object::InteropCSibling * GetC() const
Definition: object.h:109
impeller::interop::ScopedObject::ScopedObject
ScopedObject(Object *ptr, AdoptTag)
Definition: object.h:74
impeller::interop::ScopedObject::ScopedObject
ScopedObject(std::nullptr_t)
Definition: object.h:71
impeller::interop::ScopedObject::operator=
ScopedObject & operator=(const ScopedObject &other)
Definition: object.h:88
impeller::interop::ScopedObject::ScopedObject
ScopedObject(Object *ptr)
Definition: object.h:76
impeller::interop::ScopedObject::ScopedObject
ScopedObject(const ScopedObject &other)
Definition: object.h:84
impeller::interop::ScopedObject::ScopedObject
ScopedObject(ScopedObject &&other)
Definition: object.h:86
impeller::interop::ScopedObject::Leak
Object::InteropCSibling * Leak()
Definition: object.h:126
impeller::interop::ScopedObject::operator->
Object * operator->() const
Definition: object.h:118
impeller::interop::ScopedObject::Get
Object * Get() const
Definition: object.h:107
impeller::interop
Definition: context_gles.cc:12
impeller::interop::Ref
ScopedObject< Object > Ref(Object *object)
Definition: object.h:146
impeller::interop::Adopt
ScopedObject< Object > Adopt(Object *object)
Definition: object.h:151
impeller::interop::AdoptTag
AdoptTag
Definition: object.h:62
impeller::interop::AdoptTag::kAdopted
@ kAdopted
impeller::interop::Create
ScopedObject< Object > Create(CtorArgs &&... args)
Definition: object.h:161