Commenting out code from commit 22457 by Genscher for PointCache.
[blender.git] / source / blender / blenkernel / intern / property.c
1
2 /*  property.c   june 2000
3  * 
4  *  ton roosendaal
5  * $Id$
6  *
7  * ***** BEGIN GPL LICENSE BLOCK *****
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License
11  * as published by the Free Software Foundation; either version 2
12  * of the License, or (at your option) any later version.
13  *
14  * This program 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
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22  *
23  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24  * All rights reserved.
25  *
26  * The Original Code is: all of this file.
27  *
28  * Contributor(s): none yet.
29  *
30  * ***** END GPL LICENSE BLOCK *****
31  */
32
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include <ctype.h>
37
38 #ifdef HAVE_CONFIG_H
39 #include <config.h>
40 #endif
41
42 #include "MEM_guardedalloc.h"
43
44 #include "DNA_property_types.h"
45 #include "DNA_object_types.h"
46 #include "DNA_listBase.h"
47
48 #include "BLI_blenlib.h"
49 #include "BKE_property.h"
50
51 void free_property(bProperty *prop)
52 {
53         
54         if(prop->poin && prop->poin != &prop->data) MEM_freeN(prop->poin);
55         MEM_freeN(prop);
56         
57 }
58
59 void free_properties(ListBase *lb)
60 {
61         bProperty *prop;
62         
63         while( (prop= lb->first) ) {
64                 BLI_remlink(lb, prop);
65                 free_property(prop);
66         }
67 }
68
69 bProperty *copy_property(bProperty *prop)
70 {
71         bProperty *propn;
72         
73         propn= MEM_dupallocN(prop);
74         if(prop->poin && prop->poin != &prop->data) {
75                 propn->poin= MEM_dupallocN(prop->poin);
76         }
77         else propn->poin= &propn->data;
78         
79         return propn;
80 }
81
82 void copy_properties(ListBase *lbn, ListBase *lbo)
83 {
84         bProperty *prop, *propn;
85         free_properties( lbn ); /* incase we are copying to an object with props */
86         prop= lbo->first;
87         while(prop) {
88                 propn= copy_property(prop);
89                 BLI_addtail(lbn, propn);
90                 prop= prop->next;
91         }
92         
93         
94 }
95
96 void init_property(bProperty *prop)
97 {
98         /* also use when property changes type */
99         
100         if(prop->poin && prop->poin != &prop->data) MEM_freeN(prop->poin);
101         prop->poin= 0;
102         
103         prop->data= 0;
104         
105         switch(prop->type) {
106         case GPROP_BOOL:
107         case GPROP_INT:
108         case GPROP_FLOAT:
109         case GPROP_TIME:
110                 prop->poin= &prop->data;
111                 break;
112         case GPROP_STRING:
113                 prop->poin= MEM_callocN(MAX_PROPSTRING, "property string");
114                 break;
115         }
116 }
117
118
119 bProperty *new_property(int type)
120 {
121         bProperty *prop;
122
123         prop= MEM_callocN(sizeof(bProperty), "property");
124         prop->type= type;
125
126         init_property(prop);
127         
128         strcpy(prop->name, "prop");
129
130         return prop;
131 }
132
133 /* used by unique_property() only */
134 static bProperty *get_property__internal(bProperty *first, bProperty *self, const char *name)
135 {
136         bProperty *p;
137         for(p= first; p; p= p->next) {
138                 if (p!=self && (strcmp(p->name, name)==0))
139                         return p;
140         }
141         return NULL;
142 }
143 void unique_property(bProperty *first, bProperty *prop, int force)
144 {
145         bProperty *p;
146
147         /* set the first if its not set */
148         if(first==NULL) {
149                 first= prop;
150                 while(first->prev) {
151                         first= first->prev;
152                 }
153         }
154
155         if(force) {
156                 /* change other names to make them unique */
157                 while((p = get_property__internal(first, prop, prop->name))) {
158                         unique_property(first, p, 0);
159                 }
160         }else {
161                 /* change our own name until its unique */
162                 if(get_property__internal(first, prop, prop->name)) {
163                         /* there is a collision */
164                         char new_name[sizeof(prop->name)];
165                         char base_name[sizeof(prop->name)];
166                         char num[sizeof(prop->name)];
167                         int i= 0;
168
169                         /* strip numbers */
170                         strcpy(base_name, prop->name);
171                         for(i= strlen(base_name)-1; (i>=0 && isdigit(base_name[i])); i--) {
172                                 base_name[i]= '\0';
173                         }
174                         i= 0;
175
176                         do { /* ensure we have enough chars for the new number in the name */
177                                 sprintf(num, "%d", i++);
178                                 BLI_strncpy(new_name, base_name, sizeof(prop->name) - strlen(num));
179                                 strcat(new_name, num);
180                         } while(get_property__internal(first, prop, new_name));
181
182                         strcpy(prop->name, new_name);
183                 }
184         }
185 }
186
187 bProperty *get_ob_property(Object *ob, char *name)
188 {
189         bProperty *prop;
190         
191         prop= ob->prop.first;
192         while(prop) {
193                 if( strcmp(prop->name, name)==0 ) return prop;
194                 prop= prop->next;
195         }
196         return NULL;
197 }
198
199 void set_ob_property(Object *ob, bProperty *propc)
200 {
201         bProperty *prop;
202         prop= get_ob_property(ob, propc->name);
203         if(prop) {
204                 free_property(prop);
205                 BLI_remlink(&ob->prop, prop);
206         }
207         BLI_addtail(&ob->prop, copy_property(propc));
208 }
209
210 /* negative: prop is smaller
211  * positive: prop is larger
212  */
213 int compare_property(bProperty *prop, char *str)
214 {
215 //      extern int Gdfra;               /* sector.c */
216         float fvalue, ftest;
217         
218         switch(prop->type) {
219         case GPROP_BOOL:
220                 if(BLI_strcasecmp(str, "true")==0) {
221                         if(prop->data==1) return 0;
222                         else return 1;
223                 }
224                 else if(BLI_strcasecmp(str, "false")==0) {
225                         if(prop->data==0) return 0;
226                         else return 1;
227                 }
228                 /* no break, do GPROP_int too! */
229                 
230         case GPROP_INT:
231                 return prop->data - atoi(str);
232
233         case GPROP_FLOAT:
234         case GPROP_TIME:
235                 // WARNING: untested for GPROP_TIME
236                 // function isn't used currently
237                 fvalue= *((float *)&prop->data);
238                 ftest= (float)atof(str);
239                 if( fvalue > ftest) return 1;
240                 else if( fvalue < ftest) return -1;
241                 return 0;
242
243         case GPROP_STRING:
244                 return strcmp(prop->poin, str);
245         }
246         
247         return 0;
248 }
249
250 void set_property(bProperty *prop, char *str)
251 {
252 //      extern int Gdfra;               /* sector.c */
253
254         switch(prop->type) {
255         case GPROP_BOOL:
256                 if(BLI_strcasecmp(str, "true")==0) prop->data= 1;
257                 else if(BLI_strcasecmp(str, "false")==0) prop->data= 0;
258                 else prop->data= (atoi(str)!=0);
259                 break;
260         case GPROP_INT:
261                 prop->data= atoi(str);
262                 break;
263         case GPROP_FLOAT:
264         case GPROP_TIME:
265                 *((float *)&prop->data)= (float)atof(str);
266                 break;
267         case GPROP_STRING:
268                 strcpy(prop->poin, str);
269                 break;
270         }
271         
272 }
273
274 void add_property(bProperty *prop, char *str)
275 {
276 //      extern int Gdfra;               /* sector.c */
277
278         switch(prop->type) {
279         case GPROP_BOOL:
280         case GPROP_INT:
281                 prop->data+= atoi(str);
282                 break;
283         case GPROP_FLOAT:
284         case GPROP_TIME:
285                 *((float *)&prop->data)+= (float)atof(str);
286                 break;
287         case GPROP_STRING:
288                 /* strcpy(prop->poin, str); */
289                 break;
290         }
291 }
292
293 /* reads value of property, sets it in chars in str */
294 void set_property_valstr(bProperty *prop, char *str)
295 {
296 //      extern int Gdfra;               /* sector.c */
297
298         if(str == NULL) return;
299
300         switch(prop->type) {
301         case GPROP_BOOL:
302         case GPROP_INT:
303                 sprintf(str, "%d", prop->data);
304                 break;
305         case GPROP_FLOAT:
306         case GPROP_TIME:
307                 sprintf(str, "%f", *((float *)&prop->data));
308                 break;
309         case GPROP_STRING:
310                 BLI_strncpy(str, prop->poin, MAX_PROPSTRING);
311                 break;
312         }
313 }
314
315 void cp_property(bProperty *prop1, bProperty *prop2)
316 {
317         char str[128];
318
319         set_property_valstr(prop2, str);
320
321         set_property(prop1, str);
322 }