metadata_types.h 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. // Copyright 2019 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. #ifndef UI_BASE_METADATA_METADATA_TYPES_H_
  5. #define UI_BASE_METADATA_METADATA_TYPES_H_
  6. #include <map>
  7. #include <memory>
  8. #include <string>
  9. #include <vector>
  10. #include "base/callback.h"
  11. #include "base/callback_list.h"
  12. #include "base/component_export.h"
  13. #include "base/memory/raw_ptr.h"
  14. namespace ui {
  15. namespace metadata {
  16. enum class PropertyFlags : uint32_t {
  17. // By default, properties are read/write. This flag indicates that the given
  18. // property metadata instance needs no special attention.
  19. kEmpty = 0x00,
  20. // Property metadata instance should be treated as read-only. SetValueAsString
  21. // should not be called since there may not be a conversion from a string for
  22. // the type of the property. (see kIsSerializable below for additional info).
  23. // Calling SetValueAsString() may trigger a NOTREACHED() error under debug.
  24. kReadOnly = 0x01,
  25. // Property metadata can be serialized to or from a string. Needs to make sure
  26. // this flag is set to have meaningful SetValueAsString() and
  27. // GetValueFromString(). This is ultimately a signal indicating the underlying
  28. // TypeConverter is able to convert the value to/from a string.
  29. kSerializable = 0x100,
  30. };
  31. COMPONENT_EXPORT(UI_BASE_METADATA)
  32. extern PropertyFlags operator|(PropertyFlags op1, PropertyFlags op2);
  33. COMPONENT_EXPORT(UI_BASE_METADATA)
  34. extern PropertyFlags operator&(PropertyFlags op1, PropertyFlags op2);
  35. COMPONENT_EXPORT(UI_BASE_METADATA)
  36. extern PropertyFlags operator^(PropertyFlags op1, PropertyFlags op2);
  37. COMPONENT_EXPORT(UI_BASE_METADATA) extern bool operator!(PropertyFlags op);
  38. // Used to identify the CallbackList<> within the PropertyChangedVectors map.
  39. using PropertyKey = const void*;
  40. using PropertyChangedCallbacks = base::RepeatingClosureList;
  41. using PropertyChangedCallback = PropertyChangedCallbacks::CallbackType;
  42. // Interface for classes that provide ClassMetaData (via macros in
  43. // metadata_header_macros.h). GetClassMetaData() is automatically overridden and
  44. // implemented in the relevant macros, so a class must merely have
  45. // MetaDataProvider somewhere in its ancestry.
  46. class COMPONENT_EXPORT(UI_BASE_METADATA) MetaDataProvider {
  47. public:
  48. MetaDataProvider();
  49. virtual ~MetaDataProvider();
  50. virtual class ClassMetaData* GetClassMetaData() = 0;
  51. protected:
  52. [[nodiscard]] base::CallbackListSubscription AddPropertyChangedCallback(
  53. PropertyKey property,
  54. PropertyChangedCallback callback);
  55. void TriggerChangedCallback(PropertyKey property);
  56. private:
  57. using PropertyChangedVectors =
  58. std::map<PropertyKey, std::unique_ptr<PropertyChangedCallbacks>>;
  59. // Property Changed Callbacks ------------------------------------------------
  60. PropertyChangedVectors property_changed_vectors_;
  61. };
  62. class MemberMetaDataBase;
  63. // Represents the 'meta data' that describes a class. Using the appropriate
  64. // macros in ui/base/metadata/metadata_impl_macros.h, a descendant of this
  65. // class is declared within the scope of the containing class. See information
  66. // about using the macros in the comment for the views::View class.
  67. class COMPONENT_EXPORT(UI_BASE_METADATA) ClassMetaData {
  68. public:
  69. ClassMetaData();
  70. ClassMetaData(std::string file, int line);
  71. ClassMetaData(const ClassMetaData&) = delete;
  72. ClassMetaData& operator=(const ClassMetaData&) = delete;
  73. virtual ~ClassMetaData();
  74. const std::string& type_name() const { return type_name_; }
  75. const std::vector<MemberMetaDataBase*>& members() const { return members_; }
  76. const std::string& file() const { return file_; }
  77. const int& line() const { return line_; }
  78. void AddMemberData(std::unique_ptr<MemberMetaDataBase> member_data);
  79. // Lookup the member data entry for a member of this class with a given name.
  80. // Returns the appropriate MemberMetaDataBase* if it exists, nullptr
  81. // otherwise.
  82. MemberMetaDataBase* FindMemberData(const std::string& member_name);
  83. ClassMetaData* parent_class_meta_data() const {
  84. return parent_class_meta_data_;
  85. }
  86. void SetParentClassMetaData(ClassMetaData* parent_meta_data) {
  87. parent_class_meta_data_ = parent_meta_data;
  88. }
  89. // Custom iterator to iterate through all member data entries associated with
  90. // a class (including members declared in parent classes).
  91. // Example:
  92. // for(views::MemberMetaDataBase* member : class_meta_data) {
  93. // OperateOn(member);
  94. // }
  95. class COMPONENT_EXPORT(UI_BASE_METADATA) ClassMemberIterator {
  96. public:
  97. using iterator_category = std::forward_iterator_tag;
  98. using value_type = MemberMetaDataBase*;
  99. using difference_type = std::ptrdiff_t;
  100. using pointer = MemberMetaDataBase**;
  101. using reference = MemberMetaDataBase*&;
  102. ClassMemberIterator(const ClassMemberIterator& other);
  103. ~ClassMemberIterator();
  104. ClassMemberIterator& operator++();
  105. ClassMemberIterator operator++(int);
  106. bool operator==(const ClassMemberIterator& rhs) const;
  107. bool operator!=(const ClassMemberIterator& rhs) const {
  108. return !(*this == rhs);
  109. }
  110. MemberMetaDataBase* operator*() {
  111. if (current_collection_ == nullptr ||
  112. current_vector_index_ >= current_collection_->members().size())
  113. return nullptr;
  114. return current_collection_->members()[current_vector_index_];
  115. }
  116. // Returns true if iterator currently on last member for that current
  117. // collection.
  118. bool IsLastMember() const;
  119. std::string GetCurrentCollectionName() const;
  120. private:
  121. friend class ClassMetaData;
  122. explicit ClassMemberIterator(ClassMetaData* starting_container);
  123. void IncrementHelper();
  124. raw_ptr<ClassMetaData> current_collection_;
  125. size_t current_vector_index_;
  126. };
  127. ClassMemberIterator begin();
  128. ClassMemberIterator end();
  129. protected:
  130. void SetTypeName(const std::string& type_name);
  131. private:
  132. std::string type_name_;
  133. std::vector<MemberMetaDataBase*> members_;
  134. raw_ptr<ClassMetaData> parent_class_meta_data_ = nullptr;
  135. std::string file_;
  136. const int line_ = 0;
  137. };
  138. // Abstract base class to represent meta data about class members.
  139. // Provides basic information (such as the name of the member), and templated
  140. // accessors to get/set the value of the member on an object.
  141. class COMPONENT_EXPORT(UI_BASE_METADATA) MemberMetaDataBase {
  142. public:
  143. using ValueStrings = std::vector<std::u16string>;
  144. MemberMetaDataBase(const std::string& member_name,
  145. const std::string& member_type)
  146. : member_name_(member_name), member_type_(member_type) {}
  147. MemberMetaDataBase(const MemberMetaDataBase&) = delete;
  148. MemberMetaDataBase& operator=(const MemberMetaDataBase&) = delete;
  149. virtual ~MemberMetaDataBase() = default;
  150. // Access the value of this member and return it as a string.
  151. // |obj| is the instance on which to obtain the value of the property this
  152. // metadata represents.
  153. virtual std::u16string GetValueAsString(void* obj) const = 0;
  154. // Set the value of this member through a string on a specified object.
  155. // |obj| is the instance on which to set the value of the property this
  156. // metadata represents.
  157. virtual void SetValueAsString(void* obj, const std::u16string& new_value);
  158. // Return various information flags about the property.
  159. virtual PropertyFlags GetPropertyFlags() const = 0;
  160. // Return a list of valid property values as a vector of strings. An empty
  161. // vector indicates that the natural limits of the underlying type applies.
  162. virtual ValueStrings GetValidValues() const;
  163. // Return an optional prefix string used by the ui-devtools frontend to
  164. // prepend to the member name which causes a special value editor to become
  165. // available. For instance, an SkColor member type would add the "--" string
  166. // which tells the frontend to display a color swatch and a color editing
  167. // dialog.
  168. virtual const char* GetMemberNamePrefix() const;
  169. const std::string& member_name() const { return member_name_; }
  170. const std::string& member_type() const { return member_type_; }
  171. private:
  172. std::string member_name_;
  173. std::string member_type_;
  174. }; // class MemberMetaDataBase
  175. } // namespace metadata
  176. } // namespace ui
  177. #endif // UI_BASE_METADATA_METADATA_TYPES_H_