Home | History | Annotate | Download | only in base
      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