|
Blender
V2.59
|
00001 00002 /* property.c june 2000 00003 * 00004 * ton roosendaal 00005 * $Id: property.c 35247 2011-02-27 20:40:57Z jesterking $ 00006 * 00007 * ***** BEGIN GPL LICENSE BLOCK ***** 00008 * 00009 * This program is free software; you can redistribute it and/or 00010 * modify it under the terms of the GNU General Public License 00011 * as published by the Free Software Foundation; either version 2 00012 * of the License, or (at your option) any later version. 00013 * 00014 * This program 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 00017 * GNU General Public License for more details. 00018 * 00019 * You should have received a copy of the GNU General Public License 00020 * along with this program; if not, write to the Free Software Foundation, 00021 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00022 * 00023 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. 00024 * All rights reserved. 00025 * 00026 * The Original Code is: all of this file. 00027 * 00028 * Contributor(s): none yet. 00029 * 00030 * ***** END GPL LICENSE BLOCK ***** 00031 */ 00032 00038 #include <stdio.h> 00039 #include <stdlib.h> 00040 #include <stddef.h> 00041 #include <string.h> 00042 #include <ctype.h> 00043 00044 #include "MEM_guardedalloc.h" 00045 00046 #include "DNA_property_types.h" 00047 #include "DNA_object_types.h" 00048 00049 #include "BLI_blenlib.h" 00050 00051 #include "BKE_property.h" 00052 00053 void free_property(bProperty *prop) 00054 { 00055 00056 if(prop->poin && prop->poin != &prop->data) MEM_freeN(prop->poin); 00057 MEM_freeN(prop); 00058 00059 } 00060 00061 void free_properties(ListBase *lb) 00062 { 00063 bProperty *prop; 00064 00065 while( (prop= lb->first) ) { 00066 BLI_remlink(lb, prop); 00067 free_property(prop); 00068 } 00069 } 00070 00071 bProperty *copy_property(bProperty *prop) 00072 { 00073 bProperty *propn; 00074 00075 propn= MEM_dupallocN(prop); 00076 if(prop->poin && prop->poin != &prop->data) { 00077 propn->poin= MEM_dupallocN(prop->poin); 00078 } 00079 else propn->poin= &propn->data; 00080 00081 return propn; 00082 } 00083 00084 void copy_properties(ListBase *lbn, ListBase *lbo) 00085 { 00086 bProperty *prop, *propn; 00087 free_properties( lbn ); /* incase we are copying to an object with props */ 00088 prop= lbo->first; 00089 while(prop) { 00090 propn= copy_property(prop); 00091 BLI_addtail(lbn, propn); 00092 prop= prop->next; 00093 } 00094 00095 00096 } 00097 00098 void init_property(bProperty *prop) 00099 { 00100 /* also use when property changes type */ 00101 00102 if(prop->poin && prop->poin != &prop->data) MEM_freeN(prop->poin); 00103 prop->poin= NULL; 00104 00105 prop->data= 0; 00106 00107 switch(prop->type) { 00108 case GPROP_BOOL: 00109 case GPROP_INT: 00110 case GPROP_FLOAT: 00111 case GPROP_TIME: 00112 prop->poin= &prop->data; 00113 break; 00114 case GPROP_STRING: 00115 prop->poin= MEM_callocN(MAX_PROPSTRING, "property string"); 00116 break; 00117 } 00118 } 00119 00120 00121 bProperty *new_property(int type) 00122 { 00123 bProperty *prop; 00124 00125 prop= MEM_callocN(sizeof(bProperty), "property"); 00126 prop->type= type; 00127 00128 init_property(prop); 00129 00130 strcpy(prop->name, "prop"); 00131 00132 return prop; 00133 } 00134 00135 /* used by unique_property() only */ 00136 static bProperty *get_property__internal(bProperty *first, bProperty *self, const char *name) 00137 { 00138 bProperty *p; 00139 for(p= first; p; p= p->next) { 00140 if (p!=self && (strcmp(p->name, name)==0)) 00141 return p; 00142 } 00143 return NULL; 00144 } 00145 void unique_property(bProperty *first, bProperty *prop, int force) 00146 { 00147 bProperty *p; 00148 00149 /* set the first if its not set */ 00150 if(first==NULL) { 00151 first= prop; 00152 while(first->prev) { 00153 first= first->prev; 00154 } 00155 } 00156 00157 if(force) { 00158 /* change other names to make them unique */ 00159 while((p = get_property__internal(first, prop, prop->name))) { 00160 unique_property(first, p, 0); 00161 } 00162 }else { 00163 /* change our own name until its unique */ 00164 if(get_property__internal(first, prop, prop->name)) { 00165 /* there is a collision */ 00166 char new_name[sizeof(prop->name)]; 00167 char base_name[sizeof(prop->name)]; 00168 char num[sizeof(prop->name)]; 00169 int i= 0; 00170 00171 /* strip numbers */ 00172 strcpy(base_name, prop->name); 00173 for(i= strlen(base_name)-1; (i>=0 && isdigit(base_name[i])); i--) { 00174 base_name[i]= '\0'; 00175 } 00176 i= 0; 00177 00178 do { /* ensure we have enough chars for the new number in the name */ 00179 sprintf(num, "%d", i++); 00180 BLI_strncpy(new_name, base_name, sizeof(prop->name) - strlen(num)); 00181 strcat(new_name, num); 00182 } while(get_property__internal(first, prop, new_name)); 00183 00184 strcpy(prop->name, new_name); 00185 } 00186 } 00187 } 00188 00189 bProperty *get_ob_property(Object *ob, const char *name) 00190 { 00191 return BLI_findstring(&ob->prop, name, offsetof(bProperty, name)); 00192 } 00193 00194 void set_ob_property(Object *ob, bProperty *propc) 00195 { 00196 bProperty *prop; 00197 prop= get_ob_property(ob, propc->name); 00198 if(prop) { 00199 free_property(prop); 00200 BLI_remlink(&ob->prop, prop); 00201 } 00202 BLI_addtail(&ob->prop, copy_property(propc)); 00203 } 00204 00205 /* negative: prop is smaller 00206 * positive: prop is larger 00207 */ 00208 int compare_property(bProperty *prop, char *str) 00209 { 00210 // extern int Gdfra; /* sector.c */ 00211 float fvalue, ftest; 00212 00213 switch(prop->type) { 00214 case GPROP_BOOL: 00215 if(BLI_strcasecmp(str, "true")==0) { 00216 if(prop->data==1) return 0; 00217 else return 1; 00218 } 00219 else if(BLI_strcasecmp(str, "false")==0) { 00220 if(prop->data==0) return 0; 00221 else return 1; 00222 } 00223 /* no break, do GPROP_int too! */ 00224 00225 case GPROP_INT: 00226 return prop->data - atoi(str); 00227 00228 case GPROP_FLOAT: 00229 case GPROP_TIME: 00230 // WARNING: untested for GPROP_TIME 00231 // function isn't used currently 00232 fvalue= *((float *)&prop->data); 00233 ftest= (float)atof(str); 00234 if( fvalue > ftest) return 1; 00235 else if( fvalue < ftest) return -1; 00236 return 0; 00237 00238 case GPROP_STRING: 00239 return strcmp(prop->poin, str); 00240 } 00241 00242 return 0; 00243 } 00244 00245 void set_property(bProperty *prop, char *str) 00246 { 00247 // extern int Gdfra; /* sector.c */ 00248 00249 switch(prop->type) { 00250 case GPROP_BOOL: 00251 if(BLI_strcasecmp(str, "true")==0) prop->data= 1; 00252 else if(BLI_strcasecmp(str, "false")==0) prop->data= 0; 00253 else prop->data= (atoi(str)!=0); 00254 break; 00255 case GPROP_INT: 00256 prop->data= atoi(str); 00257 break; 00258 case GPROP_FLOAT: 00259 case GPROP_TIME: 00260 *((float *)&prop->data)= (float)atof(str); 00261 break; 00262 case GPROP_STRING: 00263 strcpy(prop->poin, str); 00264 break; 00265 } 00266 00267 } 00268 00269 void add_property(bProperty *prop, char *str) 00270 { 00271 // extern int Gdfra; /* sector.c */ 00272 00273 switch(prop->type) { 00274 case GPROP_BOOL: 00275 case GPROP_INT: 00276 prop->data+= atoi(str); 00277 break; 00278 case GPROP_FLOAT: 00279 case GPROP_TIME: 00280 *((float *)&prop->data)+= (float)atof(str); 00281 break; 00282 case GPROP_STRING: 00283 /* strcpy(prop->poin, str); */ 00284 break; 00285 } 00286 } 00287 00288 /* reads value of property, sets it in chars in str */ 00289 void set_property_valstr(bProperty *prop, char *str) 00290 { 00291 // extern int Gdfra; /* sector.c */ 00292 00293 if(str == NULL) return; 00294 00295 switch(prop->type) { 00296 case GPROP_BOOL: 00297 case GPROP_INT: 00298 sprintf(str, "%d", prop->data); 00299 break; 00300 case GPROP_FLOAT: 00301 case GPROP_TIME: 00302 sprintf(str, "%f", *((float *)&prop->data)); 00303 break; 00304 case GPROP_STRING: 00305 BLI_strncpy(str, prop->poin, MAX_PROPSTRING); 00306 break; 00307 } 00308 } 00309 00310 void cp_property(bProperty *prop1, bProperty *prop2) 00311 { 00312 char str[128]; 00313 00314 set_property_valstr(prop2, str); 00315 00316 set_property(prop1, str); 00317 }