chrome ui源码剖析-ViewProp
2013-08-12 00:27 Clingingboy 阅读(660) 评论(0) 编辑 收藏 举报
先熟悉set的find原理
http://www.cnblogs.com/Clingingboy/p/3252136.html
这个类改造下,还是非常实用的,可以对于不同的类型做数据存储
一.ViewProp
// Copyright (c) 2011 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. #ifndef UI_BASE_VIEW_PROP_H_ #define UI_BASE_VIEW_PROP_H_ namespace ui { // ViewProp maintains a key/value pair for a particular view. ViewProp is // designed as a replacement for the Win32's SetProp, but does not make use of // window manager memory. ViewProp shares similar semantics as SetProp, the // value for a particular view/key pair comes from the last ViewProp created. class UI_EXPORT ViewProp { public: // Associates data with a view/key pair. If a ViewProp has already been // created for the specified pair |data| replaces the current value. // // ViewProp does *not* make a copy of the char*, the pointer is used for // sorting. ViewProp(gfx::AcceleratedWidget view, const char* key, void* data); ~ViewProp(); // Returns the value associated with the view/key pair, or NULL if there is // none. static void* GetValue(gfx::AcceleratedWidget view, const char* key); // Returns the key. const char* Key() const; private: class Data; // Stores the actual data. scoped_refptr<Data> data_; }; } // namespace ui #endif // UI_BASE_VIEW_PROP_H_
二.实现
ViewProp::ViewProp(gfx::AcceleratedWidget view, const char* key, void* data) { Data::Get(view, key, true, &data_); data_->set_data(data); } ViewProp::~ViewProp() { // This is done to provide similar semantics to SetProp. In particular it's // assumed that ~ViewProp should behave as though RemoveProp was invoked. data_->set_data(NULL); } // static void* ViewProp::GetValue(gfx::AcceleratedWidget view, const char* key) { scoped_refptr<Data> data; Data::Get(view, key, false, &data); return data.get() ? data->data() : NULL; } // static const char* ViewProp::Key() const { return data_->key(); }
三.测试代码
TEST(ViewPropTest, Basic) { gfx::AcceleratedWidget nv1 = reinterpret_cast<gfx::AcceleratedWidget>(1); void* data1 = reinterpret_cast<void*>(11); // Register a value for a view/key pair. const char kKey1[] = "key_1"; ViewProp prop(nv1, kKey1, data1); EXPECT_EQ(data1, ViewProp::GetValue(nv1, kKey1)); }
- 构建一个ViewProp
- 然后使用ViewProp::GetValue静态方法查找
四.Data类的实现
ViewProp构造函数用Data::Get创建Data,查找的时候还是用Data::Get方法,区别在于构造函数时创建,查找时不会创建
// Maints the actual view, key and data. class ViewProp::Data : public base::RefCounted<ViewProp::Data> { public: // Returns the Data* for the view/key pair. If |create| is false and |Get| // has not been invoked for the view/key pair, NULL is returned. static void Get(gfx::AcceleratedWidget view, const char* key, bool create, scoped_refptr<Data>* data) { if (!data_set_) data_set_ = new DataSet; scoped_refptr<Data> new_data(new Data(view, key)); DataSet::const_iterator i = data_set_->find(new_data.get()); if (i != data_set_->end()) { *data = *i; return; } if (!create) return; data_set_->insert(new_data.get()); *data = new_data.get(); } // The data. void set_data(void* data) { data_ = data; } void* data() const { return data_; } const char* key() const { return key_; } private: friend class base::RefCounted<Data>; // Used to order the Data in the map. class DataComparator { public: bool operator()(const Data* d1, const Data* d2) const { return (d1->view_ == d2->view_) ? (d1->key_ < d2->key_) : (d1->view_ < d2->view_); } }; typedef std::set<Data*, DataComparator> DataSet; Data(gfx::AcceleratedWidget view, const char* key) : view_(view), key_(key), data_(NULL) {} ~Data() { DataSet::iterator i = data_set_->find(this); // Also check for equality using == as |Get| creates dummy values in order // to look up a value. if (i != data_set_->end() && *i == this) data_set_->erase(i); } // The existing set of Data is stored here. ~Data removes from the set. static DataSet* data_set_; const gfx::AcceleratedWidget view_; const char* key_; void* data_; DISALLOW_COPY_AND_ASSIGN(Data); }; // static ViewProp::Data::DataSet* ViewProp::Data::data_set_ = NULL;