123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197 |
- // Copyright 2022 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.
- #include "ash/system/progress_indicator/progress_indicator_animation_registry.h"
- #include <set>
- namespace ash {
- namespace {
- // Type aliases ----------------------------------------------------------------
- template <typename AnimationType>
- using KeyedAnimationMap = std::map<const void*, std::unique_ptr<AnimationType>>;
- template <typename CallbackListType>
- using KeyedAnimationChangedCallbackListMap =
- std::map<const void*, CallbackListType>;
- // Helpers ---------------------------------------------------------------------
- // Notifies any animation changed callbacks registered for the specified `key`
- // that the associated animation has changed.
- template <typename AnimationType, typename CallbackListType>
- void NotifyAnimationChangedForKey(
- KeyedAnimationMap<AnimationType>* animations_by_key,
- KeyedAnimationChangedCallbackListMap<CallbackListType>*
- animation_changed_callback_lists_by_key,
- const void* key) {
- auto callback_lists_it = animation_changed_callback_lists_by_key->find(key);
- if (callback_lists_it == animation_changed_callback_lists_by_key->end())
- return;
- auto animations_it = animations_by_key->find(key);
- callback_lists_it->second.Notify(animations_it != animations_by_key->end()
- ? animations_it->second.get()
- : nullptr);
- }
- // Implements:
- // * `AddProgressIconAnimationChangedCallbackForKey()`
- // * `AddProgressRingAnimationChangedCallbackForKey()`
- template <typename CallbackListType>
- base::CallbackListSubscription AddAnimationChangedCallbackForKey(
- KeyedAnimationChangedCallbackListMap<CallbackListType>*
- animation_changed_callback_lists_by_key,
- const void* key,
- typename CallbackListType::CallbackType callback) {
- auto it = animation_changed_callback_lists_by_key->find(key);
- // If this is the first time that an animation changed callback is being
- // registered for the specified `key`, set a callback to destroy the created
- // callback list when it becomes empty.
- if (it == animation_changed_callback_lists_by_key->end()) {
- it = animation_changed_callback_lists_by_key
- ->emplace(std::piecewise_construct, std::forward_as_tuple(key),
- std::forward_as_tuple())
- .first;
- it->second.set_removal_callback(base::BindRepeating(
- [](KeyedAnimationChangedCallbackListMap<CallbackListType>*
- animation_changed_callback_lists_by_key,
- const void* key) {
- auto it = animation_changed_callback_lists_by_key->find(key);
- if (it != animation_changed_callback_lists_by_key->end() &&
- it->second.empty()) {
- animation_changed_callback_lists_by_key->erase(it);
- }
- },
- base::Unretained(animation_changed_callback_lists_by_key),
- base::Unretained(key)));
- }
- return it->second.Add(std::move(callback));
- }
- // Implements:
- // * `GetProgressIconAnimationForKey()`
- // * `GetProgressRingAnimationForKey()`
- template <typename AnimationType>
- AnimationType* GetAnimationForKey(
- KeyedAnimationMap<AnimationType>* animations_by_key,
- const void* key) {
- auto it = animations_by_key->find(key);
- return it != animations_by_key->end() ? it->second.get() : nullptr;
- }
- // Implements:
- // * `SetProgressIconAnimationForKey()`
- // * `SetProgressRingAnimationForKey()`
- template <typename AnimationType, typename CallbackListType>
- AnimationType* SetAnimationForKey(
- KeyedAnimationMap<AnimationType>* animations_by_key,
- KeyedAnimationChangedCallbackListMap<CallbackListType>*
- animation_changed_callback_lists_by_key,
- const void* key,
- std::unique_ptr<AnimationType> animation) {
- AnimationType* animation_ptr = animation.get();
- if (animation) {
- (*animations_by_key)[key] = std::move(animation);
- NotifyAnimationChangedForKey(animations_by_key,
- animation_changed_callback_lists_by_key, key);
- } else {
- auto it = animations_by_key->find(key);
- if (it != animations_by_key->end()) {
- animations_by_key->erase(it);
- NotifyAnimationChangedForKey(
- animations_by_key, animation_changed_callback_lists_by_key, key);
- }
- }
- return animation_ptr;
- }
- } // namespace
- // ProgressIndicatorAnimationRegistry ------------------------------------------
- ProgressIndicatorAnimationRegistry::ProgressIndicatorAnimationRegistry() =
- default;
- ProgressIndicatorAnimationRegistry::~ProgressIndicatorAnimationRegistry() =
- default;
- base::CallbackListSubscription ProgressIndicatorAnimationRegistry::
- AddProgressIconAnimationChangedCallbackForKey(
- const void* key,
- ProgressIconAnimationChangedCallbackList::CallbackType callback) {
- return AddAnimationChangedCallbackForKey(
- &icon_animation_changed_callback_lists_by_key_, key, std::move(callback));
- }
- base::CallbackListSubscription ProgressIndicatorAnimationRegistry::
- AddProgressRingAnimationChangedCallbackForKey(
- const void* key,
- ProgressRingAnimationChangedCallbackList::CallbackType callback) {
- return AddAnimationChangedCallbackForKey(
- &ring_animation_changed_callback_lists_by_key_, key, std::move(callback));
- }
- ProgressIconAnimation*
- ProgressIndicatorAnimationRegistry::GetProgressIconAnimationForKey(
- const void* key) {
- return GetAnimationForKey(&icon_animations_by_key_, key);
- }
- ProgressRingAnimation*
- ProgressIndicatorAnimationRegistry::GetProgressRingAnimationForKey(
- const void* key) {
- return GetAnimationForKey(&ring_animations_by_key_, key);
- }
- ProgressIconAnimation*
- ProgressIndicatorAnimationRegistry::SetProgressIconAnimationForKey(
- const void* key,
- std::unique_ptr<ProgressIconAnimation> animation) {
- return SetAnimationForKey(&icon_animations_by_key_,
- &icon_animation_changed_callback_lists_by_key_, key,
- std::move(animation));
- }
- ProgressRingAnimation*
- ProgressIndicatorAnimationRegistry::SetProgressRingAnimationForKey(
- const void* key,
- std::unique_ptr<ProgressRingAnimation> animation) {
- return SetAnimationForKey(&ring_animations_by_key_,
- &ring_animation_changed_callback_lists_by_key_, key,
- std::move(animation));
- }
- void ProgressIndicatorAnimationRegistry::EraseAllAnimations() {
- EraseAllAnimationsForKeyIf(
- base::BindRepeating([](const void* key) { return true; }));
- }
- void ProgressIndicatorAnimationRegistry::EraseAllAnimationsForKey(
- const void* key) {
- SetProgressIconAnimationForKey(key, nullptr);
- SetProgressRingAnimationForKey(key, nullptr);
- }
- void ProgressIndicatorAnimationRegistry::EraseAllAnimationsForKeyIf(
- base::RepeatingCallback<bool(const void* key)> predicate) {
- std::set<const void*> keys_to_erase;
- for (const auto& icon_animation_by_key : icon_animations_by_key_) {
- const void* key = icon_animation_by_key.first;
- if (predicate.Run(key))
- keys_to_erase.insert(key);
- }
- for (const auto& ring_animation_by_key : ring_animations_by_key_) {
- const void* key = ring_animation_by_key.first;
- if (predicate.Run(key))
- keys_to_erase.insert(key);
- }
- for (const void* key : keys_to_erase)
- EraseAllAnimationsForKey(key);
- }
- } // namespace ash
|