use gcc attrubutes to warn on unused return values and arguments which shouldnt be...
[blender.git] / source / blender / blenkernel / BKE_idprop.h
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19  * All rights reserved.
20  *
21  * Contributor(s): Joseph Eagar
22  *
23  * ***** END GPL LICENSE BLOCK *****
24  */
25  
26 #ifndef __BKE_IDPROP_H__
27 #define __BKE_IDPROP_H__
28
29 /** \file BKE_idprop.h
30  *  \ingroup bke
31  *  \author Joseph Eagar
32  */
33
34 #include "DNA_ID.h"
35
36 struct IDProperty;
37 struct ID;
38
39 typedef union IDPropertyTemplate {
40         int i;
41         float f;
42         double d;
43         struct {
44                 char *str;
45                 short len;
46                 char subtype;
47         } string;
48         struct ID *id;
49         struct {
50                 short type;
51                 short len;
52         } array;
53         struct {
54                 int matvec_size;
55                 float *example;
56         } matrix_or_vector;
57 } IDPropertyTemplate;
58
59 /* ----------- Property Array Type ---------- */
60
61 /* note: as a start to move away from the stupid IDP_New function, this type
62  * has it's own allocation function.*/
63 IDProperty *IDP_NewIDPArray(const char *name)
64 #ifdef __GNUC__
65 __attribute__((warn_unused_result))
66 __attribute__((nonnull))
67 #endif
68 ;
69 IDProperty *IDP_CopyIDPArray(IDProperty *array)
70 #ifdef __GNUC__
71 __attribute__((warn_unused_result))
72 __attribute__((nonnull))
73 #endif
74 ;
75
76 void IDP_FreeIDPArray(IDProperty *prop);
77
78 /* shallow copies item */
79 void IDP_SetIndexArray(struct IDProperty *prop, int index, struct IDProperty *item);
80 struct IDProperty *IDP_GetIndexArray(struct IDProperty *prop, int index)
81 #ifdef __GNUC__
82 __attribute__((warn_unused_result))
83 __attribute__((nonnull))
84 #endif
85 ;
86 void IDP_AppendArray(struct IDProperty *prop, struct IDProperty *item);
87 void IDP_ResizeIDPArray(struct IDProperty *prop, int len);
88
89 /* ----------- Numeric Array Type ----------- */
90 /*this function works for strings too!*/
91 void IDP_ResizeArray(struct IDProperty *prop, int newlen);
92 void IDP_FreeArray(struct IDProperty *prop);
93
94 /* ---------- String Type ------------ */
95 IDProperty *IDP_NewString(const char *st, const char *name, int maxlen) /* maxlen excludes '\0' */
96 #ifdef __GNUC__
97 __attribute__((warn_unused_result))
98 __attribute__((nonnull))
99 #endif
100 ;
101
102 void IDP_AssignString(struct IDProperty *prop, const char *st, int maxlen) /* maxlen excludes '\0' */
103 #ifdef __GNUC__
104 __attribute__((nonnull))
105 #endif
106 ;
107 void IDP_ConcatStringC(struct IDProperty *prop, const char *st)
108 #ifdef __GNUC__
109 __attribute__((nonnull))
110 #endif
111 ;
112 void IDP_ConcatString(struct IDProperty *str1, struct IDProperty *append)
113 #ifdef __GNUC__
114 __attribute__((nonnull))
115 #endif
116 ;
117 void IDP_FreeString(struct IDProperty *prop)
118 #ifdef __GNUC__
119 __attribute__((nonnull))
120 #endif
121 ;
122
123 /*-------- ID Type -------*/
124 void IDP_LinkID(struct IDProperty *prop, ID *id);
125 void IDP_UnlinkID(struct IDProperty *prop);
126
127 /*-------- Group Functions -------*/
128
129 /** Sync values from one group to another, only where they match */
130 void IDP_SyncGroupValues(struct IDProperty *dest, struct IDProperty *src)
131 #ifdef __GNUC__
132 __attribute__((nonnull))
133 #endif
134 ;
135
136 /**
137  * replaces all properties with the same name in a destination group from a source group.
138  */
139 void IDP_ReplaceGroupInGroup(struct IDProperty *dest, struct IDProperty *src)
140 #ifdef __GNUC__
141 __attribute__((nonnull))
142 #endif
143 ;
144
145 /**
146  * Checks if a property with the same name as prop exists, and if so replaces it.
147  * Use this to preserve order!*/
148 void IDP_ReplaceInGroup(struct IDProperty *group, struct IDProperty *prop)
149 #ifdef __GNUC__
150 __attribute__((nonnull))
151 #endif
152 ;
153
154 /**
155  * This function has a sanity check to make sure ID properties with the same name don't
156  * get added to the group.
157  * 
158  * The sanity check just means the property is not added to the group if another property
159  * exists with the same name; the client code using ID properties then needs to detect this 
160  * (the function that adds new properties to groups, IDP_AddToGroup, returns 0 if a property can't
161  * be added to the group, and 1 if it can) and free the property.
162  * 
163  * Currently the code to free ID properties is designed to leave the actual struct
164  * you pass it un-freed, this is needed for how the system works.  This means
165  * to free an ID property, you first call IDP_FreeProperty then MEM_freeN the
166  * struct.  In the future this will just be IDP_FreeProperty and the code will
167  * be reorganized to work properly.
168  */
169 int IDP_AddToGroup(struct IDProperty *group, struct IDProperty *prop)
170 #ifdef __GNUC__
171 __attribute__((nonnull))
172 #endif
173 ;
174
175 /** this is the same as IDP_AddToGroup, only you pass an item
176  * in the group list to be inserted after. */
177 int IDP_InsertToGroup(struct IDProperty *group, struct IDProperty *previous, 
178                       struct IDProperty *pnew)
179 #ifdef __GNUC__
180 __attribute__((nonnull))
181 #endif
182 ;
183
184 /** \note this does not free the property!!
185  *
186  * To free the property, you have to do:
187  * IDP_FreeProperty(prop); //free all subdata
188  * MEM_freeN(prop); //free property struct itself
189  */
190 void IDP_RemFromGroup(struct IDProperty *group, struct IDProperty *prop)
191 #ifdef __GNUC__
192 __attribute__((nonnull))
193 #endif
194 ;
195
196 IDProperty *IDP_GetPropertyFromGroup(struct IDProperty *prop, const char *name)
197 #ifdef __GNUC__
198 __attribute__((warn_unused_result))
199 __attribute__((nonnull))
200 #endif
201 ;
202 /** same as above but ensure type match */
203 IDProperty *IDP_GetPropertyTypeFromGroup(struct IDProperty *prop, const char *name, const char type)
204 #ifdef __GNUC__
205 __attribute__((warn_unused_result))
206 __attribute__((nonnull))
207 #endif
208 ;
209
210 /**
211  * Get an iterator to iterate over the members of an id property group.
212  * Note that this will automatically free the iterator once iteration is complete;
213  * if you stop the iteration before hitting the end, make sure to call
214  * IDP_FreeIterBeforeEnd(). */
215 void *IDP_GetGroupIterator(struct IDProperty *prop)
216 #ifdef __GNUC__
217 __attribute__((warn_unused_result))
218 #endif
219 ;
220
221 /**
222  * Returns the next item in the iteration.  To use, simple for a loop like the following:
223  * while (IDP_GroupIterNext(iter) != NULL) {
224  *     ...
225  * }
226  */
227 IDProperty *IDP_GroupIterNext(void *vself)
228 #ifdef __GNUC__
229 __attribute__((warn_unused_result))
230 __attribute__((nonnull))
231 #endif
232 ;
233
234 /**
235  * Frees the iterator pointed to at vself, only use this if iteration is stopped early; 
236  * when the iterator hits the end of the list it'll automatically free itself.*/
237 void IDP_FreeIterBeforeEnd(void *vself)
238 #ifdef __GNUC__
239 __attribute__((nonnull))
240 #endif
241 ;
242
243 /*-------- Main Functions --------*/
244 /** Get the Group property that contains the id properties for ID id.  Set create_if_needed
245  * to create the Group property and attach it to id if it doesn't exist; otherwise
246  * the function will return NULL if there's no Group property attached to the ID.*/
247 struct IDProperty *IDP_GetProperties(struct ID *id, int create_if_needed)
248 #ifdef __GNUC__
249 __attribute__((warn_unused_result))
250 __attribute__((nonnull))
251 #endif
252 ;
253 struct IDProperty *IDP_CopyProperty(struct IDProperty *prop)
254 #ifdef __GNUC__
255 __attribute__((warn_unused_result))
256 __attribute__((nonnull))
257 #endif
258 ;
259
260 int IDP_EqualsProperties(struct IDProperty *prop1, struct IDProperty *prop2)
261 #ifdef __GNUC__
262 __attribute__((warn_unused_result))
263 __attribute__((nonnull))
264 #endif
265 ;
266
267 /**
268  * Allocate a new ID.
269  *
270  * This function takes three arguments: the ID property type, a union which defines
271  * it's initial value, and a name.
272  *
273  * The union is simple to use; see the top of this header file for its definition. 
274  * An example of using this function:
275  *
276  *     IDPropertyTemplate val;
277  *     IDProperty *group, *idgroup, *color;
278  *     group = IDP_New(IDP_GROUP, val, "group1"); //groups don't need a template.
279  *    
280  *     val.array.len = 4
281  *     val.array.type = IDP_FLOAT;
282  *     color = IDP_New(IDP_ARRAY, val, "color1");
283  *    
284  *     idgroup = IDP_GetProperties(some_id, 1);
285  *     IDP_AddToGroup(idgroup, color);
286  *     IDP_AddToGroup(idgroup, group);
287  * 
288  * Note that you MUST either attach the id property to an id property group with 
289  * IDP_AddToGroup or MEM_freeN the property, doing anything else might result in
290  * a memory leak.
291  */
292 struct IDProperty *IDP_New(const int type, const IDPropertyTemplate *val, const char *name)
293 #ifdef __GNUC__
294 __attribute__((warn_unused_result))
295 __attribute__((nonnull))
296 #endif
297 ;
298
299 /** \note this will free all child properties of list arrays and groups!
300  * Also, note that this does NOT unlink anything!  Plus it doesn't free
301  * the actual struct IDProperty struct either.*/
302 void IDP_FreeProperty(struct IDProperty *prop);
303
304 /** Unlinks any struct IDProperty<->ID linkage that might be going on.*/
305 void IDP_UnlinkProperty(struct IDProperty *prop);
306
307 #define IDP_Int(prop) ((prop)->data.val)
308 #define IDP_Float(prop) (*(float *)&(prop)->data.val)
309 #define IDP_String(prop) ((char *)(prop)->data.pointer)
310 #define IDP_Array(prop) ((prop)->data.pointer)
311 #define IDP_IDPArray(prop) ((IDProperty *)(prop)->data.pointer)
312 #define IDP_Double(prop) (*(double *)&(prop)->data.val)
313
314 #endif /* __BKE_IDPROP_H__ */