MOAB: Mesh Oriented datABase
(version 5.4.1)
|
00001 /* ***************************************************************** 00002 MESQUITE -- The Mesh Quality Improvement Toolkit 00003 00004 Copyright 2006 Lawrence Livermore National Laboratory. Under 00005 the terms of Contract B545069 with the University of Wisconsin -- 00006 Madison, Lawrence Livermore National Laboratory retains certain 00007 rights in this software. 00008 00009 This library is free software; you can redistribute it and/or 00010 modify it under the terms of the GNU Lesser General Public 00011 License as published by the Free Software Foundation; either 00012 version 2.1 of the License, or (at your option) any later version. 00013 00014 This library is distributed in the hope that it will be useful, 00015 but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00017 Lesser General Public License for more details. 00018 00019 You should have received a copy of the GNU Lesser General Public License 00020 (lgpl.txt) along with this library; if not, write to the Free Software 00021 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00022 00023 (2006) [email protected] 00024 00025 ***************************************************************** */ 00026 00027 /** \file ExtraDataUser.hpp 00028 * \brief 00029 * \author Jason Kraftcheck 00030 */ 00031 00032 #ifndef MSQ_EXTRA_DATA_USER_HPP 00033 #define MSQ_EXTRA_DATA_USER_HPP 00034 00035 #include "Mesquite.hpp" 00036 #include "ExtraData.hpp" 00037 #include <cassert> 00038 00039 namespace MBMesquite 00040 { 00041 00042 template < typename T > 00043 class ExtraUserData; 00044 00045 /**\brief Manage extra data attached to PatchData instances 00046 * 00047 * This class manages the details of using the ExtraData mechanism 00048 * for attaching data to and/or observing a PatchData. The template 00049 * parameter is the type definint the data to be stored on the 00050 * PatchData. 00051 * 00052 * To use this class, define a type (struct or whatever) to contain 00053 * the data that will be stored on PatchData instances, and create 00054 * a subclass of this class, where the template parameter for this 00055 * class is the data type. Provide implementations of the pure 00056 * virtual (abstract) methods for notification of changes to the PatchData. 00057 */ 00058 template < typename T > 00059 class ExtraDataUser 00060 { 00061 public: 00062 ExtraDataUser(); 00063 00064 virtual ~ExtraDataUser(); 00065 00066 typedef T DataType; 00067 00068 /** returns null if data hasn't been set via set_data */ 00069 T* get_data_ptr( PatchData& patch ); 00070 00071 /** creates data if doesn't exist */ 00072 T& get_data( PatchData& patch ); 00073 00074 void set_data( PatchData& patch, const T& data ); 00075 00076 void notify_patch_destroyed( ExtraUserData< T >* data ); 00077 00078 virtual void notify_patch_destroyed( T& data ) = 0; 00079 00080 virtual void notify_new_patch( PatchData& patch, T& data ) = 0; 00081 00082 virtual void notify_sub_patch( PatchData& patch, 00083 T& data, 00084 PatchData& sub_patch, 00085 const size_t* vertex_index_map, 00086 const size_t* element_index_map, 00087 MsqError& err ) = 0; 00088 00089 private: 00090 ExtraUserData< T >* listHead; 00091 }; 00092 00093 template < typename T > 00094 class ExtraUserData : public ExtraData 00095 { 00096 public: 00097 ExtraDataUser< T >* dataOwner; 00098 ExtraUserData< T >* userNext; 00099 T userData; 00100 00101 ExtraUserData( PatchData& patch, ExtraDataUser< T >* owner, ExtraUserData< T >* next, const T& data ) 00102 : ExtraData( patch ), dataOwner( owner ), userNext( next ), userData( data ) 00103 { 00104 } 00105 00106 ExtraUserData( PatchData& patch, ExtraDataUser< T >* owner, ExtraUserData< T >* next ) 00107 : ExtraData( patch ), dataOwner( owner ), userNext( next ) 00108 { 00109 } 00110 00111 virtual void notify_patch_destroyed(); 00112 00113 virtual void notify_new_patch(); 00114 00115 virtual void notify_sub_patch( PatchData& sub_patch, 00116 const size_t* vtx_index_map, 00117 const size_t* elm_index_map, 00118 MsqError& err ); 00119 }; 00120 00121 template < typename T > 00122 void ExtraUserData< T >::notify_patch_destroyed() 00123 { 00124 dataOwner->notify_patch_destroyed( this ); 00125 } 00126 00127 template < typename T > 00128 void ExtraUserData< T >::notify_new_patch() 00129 { 00130 dataOwner->notify_new_patch( *get_patch_data(), userData ); 00131 } 00132 00133 template < typename T > 00134 void ExtraUserData< T >::notify_sub_patch( PatchData& sub, 00135 const size_t* vertex_map, 00136 const size_t* element_map, 00137 MsqError& err ) 00138 { 00139 dataOwner->notify_sub_patch( *get_patch_data(), userData, sub, vertex_map, element_map, err ); 00140 } 00141 00142 template < typename T > 00143 ExtraDataUser< T >::ExtraDataUser() : listHead( 0 ) 00144 { 00145 } 00146 00147 template < typename T > 00148 ExtraDataUser< T >::~ExtraDataUser() 00149 { 00150 while( ExtraUserData< T >* dead_ptr = listHead ) 00151 { 00152 listHead = dead_ptr->userNext; 00153 dead_ptr->userNext = 0; 00154 delete dead_ptr; 00155 } 00156 } 00157 00158 template < typename T > 00159 T* ExtraDataUser< T >::get_data_ptr( PatchData& patch ) 00160 { 00161 for( ExtraUserData< T >* ptr = listHead; ptr; ptr = ptr->userNext ) 00162 if( ptr->get_patch_data() == &patch ) return &( ptr->userData ); 00163 return 0; 00164 } 00165 00166 template < typename T > 00167 T& ExtraDataUser< T >::get_data( PatchData& patch ) 00168 { 00169 T* ptr = get_data_ptr( patch ); 00170 if( !ptr ) 00171 { 00172 listHead = new ExtraUserData< T >( patch, this, listHead ); 00173 ptr = &( listHead->userData ); 00174 } 00175 return *ptr; 00176 } 00177 00178 template < typename T > 00179 void ExtraDataUser< T >::set_data( PatchData& patch, const T& data ) 00180 { 00181 T* ptr = get_data_ptr( patch ); 00182 if( ptr ) 00183 *ptr = data; 00184 else 00185 listHead = new ExtraUserData< T >( patch, this, listHead, data ); 00186 } 00187 00188 template < typename T > 00189 void ExtraDataUser< T >::notify_patch_destroyed( ExtraUserData< T >* data ) 00190 { 00191 // remove from list 00192 assert( listHead != 0 ); 00193 if( listHead == data ) 00194 listHead = data->userNext; 00195 else 00196 { 00197 ExtraUserData< T >* prev; 00198 for( prev = listHead; prev->userNext != data; prev = prev->userNext ) 00199 assert( prev->userNext != 0 ); 00200 prev->userNext = data->userNext; 00201 } 00202 data->userNext = 0; 00203 00204 // notify concrete class of event 00205 notify_patch_destroyed( data->userData ); 00206 00207 delete data; 00208 } 00209 00210 } // namespace MBMesquite 00211 00212 #endif