MOAB: Mesh Oriented datABase
(version 5.2.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) kraftche@cae.wisc.edu 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 <assert.h> 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, T& data, PatchData& sub_patch, const size_t* vertex_index_map, 00083 const size_t* element_index_map, MsqError& err ) = 0; 00084 00085 private: 00086 ExtraUserData< T >* listHead; 00087 }; 00088 00089 template < typename T > 00090 class ExtraUserData : public ExtraData 00091 { 00092 public: 00093 ExtraDataUser< T >* dataOwner; 00094 ExtraUserData< T >* userNext; 00095 T userData; 00096 00097 ExtraUserData( PatchData& patch, ExtraDataUser< T >* owner, ExtraUserData< T >* next, const T& data ) 00098 : ExtraData( patch ), dataOwner( owner ), userNext( next ), userData( data ) 00099 { 00100 } 00101 00102 ExtraUserData( PatchData& patch, ExtraDataUser< T >* owner, ExtraUserData< T >* next ) 00103 : ExtraData( patch ), dataOwner( owner ), userNext( next ) 00104 { 00105 } 00106 00107 virtual void notify_patch_destroyed(); 00108 00109 virtual void notify_new_patch(); 00110 00111 virtual void notify_sub_patch( PatchData& sub_patch, const size_t* vtx_index_map, const size_t* elm_index_map, 00112 MsqError& err ); 00113 }; 00114 00115 template < typename T > 00116 void ExtraUserData< T >::notify_patch_destroyed() 00117 { 00118 dataOwner->notify_patch_destroyed( this ); 00119 } 00120 00121 template < typename T > 00122 void ExtraUserData< T >::notify_new_patch() 00123 { 00124 dataOwner->notify_new_patch( *get_patch_data(), userData ); 00125 } 00126 00127 template < typename T > 00128 void ExtraUserData< T >::notify_sub_patch( PatchData& sub, const size_t* vertex_map, const size_t* element_map, 00129 MsqError& err ) 00130 { 00131 dataOwner->notify_sub_patch( *get_patch_data(), userData, sub, vertex_map, element_map, err ); 00132 } 00133 00134 template < typename T > 00135 ExtraDataUser< T >::ExtraDataUser() : listHead( 0 ) 00136 { 00137 } 00138 00139 template < typename T > 00140 ExtraDataUser< T >::~ExtraDataUser() 00141 { 00142 while( ExtraUserData< T >* dead_ptr = listHead ) 00143 { 00144 listHead = dead_ptr->userNext; 00145 dead_ptr->userNext = 0; 00146 delete dead_ptr; 00147 } 00148 } 00149 00150 template < typename T > 00151 T* ExtraDataUser< T >::get_data_ptr( PatchData& patch ) 00152 { 00153 for( ExtraUserData< T >* ptr = listHead; ptr; ptr = ptr->userNext ) 00154 if( ptr->get_patch_data() == &patch ) return &( ptr->userData ); 00155 return 0; 00156 } 00157 00158 template < typename T > 00159 T& ExtraDataUser< T >::get_data( PatchData& patch ) 00160 { 00161 T* ptr = get_data_ptr( patch ); 00162 if( !ptr ) 00163 { 00164 listHead = new ExtraUserData< T >( patch, this, listHead ); 00165 ptr = &( listHead->userData ); 00166 } 00167 return *ptr; 00168 } 00169 00170 template < typename T > 00171 void ExtraDataUser< T >::set_data( PatchData& patch, const T& data ) 00172 { 00173 T* ptr = get_data_ptr( patch ); 00174 if( ptr ) 00175 *ptr = data; 00176 else 00177 listHead = new ExtraUserData< T >( patch, this, listHead, data ); 00178 } 00179 00180 template < typename T > 00181 void ExtraDataUser< T >::notify_patch_destroyed( ExtraUserData< T >* data ) 00182 { 00183 // remove from list 00184 assert( listHead != 0 ); 00185 if( listHead == data ) 00186 listHead = data->userNext; 00187 else 00188 { 00189 ExtraUserData< T >* prev; 00190 for( prev = listHead; prev->userNext != data; prev = prev->userNext ) 00191 assert( prev->userNext != 0 ); 00192 prev->userNext = data->userNext; 00193 } 00194 data->userNext = 0; 00195 00196 // notify concrete class of event 00197 notify_patch_destroyed( data->userData ); 00198 00199 delete data; 00200 } 00201 00202 } // namespace MBMesquite 00203 00204 #endif