1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "ui/base/view_prop.h" 6 7 #include <set> 8 9 namespace ui { 10 11 // Maints the actual view, key and data. 12 class ViewProp::Data : public base::RefCounted<ViewProp::Data> { 13 public: 14 // Returns the Data* for the view/key pair. If |create| is false and |Get| 15 // has not been invoked for the view/key pair, NULL is returned. 16 static void Get(gfx::AcceleratedWidget view, 17 const char* key, 18 bool create, 19 scoped_refptr<Data>* data) { 20 if (!data_set_) 21 data_set_ = new DataSet; 22 scoped_refptr<Data> new_data(new Data(view, key)); 23 DataSet::const_iterator i = data_set_->find(new_data.get()); 24 if (i != data_set_->end()) { 25 *data = *i; 26 return; 27 } 28 if (!create) 29 return; 30 data_set_->insert(new_data.get()); 31 *data = new_data.get(); 32 } 33 34 // The data. 35 void set_data(void* data) { data_ = data; } 36 void* data() const { return data_; } 37 38 const char* key() const { return key_; } 39 40 private: 41 friend class base::RefCounted<Data>; 42 43 // Used to order the Data in the map. 44 class DataComparator { 45 public: 46 bool operator()(const Data* d1, const Data* d2) const { 47 return (d1->view_ == d2->view_) ? (d1->key_ < d2->key_) : 48 (d1->view_ < d2->view_); 49 } 50 }; 51 52 typedef std::set<Data*, DataComparator> DataSet; 53 54 Data(gfx::AcceleratedWidget view, const char* key) 55 : view_(view), 56 key_(key), 57 data_(NULL) {} 58 59 ~Data() { 60 DataSet::iterator i = data_set_->find(this); 61 // Also check for equality using == as |Get| creates dummy values in order 62 // to look up a value. 63 if (i != data_set_->end() && *i == this) 64 data_set_->erase(i); 65 } 66 67 // The existing set of Data is stored here. ~Data removes from the set. 68 static DataSet* data_set_; 69 70 const gfx::AcceleratedWidget view_; 71 const char* key_; 72 void* data_; 73 74 DISALLOW_COPY_AND_ASSIGN(Data); 75 }; 76 77 // static 78 ViewProp::Data::DataSet* ViewProp::Data::data_set_ = NULL; 79 80 ViewProp::ViewProp(gfx::AcceleratedWidget view, const char* key, void* data) { 81 Data::Get(view, key, true, &data_); 82 data_->set_data(data); 83 } 84 85 ViewProp::~ViewProp() { 86 // This is done to provide similar semantics to SetProp. In particular it's 87 // assumed that ~ViewProp should behave as though RemoveProp was invoked. 88 data_->set_data(NULL); 89 } 90 91 // static 92 void* ViewProp::GetValue(gfx::AcceleratedWidget view, const char* key) { 93 scoped_refptr<Data> data; 94 Data::Get(view, key, false, &data); 95 return data.get() ? data->data() : NULL; 96 } 97 98 // static 99 const char* ViewProp::Key() const { 100 return data_->key(); 101 } 102 103 } // namespace ui 104