| Flutter Impeller |

capture.cc
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 #include "impeller/core/capture.h"
6
7 #include <initializer_list>
8 #include <memory>
9
10 namespace impeller {
11
12 //-----------------------------------------------------------------------------
13 /// CaptureProperty
14 ///
15
16 CaptureProperty::CaptureProperty(const std::string& label, Options options)
17 : CaptureCursorListElement(label), options(options) {}
18
19 CaptureProperty::~CaptureProperty() = default;
20
21 bool CaptureProperty::MatchesCloselyEnough(const CaptureProperty& other) const {
22 if (label != other.label) {
23 return false;
24 }
25 if (GetType() != other.GetType()) {
26 return false;
27 }
28 return true;
29 }
30
31 #define _CAPTURE_PROPERTY_CAST_DEFINITION(type_name, pascal_name, lower_name) \
32 std::optional<type_name> CaptureProperty::As##pascal_name() const { \
33 if (GetType() != Type::k##pascal_name) { \
34 return std::nullopt; \
35 } \
36 return reinterpret_cast<const Capture##pascal_name##Property*>(this) \
37 ->value; \
38 }
39
40 _FOR_EACH_CAPTURE_PROPERTY(_CAPTURE_PROPERTY_CAST_DEFINITION);
41
42 #define _CAPTURE_PROPERTY_DEFINITION(type_name, pascal_name, lower_name) \
43 Capture##pascal_name##Property::Capture##pascal_name##Property( \
44 const std::string& label, type_name value, Options options) \
45 : CaptureProperty(label, options), value(std::move(value)) {} \
46 \
47 std::shared_ptr<Capture##pascal_name##Property> \
48 Capture##pascal_name##Property::Make(const std::string& label, \
49 type_name value, Options options) { \
50 auto result = std::shared_ptr<Capture##pascal_name##Property>( \
51 new Capture##pascal_name##Property(label, std::move(value), options)); \
52 return result; \
53 } \
54 \
55 CaptureProperty::Type Capture##pascal_name##Property::GetType() const { \
56 return Type::k##pascal_name; \
57 } \
58 \
59 void Capture##pascal_name##Property::Invoke( \
60 const CaptureProcTable& proc_table) { \
61 proc_table.lower_name(*this); \
62 }
63
64 _FOR_EACH_CAPTURE_PROPERTY(_CAPTURE_PROPERTY_DEFINITION);
65
66 //-----------------------------------------------------------------------------
67 /// CaptureElement
68 ///
69
70 CaptureElement::CaptureElement(const std::string& label)
71 : CaptureCursorListElement(label) {}
72
73 std::shared_ptr<CaptureElement> CaptureElement::Make(const std::string& label) {
74 return std::shared_ptr<CaptureElement>(new CaptureElement(label));
75 }
76
77 void CaptureElement::Rewind() {
78 properties.Rewind();
79 children.Rewind();
80 }
81
82 bool CaptureElement::MatchesCloselyEnough(const CaptureElement& other) const {
83 return label == other.label;
84 }
85
86 //-----------------------------------------------------------------------------
87 /// Capture
88 ///
89
90 Capture::Capture() = default;
91
92 #ifdef IMPELLER_ENABLE_CAPTURE
93 Capture::Capture(const std::string& label)
94 : element_(CaptureElement::Make(label)), active_(true) {
95 element_->label = label;
96 }
97 #else
98 Capture::Capture(const std::string& label) {}
99 #endif
100
101 Capture Capture::MakeInactive() {
102 return Capture();
103 }
104
105 std::shared_ptr<CaptureElement> Capture::GetElement() const {
106 #ifdef IMPELLER_ENABLE_CAPTURE
107 return element_;
108 #else
109 return nullptr;
110 #endif
111 }
112
113 void Capture::Rewind() {
114 return GetElement()->Rewind();
115 }
116
117 #ifdef IMPELLER_ENABLE_CAPTURE
118 #define _CAPTURE_PROPERTY_RECORDER_DEFINITION(type_name, pascal_name, \
119 lower_name) \
120 type_name Capture::Add##pascal_name(std::string_view label, type_name value, \
121 CaptureProperty::Options options) { \
122 if (!active_) { \
123 return value; \
124 } \
125 FML_DCHECK(element_ != nullptr); \
126 \
127 std::string label_clone = std::string(label); \
128 auto new_value = Capture##pascal_name##Property::Make( \
129 label_clone, std::move(value), options); \
130 \
131 auto next = std::reinterpret_pointer_cast<Capture##pascal_name##Property>( \
132 element_->properties.GetNext(std::move(new_value), options.readonly)); \
133 \
134 return next->value; \
135 }
136
137 _FOR_EACH_CAPTURE_PROPERTY(_CAPTURE_PROPERTY_RECORDER_DEFINITION);
138 #endif
139
140 //-----------------------------------------------------------------------------
141 /// CaptureContext
142 ///
143
144 #ifdef IMPELLER_ENABLE_CAPTURE
145 CaptureContext::CaptureContext() : active_(true) {}
146 CaptureContext::CaptureContext(std::initializer_list<std::string> allowlist)
147 : active_(true), allowlist_(allowlist) {}
148 #else
149 CaptureContext::CaptureContext() {}
150 CaptureContext::CaptureContext(std::initializer_list<std::string> allowlist) {}
151 #endif
152
153 CaptureContext::CaptureContext(CaptureContext::InactiveFlag) {}
154
155 CaptureContext CaptureContext::MakeInactive() {
156 return CaptureContext(InactiveFlag{});
157 }
158
159 CaptureContext CaptureContext::MakeAllowlist(
160 std::initializer_list<std::string> allowlist) {
161 return CaptureContext(allowlist);
162 }
163
164 bool CaptureContext::IsActive() const {
165 #ifdef IMPELLER_ENABLE_CAPTURE
166 return active_;
167 #else
168 return false;
169 #endif
170 }
171
172 void CaptureContext::Rewind() {
173 #ifdef IMPELLER_ENABLE_CAPTURE
174 for (auto& [name, capture] : documents_) {
175 capture.GetElement()->Rewind();
176 }
177 #else
178 return;
179 #endif
180 }
181
182 Capture CaptureContext::GetDocument(const std::string& label) {
183 #ifdef IMPELLER_ENABLE_CAPTURE
184 if (!active_) {
185 return Capture::MakeInactive();
186 }
187
188 if (allowlist_.has_value()) {
189 if (allowlist_->find(label) == allowlist_->end()) {
190 return Capture::MakeInactive();
191 }
192 }
193
194 auto found = documents_.find(label);
195 if (found != documents_.end()) {
196 // Always rewind when fetching an existing document.
197 found->second.Rewind();
198 return found->second;
199 }
200
201 auto new_document = Capture(label);
202 documents_.emplace(label, new_document);
203 return new_document;
204 #else
205 return Capture::MakeInactive();
206 #endif
207 }
208
209 bool CaptureContext::DoesDocumentExist(const std::string& label) const {
210 #ifdef IMPELLER_ENABLE_CAPTURE
211 if (!active_) {
212 return false;
213 }
214 return documents_.find(label) != documents_.end();
215 #else
216 return false;
217 #endif
218 }
219
220 } // namespace impeller
impeller::Capture
Definition: capture.h:231
capture.h
impeller::Capture::MakeInactive
static Capture MakeInactive()
Definition: capture.cc:101
_CAPTURE_PROPERTY_CAST_DEFINITION
#define _CAPTURE_PROPERTY_CAST_DEFINITION(type_name, pascal_name, lower_name)
Definition: capture.cc:31
_CAPTURE_PROPERTY_DEFINITION
#define _CAPTURE_PROPERTY_DEFINITION(type_name, pascal_name, lower_name)
Definition: capture.cc:42
impeller::Capture::GetElement
std::shared_ptr< CaptureElement > GetElement() const
Definition: capture.cc:105
impeller::CaptureContext::MakeAllowlist
static CaptureContext MakeAllowlist(std::initializer_list< std::string > allowlist)
Definition: capture.cc:159
impeller::CaptureCursorListElement< CaptureProperty >::label
std::string label
Definition: capture.h:43
impeller::CaptureContext
Definition: capture.h:269
impeller::CaptureContext::DoesDocumentExist
bool DoesDocumentExist(const std::string &label) const
Definition: capture.cc:209
impeller::CaptureContext::Rewind
void Rewind()
Definition: capture.cc:172
impeller::_FOR_EACH_CAPTURE_PROPERTY
_FOR_EACH_CAPTURE_PROPERTY(_CAPTURE_PROPERTY_CAST_DEFINITION)
impeller::CaptureContext::MakeInactive
static CaptureContext MakeInactive()
Definition: capture.cc:155
impeller::CaptureElement
Definition: capture.h:199
impeller::CaptureProperty::MatchesCloselyEnough
bool MatchesCloselyEnough(const CaptureProperty &other) const override
Determines if previously captured data matches closely enough with newly recorded data to safely emit...
Definition: capture.cc:21
impeller::Capture::Rewind
void Rewind()
Definition: capture.cc:113
impeller::CaptureProperty::CaptureProperty
CaptureProperty(const std::string &label, Options options)
Definition: capture.cc:16
impeller::CaptureProperty
A capturable property type.
Definition: capture.h:68
impeller::CaptureProperty::~CaptureProperty
virtual ~CaptureProperty()
impeller::CaptureContext::IsActive
bool IsActive() const
Definition: capture.cc:164
impeller::CaptureContext::CaptureContext
CaptureContext()
Definition: capture.cc:149
impeller::CaptureProperty::Options
Definition: capture.h:71
impeller::CaptureCursorListElement
Definition: capture.h:42
impeller::Capture::Capture
Capture()
impeller::CaptureContext::GetDocument
Capture GetDocument(const std::string &label)
Definition: capture.cc:182
impeller
Definition: aiks_context.cc:10
impeller::CaptureProperty::GetType
virtual Type GetType() const =0