Index: services/resource_coordinator/coordination_unit/coordination_unit_impl.h |
diff --git a/services/resource_coordinator/coordination_unit/coordination_unit_impl.h b/services/resource_coordinator/coordination_unit/coordination_unit_impl.h |
index 94ebb044e624c8a0b0f6217f2b7e71e05ed5a62d..18a40a007a02bdd7f9c3c90b2ef2bbf68f6acac0 100644 |
--- a/services/resource_coordinator/coordination_unit/coordination_unit_impl.h |
+++ b/services/resource_coordinator/coordination_unit/coordination_unit_impl.h |
@@ -6,24 +6,100 @@ |
#define SERVICES_RESOURCE_COORDINATOR_COORDINATION_UNIT_COORDINATION_UNIT_IMPL_H_ |
#include <list> |
+#include <map> |
#include <memory> |
#include <set> |
#include <unordered_map> |
#include <utility> |
+#include <vector> |
+#include "base/callback.h" |
#include "base/optional.h" |
#include "base/values.h" |
#include "mojo/public/cpp/bindings/binding_set.h" |
#include "mojo/public/cpp/bindings/interface_request.h" |
#include "mojo/public/cpp/bindings/strong_binding.h" |
#include "services/resource_coordinator/public/cpp/coordination_unit_id.h" |
+#include "services/resource_coordinator/public/cpp/coordination_unit_types.h" |
#include "services/resource_coordinator/public/interfaces/coordination_unit.mojom.h" |
#include "services/resource_coordinator/public/interfaces/coordination_unit_provider.mojom.h" |
#include "services/service_manager/public/cpp/service_context_ref.h" |
namespace resource_coordinator { |
+// Collection to manage CoordinationUnitEvent listeners. |
+template <typename Listener, typename Filter> |
+class CoordinationUnitEventListenerRegistry { |
+ public: |
+ CoordinationUnitEventListenerRegistry() = default; |
+ ~CoordinationUnitEventListenerRegistry() = default; |
+ |
+ // callbacks paired with this kNoFilter will always be invoked |
+ static const Filter kNoFilter = static_cast<Filter>(0); |
+ |
+ void AddListener(Listener listener, Filter filter) { |
+ registry_[filter].push_back(listener); |
+ } |
+ |
+ void AddListener(Listener listener) { AddListener(listener, kNoFilter); } |
+ |
+ // Get the listeners who are are either registered to be invoked for a |
+ // specific filter or were registered with the kNoFilter. |
+ // TODO(matthalp) add iterator support to replace this call and |
+ // avoid excessive copying that currently occurs |
+ std::vector<Listener> GetListeners(Filter filter) { |
+ std::vector<Listener> listeners; |
+ |
+ // Get listeners registered with a listener first. |
+ AppendListeners(&listeners, filter); |
+ |
+ // Get listeners registered without a filter after. |
+ if (filter != kNoFilter) { |
+ AppendListeners(&listeners, kNoFilter); |
+ } |
+ |
+ return listeners; |
+ } |
+ |
+ std::vector<Listener> GetListenersWithoutAFilter() { |
+ return GetListeners(kNoFilter); |
+ } |
+ |
+ private: |
+ // TODO(matthalp) Consider using a std::unordered_map instead. |
+ std::map<Filter, std::vector<Listener>> registry_; |
+ |
+ void AppendListeners(std::vector<Listener>* listeners, Filter filter) { |
+ listeners->insert(listeners->end(), registry_[filter].begin(), |
+ registry_[filter].end()); |
+ } |
+ |
+ DISALLOW_COPY_AND_ASSIGN(CoordinationUnitEventListenerRegistry); |
+}; |
+ |
class CoordinationUnitImpl : public mojom::CoordinationUnit { |
+ typedef base::Callback<void( |
+ const CoordinationUnitImpl* coordination_unit, |
+ const CoordinationUnitImpl* child_coordination_unit)> |
+ OnAddChildEventListener; |
+ typedef base::Callback<void( |
+ const CoordinationUnitImpl* coordination_unit, |
+ const CoordinationUnitImpl* parent_coordination_unit)> |
+ OnAddParentEventListener; |
+ typedef base::Callback<void( |
+ const CoordinationUnitImpl* coordination_unit, |
+ const CoordinationUnitImpl* removed_child_coordination_unit)> |
+ OnRemoveChildEventListener; |
+ typedef base::Callback<void( |
+ const CoordinationUnitImpl* coordination_unit, |
+ const CoordinationUnitImpl* removed_parent_coordination_unit)> |
+ OnRemoveParentEventListener; |
+ typedef base::Callback<void(const CoordinationUnitImpl* coordination_unit, |
+ mojom::PropertyType property)> |
+ OnPropertyChangedEventListener; |
+ typedef base::Callback<void(const CoordinationUnitImpl* coordination_unit)> |
+ OnWillBeDestroyedEventListener; |
+ |
public: |
CoordinationUnitImpl( |
const CoordinationUnitID& id, |
@@ -55,10 +131,45 @@ class CoordinationUnitImpl : public mojom::CoordinationUnit { |
// Clear property from internal key-value store |
void ClearProperty(mojom::PropertyType property); |
// Retrieve property from internal key-value store |
- base::Value GetProperty(mojom::PropertyType property); |
+ base::Value GetProperty(mojom::PropertyType property) const; |
// Set property from internal key-value store |
void SetProperty(mojom::PropertyType property, base::Value value); |
+ // Notify an instance it will be destroyed before its destructor is |
+ // actually called. |
+ void WillBeDestroyed(); |
+ |
+ CoordinationUnitEventListenerRegistry<OnAddChildEventListener, |
+ CoordinationUnitType>& |
+ on_add_child_event_listeners() { |
+ return on_add_child_event_listeners_; |
+ } |
+ CoordinationUnitEventListenerRegistry<OnAddParentEventListener, |
+ CoordinationUnitType>& |
+ on_add_parent_event_listeners() { |
+ return on_add_parent_event_listeners_; |
+ } |
+ CoordinationUnitEventListenerRegistry<OnRemoveChildEventListener, |
+ CoordinationUnitType>& |
+ on_remove_child_event_listeners() { |
+ return on_remove_child_event_listeners_; |
+ } |
+ CoordinationUnitEventListenerRegistry<OnRemoveParentEventListener, |
+ CoordinationUnitType>& |
+ on_remove_parent_event_listeners() { |
+ return on_remove_parent_event_listeners_; |
+ } |
+ CoordinationUnitEventListenerRegistry<OnPropertyChangedEventListener, |
+ mojom::PropertyType>& |
+ on_property_changed_event_listeners() { |
+ return on_property_changed_event_listeners_; |
+ } |
+ CoordinationUnitEventListenerRegistry<OnWillBeDestroyedEventListener, |
+ CoordinationUnitType>& |
+ on_will_be_destroyed_event_listeners() { |
+ return on_will_be_destroyed_event_listeners_; |
+ } |
+ |
protected: |
const CoordinationUnitID id_; |
std::set<CoordinationUnitImpl*> children_; |
@@ -94,6 +205,27 @@ class CoordinationUnitImpl : public mojom::CoordinationUnit { |
base::Optional<bool> state_flags_[kNumStateFlags]; |
+ CoordinationUnitEventListenerRegistry<OnAddChildEventListener, |
+ CoordinationUnitType> |
+ on_add_child_event_listeners_; |
+ CoordinationUnitEventListenerRegistry<OnAddParentEventListener, |
+ CoordinationUnitType> |
+ on_add_parent_event_listeners_; |
+ CoordinationUnitEventListenerRegistry<OnRemoveChildEventListener, |
+ CoordinationUnitType> |
+ on_remove_child_event_listeners_; |
+ CoordinationUnitEventListenerRegistry<OnRemoveParentEventListener, |
+ CoordinationUnitType> |
+ on_remove_parent_event_listeners_; |
+ CoordinationUnitEventListenerRegistry<OnPropertyChangedEventListener, |
+ mojom::PropertyType> |
+ on_property_changed_event_listeners_; |
+ // There is nothing to filter WillBeDestroyedEventCallbacks on so the |
+ // CoordinationUnitType is used as a filter placeholder |
+ CoordinationUnitEventListenerRegistry<OnWillBeDestroyedEventListener, |
+ CoordinationUnitType> |
+ on_will_be_destroyed_event_listeners_; |
+ |
DISALLOW_COPY_AND_ASSIGN(CoordinationUnitImpl); |
}; |