// Copyright (c) 2012 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 "ui/views/focus/view_storage.h"
#include <algorithm>
#include "base/logging.h"
#include "base/memory/singleton.h"
#include "base/stl_util.h"
namespace views {
// static
ViewStorage* ViewStorage::GetInstance() {
return Singleton<ViewStorage>::get();
}
ViewStorage::ViewStorage() : view_storage_next_id_(0) {
}
ViewStorage::~ViewStorage() {
STLDeleteContainerPairSecondPointers(view_to_ids_.begin(),
view_to_ids_.end());
}
int ViewStorage::CreateStorageID() {
return view_storage_next_id_++;
}
void ViewStorage::StoreView(int storage_id, View* view) {
DCHECK(view);
std::map<int, View*>::iterator iter = id_to_view_.find(storage_id);
if (iter != id_to_view_.end()) {
NOTREACHED();
RemoveView(storage_id);
}
id_to_view_[storage_id] = view;
std::vector<int>* ids = NULL;
std::map<View*, std::vector<int>*>::iterator id_iter =
view_to_ids_.find(view);
if (id_iter == view_to_ids_.end()) {
ids = new std::vector<int>();
view_to_ids_[view] = ids;
} else {
ids = id_iter->second;
}
ids->push_back(storage_id);
}
View* ViewStorage::RetrieveView(int storage_id) {
std::map<int, View*>::iterator iter = id_to_view_.find(storage_id);
if (iter == id_to_view_.end())
return NULL;
return iter->second;
}
void ViewStorage::RemoveView(int storage_id) {
EraseView(storage_id, false);
}
void ViewStorage::ViewRemoved(View* removed) {
// Let's first retrieve the ids for that view.
std::map<View*, std::vector<int>*>::iterator ids_iter =
view_to_ids_.find(removed);
if (ids_iter == view_to_ids_.end()) {
// That view is not in the view storage.
return;
}
std::vector<int>* ids = ids_iter->second;
DCHECK(!ids->empty());
EraseView((*ids)[0], true);
}
void ViewStorage::EraseView(int storage_id, bool remove_all_ids) {
// Remove the view from id_to_view_location_.
std::map<int, View*>::iterator view_iter = id_to_view_.find(storage_id);
if (view_iter == id_to_view_.end())
return;
View* view = view_iter->second;
id_to_view_.erase(view_iter);
// Also update view_to_ids_.
std::map<View*, std::vector<int>*>::iterator ids_iter =
view_to_ids_.find(view);
DCHECK(ids_iter != view_to_ids_.end());
std::vector<int>* ids = ids_iter->second;
if (remove_all_ids) {
for (size_t i = 0; i < ids->size(); ++i) {
view_iter = id_to_view_.find((*ids)[i]);
if (view_iter != id_to_view_.end())
id_to_view_.erase(view_iter);
}
ids->clear();
} else {
std::vector<int>::iterator id_iter =
std::find(ids->begin(), ids->end(), storage_id);
DCHECK(id_iter != ids->end());
ids->erase(id_iter);
}
if (ids->empty()) {
delete ids;
view_to_ids_.erase(ids_iter);
}
}
} // namespace views