| Index: base/callback_list_internal.cc
|
| diff --git a/base/callback_list_internal.cc b/base/callback_list_internal.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..76f7b1cb21e1c6bd7e68b58d4962543ad3b96d7a
|
| --- /dev/null
|
| +++ b/base/callback_list_internal.cc
|
| @@ -0,0 +1,91 @@
|
| +// Copyright 2013 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 "base/callback_list_internal.h"
|
| +
|
| +#include <algorithm>
|
| +
|
| +#include "base/bind.h"
|
| +#include "base/bind_helpers.h"
|
| +
|
| +namespace base {
|
| +namespace internal {
|
| +
|
| +CallbackListImpl::Iterator::Iterator(
|
| + const base::WeakPtr<CallbackListImpl>& list)
|
| + : list_(list),
|
| + index_(0) {
|
| + ++list_->active_iterator_count_;
|
| +}
|
| +
|
| +CallbackListImpl::Iterator::~Iterator() {
|
| + if (list_ && --list_->active_iterator_count_ == 0) {
|
| + list_->Compact();
|
| + }
|
| +}
|
| +
|
| +CallbackBase* CallbackListImpl::Iterator::GetNext() {
|
| + if (!list_)
|
| + return NULL;
|
| + size_t max_index = list_->callbacks_.size();
|
| + while (index_ < max_index && !list_->callbacks_[index_])
|
| + ++index_;
|
| + return index_ < max_index ? list_->callbacks_[index_++] : NULL;
|
| +}
|
| +
|
| +CallbackListImpl::CallbackListImpl()
|
| + : active_iterator_count_(0),
|
| + weak_factory_(this) {}
|
| +
|
| +CallbackListImpl::~CallbackListImpl() {
|
| + Clear();
|
| +}
|
| +
|
| +void CallbackListImpl::Clear() {
|
| + if (active_iterator_count_) {
|
| + for (size_t i = 0; i < callbacks_.size(); ++i) {
|
| + CallbackBase* tmp = callbacks_[i];
|
| + delete tmp;
|
| + callbacks_[i] = NULL;
|
| + }
|
| + } else {
|
| + for (size_t i = 0; i < callbacks_.size(); ++i)
|
| + delete callbacks_[i];
|
| + callbacks_.clear();
|
| + }
|
| +}
|
| +
|
| +void CallbackListImpl::Remove(base::internal::CallbackBase* cb) {
|
| + for (size_t i = 0; i < callbacks_.size(); i++) {
|
| + if (callbacks_[i] == cb) {
|
| + CallbackBase* tmp = callbacks_[i];
|
| + delete tmp;
|
| + if (active_iterator_count_) {
|
| + callbacks_[i] = NULL;
|
| + } else {
|
| + callbacks_.erase(callbacks_.begin() + i);
|
| + }
|
| + return;
|
| + }
|
| + }
|
| +}
|
| +
|
| +base::Closure CallbackListImpl::Add(base::internal::CallbackBase* cb) {
|
| + callbacks_.push_back(cb);
|
| + return base::Bind(&CallbackListImpl::Remove, Unretained(this), cb);
|
| +}
|
| +
|
| +scoped_ptr<CallbackListImpl::Iterator> CallbackListImpl::GetIterator() {
|
| + return make_scoped_ptr(new Iterator(weak_factory_.GetWeakPtr()));
|
| +}
|
| +
|
| +void CallbackListImpl::Compact() {
|
| + callbacks_.erase(
|
| + std::remove(callbacks_.begin(), callbacks_.end(),
|
| + static_cast<base::internal::CallbackBase*>(NULL)),
|
| + callbacks_.end());
|
| +}
|
| +
|
| +} // namespace internal
|
| +} // namespace base
|
|
|