5#ifndef FLUTTER_IMPELLER_CORE_CAPTURE_H_
6#define FLUTTER_IMPELLER_CORE_CAPTURE_H_
9#include <initializer_list>
13#include <unordered_map>
14#include <unordered_set>
17#include "flutter/fml/logging.h"
18#include "flutter/fml/macros.h"
28struct CaptureProcTable;
30#define _FOR_EACH_CAPTURE_PROPERTY(PROPERTY_V) \
31 PROPERTY_V(bool, Boolean, boolean) \
32 PROPERTY_V(int, Integer, integer) \
33 PROPERTY_V(Scalar, Scalar, scalar) \
34 PROPERTY_V(Point, Point, point) \
35 PROPERTY_V(Vector3, Vector3, vector3) \
36 PROPERTY_V(Rect, Rect, rect) \
37 PROPERTY_V(Color, Color, color) \
38 PROPERTY_V(Matrix, Matrix, matrix) \
39 PROPERTY_V(std::string, String, string)
41template <
typename Type>
62#define _CAPTURE_TYPE(type_name, pascal_name, lower_name) k##pascal_name,
64#define _CAPTURE_PROPERTY_CAST_DECLARATION(type_name, pascal_name, lower_name) \
65 std::optional<type_name> As##pascal_name() const;
102#define _CAPTURE_PROPERTY_DECLARATION(type_name, pascal_name, lower_name) \
103 struct Capture##pascal_name##Property final : public CaptureProperty { \
106 static std::shared_ptr<Capture##pascal_name##Property> \
107 Make(const std::string& label, type_name value, Options options); \
110 Type GetType() const override; \
113 void Invoke(const CaptureProcTable& proc_table) override; \
116 Capture##pascal_name##Property(const std::string& label, \
120 FML_DISALLOW_COPY_AND_ASSIGN(Capture##pascal_name##Property); \
125#define _CAPTURE_PROC(type_name, pascal_name, lower_name) \
126 std::function<void(Capture##pascal_name##Property&)> lower_name = \
127 [](Capture##pascal_name##Property& value) {};
133template <
typename Type>
143 static_assert(std::is_base_of_v<CaptureCursorListElement<Type>,
Type>);
148 size_t Count() {
return values_.size(); }
150 std::shared_ptr<Type>
GetNext(std::shared_ptr<Type> captured,
151 bool force_overwrite) {
152 if (cursor_ < values_.size()) {
153 std::shared_ptr<Type>&
result = values_[cursor_];
155 if (
result->MatchesCloselyEnough(*captured)) {
156 if (force_overwrite) {
157 values_[cursor_] = captured;
165 values_.resize(cursor_);
169 values_.push_back(captured);
174 for (std::shared_ptr<Type>&
value : values_) {
175 if (
value->label == label) {
183 for (
auto&
value : values_) {
190 std::vector<std::shared_ptr<Type>> values_;
203 static std::shared_ptr<CaptureElement>
Make(
const std::string&
label);
217#ifdef IMPELLER_ENABLE_CAPTURE
218#define _CAPTURE_PROPERTY_RECORDER_DECLARATION(type_name, pascal_name, \
220 type_name Add##pascal_name(std::string_view label, type_name value, \
221 CaptureProperty::Options options = {});
223#define _CAPTURE_PROPERTY_RECORDER_DECLARATION(type_name, pascal_name, \
225 inline type_name Add##pascal_name(std::string_view label, type_name value, \
226 CaptureProperty::Options options = {}) { \
233 explicit Capture(
const std::string& label);
240#ifdef IMPELLER_ENABLE_CAPTURE
245 std::string label_copy = std::string(label);
246 auto new_capture =
Capture(label_copy);
247 new_capture.element_ =
248 element_->children.GetNext(new_capture.element_,
false);
249 new_capture.element_->Rewind();
256 std::shared_ptr<CaptureElement>
GetElement()
const;
263#ifdef IMPELLER_ENABLE_CAPTURE
264 std::shared_ptr<CaptureElement> element_;
265 bool active_ =
false;
276 std::initializer_list<std::string> allowlist);
287 struct InactiveFlag {};
291#ifdef IMPELLER_ENABLE_CAPTURE
292 bool active_ =
false;
293 std::optional<std::unordered_set<std::string>> allowlist_;
294 std::unordered_map<std::string, Capture> documents_;
#define _FOR_EACH_CAPTURE_PROPERTY(PROPERTY_V)
#define _CAPTURE_PROPERTY_CAST_DECLARATION(type_name, pascal_name, lower_name)
#define _CAPTURE_PROC(type_name, pascal_name, lower_name)
#define _CAPTURE_PROPERTY_RECORDER_DECLARATION(type_name, pascal_name, lower_name)
#define _CAPTURE_TYPE(type_name, pascal_name, lower_name)
#define _CAPTURE_PROPERTY_DECLARATION(type_name, pascal_name, lower_name)
bool DoesDocumentExist(const std::string &label) const
static CaptureContext MakeInactive()
Capture GetDocument(const std::string &label)
static CaptureContext MakeAllowlist(std::initializer_list< std::string > allowlist)
CapturePlaybackList()=default
std::shared_ptr< Type > FindFirstByLabel(const std::string &label)
void Iterate(std::function< void(Type &)> iterator) const
std::shared_ptr< Type > GetNext(std::shared_ptr< Type > captured, bool force_overwrite)
Capture CreateChild(std::string_view label)
std::shared_ptr< CaptureElement > GetElement() const
static Capture MakeInactive()
virtual ~CaptureCursorListElement()=default
CaptureCursorListElement(const std::string &label)
virtual bool MatchesCloselyEnough(const Type &other) const =0
Determines if previously captured data matches closely enough with newly recorded data to safely emit...
bool MatchesCloselyEnough(const CaptureElement &other) const override
Determines if previously captured data matches closely enough with newly recorded data to safely emit...
CapturePlaybackList< CaptureElement > children
CapturePlaybackList< CaptureProperty > properties
static std::shared_ptr< CaptureElement > Make(const std::string &label)
std::optional< Range > range
A capturable property type.
virtual Type GetType() const =0
virtual void Invoke(const CaptureProcTable &proc_table)=0
virtual ~CaptureProperty()
@ _FOR_EACH_CAPTURE_PROPERTY
bool MatchesCloselyEnough(const CaptureProperty &other) const override
Determines if previously captured data matches closely enough with newly recorded data to safely emit...