123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102 |
- // Copyright 2018 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #ifndef SERVICES_AUDIO_GROUP_COORDINATOR_H_
- #define SERVICES_AUDIO_GROUP_COORDINATOR_H_
- #include <algorithm>
- #include <utility>
- #include <vector>
- #include "base/callback.h"
- #include "base/check.h"
- #include "base/sequence_checker.h"
- #include "base/unguessable_token.h"
- namespace audio {
- // Manages a registry of group members and notifies observers as membership in
- // the group changes.
- template <typename Member>
- class GroupCoordinator {
- public:
- // Interface for entities that wish to montior and take action as members
- // join/leave a particular group.
- class Observer {
- public:
- virtual void OnMemberJoinedGroup(Member* member) = 0;
- virtual void OnMemberLeftGroup(Member* member) = 0;
- protected:
- virtual ~Observer();
- };
- GroupCoordinator();
- GroupCoordinator(const GroupCoordinator&) = delete;
- GroupCoordinator& operator=(const GroupCoordinator&) = delete;
- ~GroupCoordinator();
- // Registers/Unregisters a group |member|. The member must remain valid until
- // after UnregisterMember() is called.
- void RegisterMember(const base::UnguessableToken& group_id, Member* member);
- void UnregisterMember(const base::UnguessableToken& group_id, Member* member);
- void AddObserver(const base::UnguessableToken& group_id, Observer* observer);
- void RemoveObserver(const base::UnguessableToken& group_id,
- Observer* observer);
- // Runs a |callback| for each member associated with the given |group_id|.
- void ForEachMemberInGroup(
- const base::UnguessableToken& group_id,
- base::RepeatingCallback<void(Member*)> callback) const;
- protected:
- // Returns the current members in the group having the given |group_id|. Note
- // that the validity of the returned reference is uncertain once any of the
- // other non-const methods are called.
- const std::vector<Member*>& GetCurrentMembersUnsafe(
- const base::UnguessableToken& group_id) const;
- private:
- struct Group {
- std::vector<Member*> members;
- std::vector<Observer*> observers;
- Group();
- Group(const Group&) = delete;
- Group& operator=(const Group&) = delete;
- Group(Group&& other);
- Group& operator=(Group&& other);
- ~Group();
- };
- using GroupMap = std::vector<std::pair<base::UnguessableToken, Group>>;
- // Returns an iterator to the entry associated with the given |group_id|,
- // creating a new one if necessary.
- typename GroupMap::iterator FindGroup(const base::UnguessableToken& group_id);
- // Deletes the entry in |groups_| if it has no members or observers remaining.
- void MaybePruneGroupMapEntry(typename GroupMap::iterator it);
- GroupMap groups_;
- #if DCHECK_IS_ON()
- // Incremented with each mutation, and used to sanity-check that there aren't
- // any possible re-entrancy bugs. It's okay if this rolls over, since the
- // implementation is only doing DCHECK_EQ's.
- size_t mutation_count_ = 0;
- #endif
- SEQUENCE_CHECKER(sequence_checker_);
- };
- } // namespace audio
- #endif // SERVICES_AUDIO_GROUP_COORDINATOR_H_
|