chromium/base/callback_list.h

// Copyright 2013 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef BASE_CALLBACK_LIST_H_
#define BASE_CALLBACK_LIST_H_

#include <list>
#include <memory>
#include <utility>

#include "base/auto_reset.h"
#include "base/base_export.h"
#include "base/check.h"
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/memory/weak_ptr.h"
#include "base/ranges/algorithm.h"
#include "base/types/is_instantiation.h"

// OVERVIEW:
//
// A container for a list of callbacks. Provides callers the ability to manually
// or automatically unregister callbacks at any time, including during callback
// notification.
//
// TYPICAL USAGE:
//
// class MyWidget {
//  public:
//   using CallbackList = base::RepeatingCallbackList<void(const Foo&)>;
//
//   // Registers |cb| to be called whenever NotifyFoo() is executed.
//   CallbackListSubscription RegisterCallback(CallbackList::CallbackType cb) {
//     return callback_list_.Add(std::move(cb));
//   }
//
//  private:
//   // Calls all registered callbacks, with |foo| as the supplied arg.
//   void NotifyFoo(const Foo& foo) {
//     callback_list_.Notify(foo);
//   }
//
//   CallbackList callback_list_;
// };
//
//
// class MyWidgetListener {
//  private:
//   void OnFoo(const Foo& foo) {
//     // Called whenever MyWidget::NotifyFoo() is executed, unless
//     // |foo_subscription_| has been destroyed.
//   }
//
//   // Automatically deregisters the callback when deleted (e.g. in
//   // ~MyWidgetListener()).  Unretained(this) is safe here since the
//   // ScopedClosureRunner does not outlive |this|.
//   CallbackListSubscription foo_subscription_ =
//       MyWidget::Get()->RegisterCallback(
//           base::BindRepeating(&MyWidgetListener::OnFoo,
//                               base::Unretained(this)));
// };
//
// UNSUPPORTED:
//
// * Destroying the CallbackList during callback notification.
//
// This is possible to support, but not currently necessary.

namespace base {
namespace internal {
template <typename CallbackListImpl>
class CallbackListBase;
}  // namespace internal

template <typename Signature>
class OnceCallbackList;

template <typename Signature>
class RepeatingCallbackList;

// A trimmed-down version of ScopedClosureRunner that can be used to guarantee a
// closure is run on destruction. This is designed to be used by
// CallbackListBase to run CancelCallback() when this subscription dies;
// consumers can avoid callbacks on dead objects by ensuring the subscription
// returned by CallbackListBase::Add() does not outlive the bound object in the
// callback. A typical way to do this is to bind a callback to a member function
// on `this` and store the returned subscription as a member variable.
class [[nodiscard]] BASE_EXPORT CallbackListSubscription {};

namespace internal {

// A traits class to break circular type dependencies between CallbackListBase
// and its subclasses.
template <typename CallbackList>
struct CallbackListTraits;

// NOTE: It's important that Callbacks provide iterator stability when items are
// added to the end, so e.g. a std::vector<> is not suitable here.
CallbackListTraits<OnceCallbackList<Signature>>;
CallbackListTraits<RepeatingCallbackList<Signature>>;

template <typename CallbackListImpl>
class CallbackListBase {};

}  // namespace internal

template <typename Signature>
class OnceCallbackList
    : public internal::CallbackListBase<OnceCallbackList<Signature>> {};

template <typename Signature>
class RepeatingCallbackList
    : public internal::CallbackListBase<RepeatingCallbackList<Signature>> {};

// Syntactic sugar to parallel that used for {Once,Repeating}Callbacks.
OnceClosureList;
RepeatingClosureList;

}  // namespace base

#endif  // BASE_CALLBACK_LIST_H_