Branch data Line data Source code
1 : : /* *****************************************************************
2 : : MESQUITE -- The Mesh Quality Improvement Toolkit
3 : :
4 : : Copyright 2006 Lawrence Livermore National Laboratory. Under
5 : : the terms of Contract B545069 with the University of Wisconsin --
6 : : Madison, Lawrence Livermore National Laboratory retains certain
7 : : rights in this software.
8 : :
9 : : This library is free software; you can redistribute it and/or
10 : : modify it under the terms of the GNU Lesser General Public
11 : : License as published by the Free Software Foundation; either
12 : : version 2.1 of the License, or (at your option) any later version.
13 : :
14 : : This library is distributed in the hope that it will be useful,
15 : : but WITHOUT ANY WARRANTY; without even the implied warranty of
16 : : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 : : Lesser General Public License for more details.
18 : :
19 : : You should have received a copy of the GNU Lesser General Public License
20 : : (lgpl.txt) along with this library; if not, write to the Free Software
21 : : Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 : :
23 : : (2006) [email protected]
24 : :
25 : : ***************************************************************** */
26 : :
27 : : /** \file ExtraDataUser.hpp
28 : : * \brief
29 : : * \author Jason Kraftcheck
30 : : */
31 : :
32 : : #ifndef MSQ_EXTRA_DATA_USER_HPP
33 : : #define MSQ_EXTRA_DATA_USER_HPP
34 : :
35 : : #include "Mesquite.hpp"
36 : : #include "ExtraData.hpp"
37 : : #include <assert.h>
38 : :
39 : : namespace MBMesquite
40 : : {
41 : :
42 : : template < typename T >
43 : : class ExtraUserData;
44 : :
45 : : /**\brief Manage extra data attached to PatchData instances
46 : : *
47 : : * This class manages the details of using the ExtraData mechanism
48 : : * for attaching data to and/or observing a PatchData. The template
49 : : * parameter is the type definint the data to be stored on the
50 : : * PatchData.
51 : : *
52 : : * To use this class, define a type (struct or whatever) to contain
53 : : * the data that will be stored on PatchData instances, and create
54 : : * a subclass of this class, where the template parameter for this
55 : : * class is the data type. Provide implementations of the pure
56 : : * virtual (abstract) methods for notification of changes to the PatchData.
57 : : */
58 : : template < typename T >
59 : : class ExtraDataUser
60 : : {
61 : : public:
62 : : ExtraDataUser();
63 : :
64 : : virtual ~ExtraDataUser();
65 : :
66 : : typedef T DataType;
67 : :
68 : : /** returns null if data hasn't been set via set_data */
69 : : T* get_data_ptr( PatchData& patch );
70 : :
71 : : /** creates data if doesn't exist */
72 : : T& get_data( PatchData& patch );
73 : :
74 : : void set_data( PatchData& patch, const T& data );
75 : :
76 : : void notify_patch_destroyed( ExtraUserData< T >* data );
77 : :
78 : : virtual void notify_patch_destroyed( T& data ) = 0;
79 : :
80 : : virtual void notify_new_patch( PatchData& patch, T& data ) = 0;
81 : :
82 : : virtual void notify_sub_patch( PatchData& patch, T& data, PatchData& sub_patch, const size_t* vertex_index_map,
83 : : const size_t* element_index_map, MsqError& err ) = 0;
84 : :
85 : : private:
86 : : ExtraUserData< T >* listHead;
87 : : };
88 : :
89 : : template < typename T >
90 [ - + ]: 8 : class ExtraUserData : public ExtraData
91 : : {
92 : : public:
93 : : ExtraDataUser< T >* dataOwner;
94 : : ExtraUserData< T >* userNext;
95 : : T userData;
96 : :
97 : : ExtraUserData( PatchData& patch, ExtraDataUser< T >* owner, ExtraUserData< T >* next, const T& data )
98 : : : ExtraData( patch ), dataOwner( owner ), userNext( next ), userData( data )
99 : : {
100 : : }
101 : :
102 : 2 : ExtraUserData( PatchData& patch, ExtraDataUser< T >* owner, ExtraUserData< T >* next )
103 [ + - ]: 2 : : ExtraData( patch ), dataOwner( owner ), userNext( next )
104 : : {
105 : 2 : }
106 : :
107 : : virtual void notify_patch_destroyed();
108 : :
109 : : virtual void notify_new_patch();
110 : :
111 : : virtual void notify_sub_patch( PatchData& sub_patch, const size_t* vtx_index_map, const size_t* elm_index_map,
112 : : MsqError& err );
113 : : };
114 : :
115 : : template < typename T >
116 : 2 : void ExtraUserData< T >::notify_patch_destroyed()
117 : : {
118 : 2 : dataOwner->notify_patch_destroyed( this );
119 : 2 : }
120 : :
121 : : template < typename T >
122 : 0 : void ExtraUserData< T >::notify_new_patch()
123 : : {
124 : 0 : dataOwner->notify_new_patch( *get_patch_data(), userData );
125 : 0 : }
126 : :
127 : : template < typename T >
128 : 0 : void ExtraUserData< T >::notify_sub_patch( PatchData& sub, const size_t* vertex_map, const size_t* element_map,
129 : : MsqError& err )
130 : : {
131 : 0 : dataOwner->notify_sub_patch( *get_patch_data(), userData, sub, vertex_map, element_map, err );
132 : 0 : }
133 : :
134 : : template < typename T >
135 : 9 : ExtraDataUser< T >::ExtraDataUser() : listHead( 0 )
136 : : {
137 : 9 : }
138 : :
139 : : template < typename T >
140 : 9 : ExtraDataUser< T >::~ExtraDataUser()
141 : : {
142 [ - + ]: 9 : while( ExtraUserData< T >* dead_ptr = listHead )
143 : : {
144 : 0 : listHead = dead_ptr->userNext;
145 : 0 : dead_ptr->userNext = 0;
146 [ # # ]: 0 : delete dead_ptr;
147 : 0 : }
148 [ - + ]: 18 : }
149 : :
150 : : template < typename T >
151 : 370575 : T* ExtraDataUser< T >::get_data_ptr( PatchData& patch )
152 : : {
153 [ + + ]: 370575 : for( ExtraUserData< T >* ptr = listHead; ptr; ptr = ptr->userNext )
154 [ + - ]: 370573 : if( ptr->get_patch_data() == &patch ) return &( ptr->userData );
155 : 2 : return 0;
156 : : }
157 : :
158 : : template < typename T >
159 : 370575 : T& ExtraDataUser< T >::get_data( PatchData& patch )
160 : : {
161 : 370575 : T* ptr = get_data_ptr( patch );
162 [ + + ]: 370575 : if( !ptr )
163 : : {
164 [ + - ]: 2 : listHead = new ExtraUserData< T >( patch, this, listHead );
165 : 2 : ptr = &( listHead->userData );
166 : : }
167 : 370575 : return *ptr;
168 : : }
169 : :
170 : : template < typename T >
171 : : void ExtraDataUser< T >::set_data( PatchData& patch, const T& data )
172 : : {
173 : : T* ptr = get_data_ptr( patch );
174 : : if( ptr )
175 : : *ptr = data;
176 : : else
177 : : listHead = new ExtraUserData< T >( patch, this, listHead, data );
178 : : }
179 : :
180 : : template < typename T >
181 : 2 : void ExtraDataUser< T >::notify_patch_destroyed( ExtraUserData< T >* data )
182 : : {
183 : : // remove from list
184 [ - + ]: 2 : assert( listHead != 0 );
185 [ + - ]: 2 : if( listHead == data )
186 : 2 : listHead = data->userNext;
187 : : else
188 : : {
189 : : ExtraUserData< T >* prev;
190 [ # # ]: 0 : for( prev = listHead; prev->userNext != data; prev = prev->userNext )
191 [ # # ]: 0 : assert( prev->userNext != 0 );
192 : 0 : prev->userNext = data->userNext;
193 : : }
194 : 2 : data->userNext = 0;
195 : :
196 : : // notify concrete class of event
197 : 2 : notify_patch_destroyed( data->userData );
198 : :
199 [ + - ]: 2 : delete data;
200 : 2 : }
201 : :
202 : : } // namespace MBMesquite
203 : :
204 : : #endif
|