sequence_model.hpp
Go to the documentation of this file.
00001 /* 00002 Copyright 2005-2007 Adobe Systems Incorporated 00003 Distributed under the MIT License (see accompanying file LICENSE_1_0_0.txt 00004 or a copy at http://stlab.adobe.com/licenses.html) 00005 */ 00006 00007 /******************************************************************************/ 00008 00009 #ifndef ADOBE_SEQUENCE_MODEL_HPP 00010 #define ADOBE_SEQUENCE_MODEL_HPP 00011 00012 /******************************************************************************/ 00013 00014 #include <list> 00015 #ifdef ADOBE_STD_SERIALIZATION 00016 #include <iostream> 00017 #endif 00018 00019 #include <boost/bind.hpp> 00020 #include <boost/next_prior.hpp> 00021 #include <boost/operators.hpp> 00022 #include <boost/static_assert.hpp> 00023 00024 #include <adobe/algorithm/copy.hpp> 00025 #include <adobe/algorithm/find.hpp> 00026 #include <adobe/algorithm/for_each.hpp> 00027 #include <adobe/copy_on_write.hpp> 00028 #include <adobe/poly_sequence_controller.hpp> 00029 #include <adobe/poly_sequence_view.hpp> 00030 #include <adobe/poly_sequence_model.hpp> 00031 #include <adobe/sequence_model_fwd.hpp> 00032 #include <adobe/typeinfo.hpp> 00033 #include <adobe/vector.hpp> 00034 00035 /******************************************************************************/ 00036 00037 namespace adobe { 00038 00039 /******************************************************************************/ 00040 00041 template <typename T> 00042 class sequence_model 00043 { 00044 public: 00046 typedef T value_type; 00048 typedef std::size_t size_type; 00050 typedef copy_on_write<value_type> cow_value_type; 00052 typedef sequence_key<T> key_type; 00054 typedef typename poly_sequence_view<T>::type poly_sequence_view_type; 00056 typedef typename poly_sequence_controller<T>::type poly_sequence_controller_type; 00057 00058 BOOST_STATIC_ASSERT((sizeof(key_type) == sizeof(void*))); 00059 00060 static bool interface_requires_std_rtti() 00061 { return adobe::type_info<T>().requires_std_rtti(); } 00062 00063 static cow_value_type at(key_type key) 00064 { return *key.value_m; } 00065 00066 void push_back(const value_type& value) 00067 { 00068 storage_m.push_back(cow_value_type(value)); 00069 00070 for_each(view_set_m, boost::bind(&poly_sequence_view_type::extend, 00071 _1, 00072 key_type::nkey, 00073 key_type(*--storage_m.end()), 00074 boost::cref(storage_m.back()))); 00075 } 00076 00077 void set(key_type key, const value_type& value) 00078 { 00079 if (!is_valid(key)) 00080 return; 00081 00082 storage_iterator iter(iterator_for(key)); 00083 00084 *iter = cow_value_type(value); 00085 00086 for_each(view_set_m, boost::bind(&poly_sequence_view_type::refresh, 00087 _1, 00088 key, 00089 boost::cref(*iter))); 00090 } 00091 00092 void insert_set(key_type before, const vector<value_type>& value_set) 00093 { 00094 storage_iterator before_iterator(iterator_for(before)); 00095 vector<key_type> extend_key_set; 00096 00097 for (typename vector<value_type>::const_iterator iter(value_set.begin()), 00098 last(value_set.end()); iter != last; ++iter) 00099 { 00100 storage_iterator result(storage_m.insert(before_iterator, cow_value_type(*iter))); 00101 00102 extend_key_set.push_back(key_type(*result)); 00103 } 00104 00105 for_each(view_set_m, boost::bind(&poly_sequence_view_type::extend_set, 00106 _1, 00107 before, 00108 extend_key_set)); 00109 } 00110 00111 void insert(key_type before, const value_type& value) 00112 { 00113 storage_iterator result(storage_m.insert(iterator_for(before), 00114 cow_value_type(value))); 00115 00116 for_each(view_set_m, boost::bind(&poly_sequence_view_type::extend, 00117 _1, 00118 before, 00119 key_type(*result), 00120 boost::cref(*result))); 00121 } 00122 00123 void erase(const vector<key_type>& key_set) 00124 { 00125 typedef typename vector<key_type>::const_iterator const_iterator; 00126 00127 for (const_iterator iter(key_set.begin()), last(key_set.end()); 00128 iter != last; ++iter) 00129 storage_m.erase(iterator_for(*iter)); 00130 00131 for_each(view_set_m, boost::bind(&poly_sequence_view_type::erase, 00132 _1, 00133 boost::cref(key_set))); 00134 } 00135 00136 void clear() 00137 { 00138 storage_m.clear(); 00139 00140 for_each(view_set_m, boost::bind(&poly_sequence_view_type::clear, 00141 _1)); 00142 } 00143 00149 void attach_view(poly_sequence_view_type& view); 00153 void detach_view(poly_sequence_view_type& view); 00154 00161 void attach_controller(poly_sequence_controller_type& controller); 00165 void detach_controller(poly_sequence_controller_type& controller); 00166 00167 private: 00168 #ifndef ADOBE_NO_DOCUMENTATION 00169 00170 typedef std::list<cow_value_type> storage_type; 00171 typedef typename storage_type::iterator storage_iterator; 00172 00173 static bool is_valid(key_type k) 00174 { return k != key_type::nkey; } 00175 00176 size_type size() const { return storage_m.size(); } 00177 bool empty() const { return storage_m.empty(); } 00178 00179 storage_iterator iterator_for(key_type key) const 00180 { 00181 storage_type& storage(const_cast<storage_type&>(storage_m)); 00182 00183 if (!is_valid(key)) 00184 return storage.end(); 00185 00186 // Ugh -- linear search through the list to find the key. 00187 // 00188 // REVISIT (fbrereto) : Is there any way to make this faster? Perhaps a 00189 // cache of some kind to binary-search the key set, 00190 // retrieving an iterator? Using table_index? 00191 00192 for (storage_iterator iter(storage.begin()), last(storage.end()); 00193 iter != last; ++iter) 00194 if (key_type(*iter) == key) 00195 return iter; 00196 00197 return storage.end(); 00198 } 00199 00200 typedef vector<poly_sequence_view_type*> view_set_t; 00201 typedef vector<poly_sequence_controller_type*> controller_set_t; 00202 00203 storage_type storage_m; 00204 view_set_t view_set_m; 00205 controller_set_t controller_set_m; 00206 auto_ptr<typename poly_sequence_model<T>::type> poly_m; 00207 00208 // ADOBE_NO_DOCUMENTATION 00209 #endif 00210 }; 00211 00212 /******************************************************************************/ 00213 00214 template <typename T> 00215 void sequence_model<T>::attach_view(poly_sequence_view_type& view) 00216 { 00217 typename view_set_t::iterator found(adobe::find(view_set_m, &view)); 00218 00219 if (found != view_set_m.end()) 00220 return; 00221 00222 view_set_m.push_back(&view); 00223 00224 view.clear(); 00225 00226 if (empty()) 00227 return; 00228 00229 // tell the view everything possible about the current state of the model 00230 00231 vector<key_type> extend_key_set; 00232 00233 for (storage_iterator iter(storage_m.begin()), last(storage_m.end()); 00234 iter != last; ++iter) 00235 extend_key_set.push_back(key_type(*iter)); 00236 00237 view.extend_set(key_type::nkey, extend_key_set); 00238 } 00239 00240 /******************************************************************************/ 00241 00242 template <typename T> 00243 void sequence_model<T>::detach_view(poly_sequence_view_type& view) 00244 { 00245 typename view_set_t::iterator found(adobe::find(view_set_m, &view)); 00246 00247 if (found == view_set_m.end()) 00248 return; 00249 00250 view_set_m.erase(found); 00251 } 00252 00253 /******************************************************************************/ 00254 00255 template <typename T> 00256 void sequence_model<T>::attach_controller(poly_sequence_controller_type& controller) 00257 { 00258 typename controller_set_t::iterator found(adobe::find(controller_set_m, &controller)); 00259 00260 if (found != controller_set_m.end()) 00261 return; 00262 00263 controller_set_m.push_back(&controller); 00264 00265 if (poly_m.get() == 0) 00266 poly_m.reset(new typename poly_sequence_model<T>::type(boost::ref(*this))); 00267 00268 controller.monitor_sequence(*poly_m); 00269 } 00270 00271 /******************************************************************************/ 00272 00273 template <typename T> 00274 void sequence_model<T>::detach_controller(poly_sequence_controller_type& controller) 00275 { 00276 typename controller_set_t::iterator found(adobe::find(controller_set_m, &controller)); 00277 00278 if (found == controller_set_m.end()) 00279 return; 00280 00281 controller_set_m.erase(found); 00282 } 00283 00284 /******************************************************************************/ 00285 00286 } // namespace adobe 00287 00288 /******************************************************************************/ 00289 // ADOBE_SEQUENCE_MODEL_HPP 00290 #endif 00291 00292 /******************************************************************************/ |