node_attached_data.h 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  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 COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_GRAPH_NODE_ATTACHED_DATA_H_
  5. #define COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_GRAPH_NODE_ATTACHED_DATA_H_
  6. #include <memory>
  7. #include "base/check_op.h"
  8. namespace performance_manager {
  9. class Node;
  10. // NodeAttachedData allows external observers of the graph to store data that is
  11. // associated with a graph node, providing lifetime management as a service.
  12. //
  13. // External (to performance_manager) implementations of NodeAttachedData should
  14. // derive from ExternalNodeAttachedDataImpl. For internal implementations refer
  15. // to NodeAttachedDataImpl and see node_attached_data_impl.h.
  16. class NodeAttachedData {
  17. public:
  18. NodeAttachedData();
  19. NodeAttachedData(const NodeAttachedData&) = delete;
  20. NodeAttachedData& operator=(const NodeAttachedData&) = delete;
  21. virtual ~NodeAttachedData();
  22. // Returns the 'key' associated with this type of NodeAttachedData. This needs
  23. // to be unique per data type or bad things happen.
  24. virtual const void* GetKey() const = 0;
  25. };
  26. // Implements NodeAttachedData for a given UserDataType.
  27. //
  28. // In order for a UserDataType to be attached to a node of type |NodeType| it
  29. // must have a constructor of the form "UserDataType(const NodeType* node)".
  30. template <typename UserDataType>
  31. class ExternalNodeAttachedDataImpl : public NodeAttachedData {
  32. public:
  33. ExternalNodeAttachedDataImpl() = default;
  34. ExternalNodeAttachedDataImpl(const ExternalNodeAttachedDataImpl&) = delete;
  35. ExternalNodeAttachedDataImpl& operator=(const ExternalNodeAttachedDataImpl&) =
  36. delete;
  37. ~ExternalNodeAttachedDataImpl() override = default;
  38. // NodeAttachedData implementation:
  39. const void* GetKey() const override { return &kUserDataKey; }
  40. // Gets the user data for the given |node|, creating it if it doesn't yet
  41. // exist.
  42. template <typename NodeType>
  43. static UserDataType* GetOrCreate(const NodeType* node);
  44. // Gets the user data for the given |node|, returning nullptr if it doesn't
  45. // exist.
  46. template <typename NodeType>
  47. static UserDataType* Get(const NodeType* node);
  48. // Destroys the user data associated with the given node, returning true
  49. // on success or false if the user data did not exist to begin with.
  50. template <typename NodeType>
  51. static bool Destroy(const NodeType* node);
  52. private:
  53. static const int kUserDataKey = 0;
  54. static const void* UserDataKey() { return &kUserDataKey; }
  55. };
  56. // Everything below this point is pure implementation detail.
  57. // Provides access for setting/getting data in the map based storage. Not
  58. // intended to be used directly, but rather by (External)NodeAttachedDataImpl.
  59. class NodeAttachedDataMapHelper {
  60. public:
  61. // Attaches the provided |data| to the provided |node|. This should only be
  62. // called if the data does not exist (GetFromMap returns nullptr), and will
  63. // DCHECK otherwise.
  64. static void AttachInMap(const Node* node,
  65. std::unique_ptr<NodeAttachedData> data);
  66. // Retrieves the data associated with the provided |node| and |key|. This
  67. // returns nullptr if no data exists.
  68. static NodeAttachedData* GetFromMap(const Node* node, const void* key);
  69. // Detaches the data associated with the provided |node| and |key|. It is
  70. // harmless to call this when no data exists.
  71. static std::unique_ptr<NodeAttachedData> DetachFromMap(const Node* node,
  72. const void* key);
  73. };
  74. // Implementation of ExternalNodeAttachedDataImpl, which is declared in the
  75. // corresponding public header. This helps keep the public headers as clean as
  76. // possible.
  77. // static
  78. template <typename UserDataType>
  79. constexpr int ExternalNodeAttachedDataImpl<UserDataType>::kUserDataKey;
  80. template <typename UserDataType>
  81. template <typename NodeType>
  82. UserDataType* ExternalNodeAttachedDataImpl<UserDataType>::GetOrCreate(
  83. const NodeType* node) {
  84. if (auto* data = Get(node))
  85. return data;
  86. std::unique_ptr<UserDataType> data = std::make_unique<UserDataType>(node);
  87. auto* raw_data = data.get();
  88. auto* base = static_cast<const Node*>(node);
  89. NodeAttachedDataMapHelper::AttachInMap(base, std::move(data));
  90. return raw_data;
  91. }
  92. template <typename UserDataType>
  93. template <typename NodeType>
  94. UserDataType* ExternalNodeAttachedDataImpl<UserDataType>::Get(
  95. const NodeType* node) {
  96. auto* base = static_cast<const Node*>(node);
  97. auto* data = NodeAttachedDataMapHelper::GetFromMap(base, UserDataKey());
  98. if (!data)
  99. return nullptr;
  100. DCHECK_EQ(UserDataKey(), data->GetKey());
  101. return static_cast<UserDataType*>(data);
  102. }
  103. template <typename UserDataType>
  104. template <typename NodeType>
  105. bool ExternalNodeAttachedDataImpl<UserDataType>::Destroy(const NodeType* node) {
  106. auto* base = static_cast<const Node*>(node);
  107. std::unique_ptr<NodeAttachedData> data =
  108. NodeAttachedDataMapHelper::DetachFromMap(base, UserDataKey());
  109. return data.get();
  110. }
  111. } // namespace performance_manager
  112. #endif // COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_GRAPH_NODE_ATTACHED_DATA_H_