00001 // -*- c-basic-offset: 4 -*- 00024 #ifndef _PANODATA_IMAGEVARIABLE_H 00025 #define _PANODATA_IMAGEVARIABLE_H 00026 00027 00028 namespace HuginBase 00029 { 00030 00046 template <class Type> 00047 class ImageVariable 00048 { 00049 public: 00051 ImageVariable(); 00052 00054 ImageVariable(Type data); 00055 00064 ImageVariable(ImageVariable<Type> * link); 00065 00071 ImageVariable(const ImageVariable &source); 00072 00074 ~ImageVariable(); 00075 00077 Type getData() const; 00078 00086 void setData(const Type data); 00087 00114 void linkWith(ImageVariable<Type> * link); 00115 00121 void removeLinks(); 00122 00128 bool isLinked() const; 00129 00149 bool isLinkedWith(const ImageVariable<Type> * otherVariable) const; 00150 00151 protected: 00182 bool searchBackwards(const ImageVariable<Type> * otherVariable) const; 00183 00189 bool searchForwards(const ImageVariable<Type> * otherVariable) const; 00190 00193 ImageVariable<Type> * findStart(); 00194 00197 ImageVariable<Type> * findEnd(); 00198 00201 void setBackwards(const Type data); 00202 00205 void setForwards(const Type data); 00206 00208 // Member variables 00209 00211 Type m_data; 00212 00214 ImageVariable<Type> * m_linkPrevious; 00216 ImageVariable<Type> * m_linkNext; 00217 }; // ImageVariable class 00218 00220 // Public member functions // 00222 00223 // Constructors 00224 00225 template <class Type> 00226 ImageVariable<Type>::ImageVariable() 00227 { 00228 // Start not linked to anything, so the variable is independant. 00229 m_linkPrevious = 0; 00230 m_linkNext = 0; 00231 } 00232 00233 template <class Type> 00234 ImageVariable<Type>::ImageVariable(Type data) 00235 { 00236 // Use the data given 00237 m_data = data; 00238 // ...and start not linked to anything. 00239 m_linkPrevious = 0; 00240 m_linkNext = 0; 00241 } 00242 00243 template <class Type> 00244 ImageVariable<Type>::ImageVariable(ImageVariable<Type> * link) 00245 { 00246 // So we don't break linkWith: 00247 m_linkPrevious = 0; 00248 m_linkNext = 0; 00249 // make the link. Note this sets our data from linked variables. 00250 linkWith(link); 00251 } 00252 00253 template <class Type> 00254 ImageVariable<Type>::ImageVariable(const ImageVariable<Type> & source) 00255 { 00256 // When creating a copy, make independant. 00257 m_data = source.m_data; 00258 m_linkNext = 0; 00259 m_linkPrevious = 0; 00260 } 00261 00262 // Destructor 00263 00264 template <class Type> 00265 ImageVariable<Type>::~ImageVariable() 00266 { 00267 // We will need to remove the links to this variable to keep the list sane. 00268 removeLinks(); 00269 // it is safe to delete this object now. 00270 } 00271 00272 // Other public member functions 00273 00274 template <class Type> 00275 Type ImageVariable<Type>::getData() const 00276 { 00277 return m_data; 00278 } 00279 00280 template <class Type> 00281 void ImageVariable<Type>::setData(const Type data) 00282 { 00283 /* We keep multiple copies of the data. 00284 * Hopefully the data isn't too large, and setData is called far less often 00285 * then getData, so it should be fast enough this way. 00286 */ 00287 // set all the linked variables. 00288 // these both set this variables data. 00289 setBackwards(data); 00290 setForwards(data); 00291 } 00292 00293 template <class Type> 00294 void ImageVariable<Type>::linkWith(ImageVariable<Type> * link) 00295 { 00296 // We need to first check that we aren't linked already. 00297 if (searchBackwards(link) || searchForwards(link)) 00298 { 00299 DEBUG_INFO("Attempt to link already linked variables"); 00300 return; 00301 } 00302 else 00303 { 00304 // not linked, it is safe to merge them. 00305 /* we need to merge the two sets together. We link the end of the list 00306 * with this object in it to the beginning of the list passed to us. 00307 */ 00308 ImageVariable<Type> *end = findEnd(); 00309 ImageVariable<Type> *beginning = link->findStart(); 00310 end->m_linkNext = beginning; 00311 beginning->m_linkPrevious = end; 00312 // now we must set the data from what we were linked to. 00313 /* the link target has the same data, but the stuff previously linked 00314 * with us might have something different. 00315 */ 00316 setBackwards(link->m_data); 00317 } 00318 } 00319 00320 template <class Type> 00321 void ImageVariable<Type>::removeLinks() 00322 { 00323 if (m_linkPrevious) 00324 { 00325 // there is something before us, link it to the item after, or 0 if none 00326 m_linkPrevious->m_linkNext = m_linkNext; 00327 } 00328 if (m_linkNext) 00329 { 00330 // there is something after us, link it to the item before, or 0 if none 00331 m_linkNext->m_linkPrevious = m_linkPrevious; 00332 m_linkNext = 0; 00333 } 00334 m_linkPrevious = 0; 00335 } 00336 00337 template <class Type> 00338 bool ImageVariable<Type>::isLinked() const 00339 { 00340 // return true if there are any links, false if this variable is independant 00341 return (m_linkPrevious || m_linkNext); 00342 } 00343 00344 template <class Type> 00345 bool ImageVariable<Type>::isLinkedWith(const ImageVariable<Type> * otherVariable) const 00346 { 00347 // return true if we can find a link with the given item. 00348 return (searchBackwards(otherVariable) || searchForwards(otherVariable)); 00349 } 00350 00352 // Protected member functions // 00354 00355 template <class Type> 00356 bool ImageVariable<Type>::searchBackwards(const ImageVariable<Type> * otherVariable) const 00357 { 00358 // is this what we are looking for? 00359 if (this == otherVariable) return true; 00360 // are there any more items to check? 00361 if (!m_linkPrevious) return false; 00362 // try another one. 00363 return m_linkPrevious->searchBackwards(otherVariable); 00364 } 00365 00366 template <class Type> 00367 bool ImageVariable<Type>::searchForwards(const ImageVariable<Type> * otherVariable) const 00368 { 00369 // is this what we are looking for? 00370 if (this == otherVariable) return true; 00371 // are there any more items to check? 00372 if (!m_linkNext) return false; 00373 // try another one. 00374 return m_linkNext->searchForwards(otherVariable); 00375 } 00376 00377 template <class Type> 00378 ImageVariable<Type> * ImageVariable<Type>::findStart() 00379 { 00380 // Is this the start of the list? 00381 if (!m_linkPrevious) return this; 00382 // look father back 00383 return m_linkPrevious->findStart(); 00384 } 00385 00386 template <class Type> 00387 ImageVariable<Type> * ImageVariable<Type>::findEnd() 00388 { 00389 // Is this the end of the list? 00390 if (!m_linkNext) return this; 00391 // look father forwards 00392 return m_linkNext->findEnd(); 00393 } 00394 00395 template <class Type> 00396 void ImageVariable<Type>::setBackwards(const Type data) 00397 { 00398 // set this and all proceeding items. 00399 m_data = data; 00400 if (m_linkPrevious) m_linkPrevious->setBackwards(data); 00401 } 00402 00403 template <class Type> 00404 void ImageVariable<Type>::setForwards(const Type data) 00405 { 00406 // set this and all proceeding items. 00407 m_data = data; 00408 if (m_linkNext) m_linkNext->setForwards(data); 00409 } 00410 00411 } // HuginBase namespace 00412 00413 #endif // ndef _PANODATA_IMAGEVARIABLE_H
1.3.9.1