2006-11-29 23:31:46 +00:00
|
|
|
/**
|
|
|
|
* $Id: idprop.c
|
|
|
|
*
|
2008-01-07 19:13:47 +00:00
|
|
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
2006-11-29 23:31:46 +00:00
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
2008-01-07 19:13:47 +00:00
|
|
|
* of the License, or (at your option) any later version.
|
2006-11-29 23:31:46 +00:00
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software Foundation,
|
2010-02-12 13:34:04 +00:00
|
|
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
2006-11-29 23:31:46 +00:00
|
|
|
*
|
|
|
|
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* Contributor(s): Joseph Eagar
|
|
|
|
*
|
2008-01-07 19:13:47 +00:00
|
|
|
* ***** END GPL LICENSE BLOCK *****
|
2006-11-29 23:31:46 +00:00
|
|
|
*/
|
|
|
|
|
2007-12-24 18:38:03 +00:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
2006-11-17 04:46:48 +00:00
|
|
|
#include "DNA_listBase.h"
|
|
|
|
#include "DNA_ID.h"
|
|
|
|
|
|
|
|
#include "BKE_idprop.h"
|
|
|
|
#include "BKE_global.h"
|
|
|
|
#include "BKE_library.h"
|
|
|
|
#include "BKE_utildefines.h"
|
|
|
|
|
|
|
|
#include "BLI_blenlib.h"
|
|
|
|
|
|
|
|
#include "MEM_guardedalloc.h"
|
|
|
|
|
2006-11-17 08:19:58 +00:00
|
|
|
#define BSTR_EQ(a, b) (*(a) == *(b) && !strcmp(a, b))
|
|
|
|
|
2006-11-17 04:46:48 +00:00
|
|
|
/* IDPropertyTemplate is a union in DNA_ID.h */
|
2007-04-19 22:49:48 +00:00
|
|
|
|
|
|
|
/*local size table.*/
|
2006-11-17 04:46:48 +00:00
|
|
|
static char idp_size_table[] = {
|
2007-04-19 22:49:48 +00:00
|
|
|
1, /*strings*/
|
2006-11-17 04:46:48 +00:00
|
|
|
sizeof(int),
|
|
|
|
sizeof(float),
|
2007-05-22 04:41:21 +00:00
|
|
|
sizeof(float)*3, /*Vector type, deprecated*/
|
|
|
|
sizeof(float)*16, /*Matrix type, deprecated*/
|
2007-04-19 22:49:48 +00:00
|
|
|
0, /*arrays don't have a fixed size*/
|
2006-11-17 04:46:48 +00:00
|
|
|
sizeof(ListBase), /*Group type*/
|
2008-07-24 19:22:17 +00:00
|
|
|
sizeof(void*),
|
|
|
|
sizeof(double)
|
2006-11-17 04:46:48 +00:00
|
|
|
};
|
|
|
|
|
2008-12-31 13:16:37 +00:00
|
|
|
/* ------------Property Array Type ----------- */
|
|
|
|
#define GETPROP(prop, i) (((IDProperty*)(prop)->data.pointer)+(i))
|
2006-11-17 04:46:48 +00:00
|
|
|
|
2008-12-31 13:16:37 +00:00
|
|
|
/* --------- property array type -------------*/
|
2006-11-17 04:46:48 +00:00
|
|
|
|
2008-12-31 13:16:37 +00:00
|
|
|
/*note: as a start to move away from the stupid IDP_New function, this type
|
|
|
|
has it's own allocation function.*/
|
|
|
|
IDProperty *IDP_NewIDPArray(const char *name)
|
|
|
|
{
|
|
|
|
IDProperty *prop = MEM_callocN(sizeof(IDProperty), "IDProperty prop array");
|
|
|
|
prop->type = IDP_IDPARRAY;
|
|
|
|
prop->len = 0;
|
|
|
|
BLI_strncpy(prop->name, name, MAX_IDPROP_NAME);
|
|
|
|
|
|
|
|
return prop;
|
|
|
|
}
|
|
|
|
|
|
|
|
IDProperty *IDP_CopyIDPArray(IDProperty *array)
|
|
|
|
{
|
|
|
|
IDProperty *narray = MEM_dupallocN(array), *tmp;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
narray->data.pointer = MEM_dupallocN(array->data.pointer);
|
|
|
|
for (i=0; i<narray->len; i++) {
|
|
|
|
/*ok, the copy functions always allocate a new structure,
|
|
|
|
which doesn't work here. instead, simply copy the
|
|
|
|
contents of the new structure into the array cell,
|
|
|
|
then free it. this makes for more maintainable
|
|
|
|
code than simply reimplementing the copy functions
|
|
|
|
in this loop.*/
|
|
|
|
tmp = IDP_CopyProperty(GETPROP(narray, i));
|
|
|
|
memcpy(GETPROP(narray, i), tmp, sizeof(IDProperty));
|
|
|
|
MEM_freeN(tmp);
|
|
|
|
}
|
|
|
|
|
|
|
|
return narray;
|
|
|
|
}
|
|
|
|
|
|
|
|
void IDP_FreeIDPArray(IDProperty *prop)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i=0; i<prop->len; i++)
|
|
|
|
IDP_FreeProperty(GETPROP(prop, i));
|
|
|
|
|
|
|
|
if(prop->data.pointer)
|
|
|
|
MEM_freeN(prop->data.pointer);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*shallow copies item*/
|
|
|
|
void IDP_SetIndexArray(IDProperty *prop, int index, IDProperty *item)
|
|
|
|
{
|
|
|
|
IDProperty *old = GETPROP(prop, index);
|
|
|
|
if (index >= prop->len || index < 0) return;
|
|
|
|
if (item != old) IDP_FreeProperty(old);
|
|
|
|
|
|
|
|
memcpy(GETPROP(prop, index), item, sizeof(IDProperty));
|
|
|
|
}
|
|
|
|
|
|
|
|
IDProperty *IDP_GetIndexArray(IDProperty *prop, int index)
|
|
|
|
{
|
|
|
|
return GETPROP(prop, index);
|
|
|
|
}
|
|
|
|
|
|
|
|
IDProperty *IDP_AppendArray(IDProperty *prop, IDProperty *item)
|
|
|
|
{
|
|
|
|
IDP_ResizeIDPArray(prop, prop->len+1);
|
|
|
|
IDP_SetIndexArray(prop, prop->len-1, item);
|
|
|
|
return item;
|
|
|
|
}
|
|
|
|
|
|
|
|
void IDP_ResizeIDPArray(IDProperty *prop, int newlen)
|
|
|
|
{
|
|
|
|
void *newarr;
|
|
|
|
int newsize=newlen;
|
|
|
|
|
|
|
|
/*first check if the array buffer size has room*/
|
|
|
|
/*if newlen is 200 chars less then totallen, reallocate anyway*/
|
|
|
|
if (newlen <= prop->totallen && prop->totallen - newlen < 200) {
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for(i=newlen; i<prop->len; i++)
|
|
|
|
IDP_FreeProperty(GETPROP(prop, i));
|
|
|
|
|
|
|
|
prop->len = newlen;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* - Note: This code comes from python, here's the corrusponding comment. - */
|
|
|
|
/* This over-allocates proportional to the list size, making room
|
|
|
|
* for additional growth. The over-allocation is mild, but is
|
|
|
|
* enough to give linear-time amortized behavior over a long
|
|
|
|
* sequence of appends() in the presence of a poorly-performing
|
|
|
|
* system realloc().
|
|
|
|
* The growth pattern is: 0, 4, 8, 16, 25, 35, 46, 58, 72, 88, ...
|
|
|
|
*/
|
|
|
|
newsize = (newsize >> 3) + (newsize < 9 ? 3 : 6) + newsize;
|
|
|
|
|
|
|
|
newarr = MEM_callocN(sizeof(IDProperty)*newsize, "idproperty array resized");
|
|
|
|
if (newlen >= prop->len) {
|
|
|
|
/* newlen is bigger*/
|
|
|
|
memcpy(newarr, prop->data.pointer, prop->len*sizeof(IDProperty));
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
int i;
|
|
|
|
/* newlen is smaller*/
|
|
|
|
for (i=newlen; i<prop->len; i++) {
|
|
|
|
IDP_FreeProperty(GETPROP(prop, i));
|
|
|
|
}
|
2.5: RNA, defining enums, pointers and collections properties is now
possible from python, but it's still work in progress.
Pointers and collections are restricted to types derived from
IDPropertyGroup (same as for operators), because RNA knows how to
allocate/deallocate those.
Collections have .add() and .remove(number) functions that can be
used. The remove function should be fixed to take an other argument
than a number.
With the IDPropertyGroup restriction, pointers are more like nested
structs. They don't have add(), remove() yet, not sure where to put
them. Currently the pointer / nested struct is automatically allocated
in the get() function, this needs to be fixed, rule is that RNA get()
will not change any data for thread safety.
Also, it is only possible to add properties to structs after they have
been registered, which needs to be improved as well.
Example code:
http://www.pasteall.org/7201/python
2009-08-18 01:29:25 +00:00
|
|
|
memcpy(newarr, prop->data.pointer, newlen*sizeof(IDProperty));
|
2008-12-31 13:16:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if(prop->data.pointer)
|
|
|
|
MEM_freeN(prop->data.pointer);
|
|
|
|
prop->data.pointer = newarr;
|
|
|
|
prop->len = newlen;
|
|
|
|
prop->totallen = newsize;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ----------- Numerical Array Type ----------- */
|
RNA:
* Added support for using pointers + collections as operator properties,
but with the restriction that they must point to other type derived from
ID property groups. The "add" function for these properties will allocate
a new ID property group and point to that.
* Added support for arrays with type IDP_GROUP in ID properties.
* Fix bug getting/setting float array values.
Example code for collections, note the "OperatorMousePath" type is defined
in rna_wm.c and has a float[2] property named "loc".
Defining the operator property:
prop= RNA_def_property(ot->srna, "path", PROP_COLLECTION, PROP_NONE);
RNA_def_property_struct_runtime(prop, &RNA_OperatorMousePath);
Adding values:
PointerRNA itemptr;
float loc[2] = {1, 1},
RNA_collection_add(op->ptr, "path", &itemptr);
RNA_float_set_array(&itemptr, "loc", loc);
Iterating:
RNA_BEGIN(op->ptr, itemptr, "path") {
float loc[2];
RNA_float_get_array(&itemptr, "loc", loc);
printf("Location: %f %f\n", loc[0], loc[1]);
}
RNA_END;
2008-12-26 20:38:52 +00:00
|
|
|
static void idp_resize_group_array(IDProperty *prop, int newlen, void *newarr)
|
|
|
|
{
|
|
|
|
if(prop->subtype != IDP_GROUP)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if(newlen >= prop->len) {
|
|
|
|
/* bigger */
|
|
|
|
IDProperty **array= newarr;
|
|
|
|
IDPropertyTemplate val;
|
|
|
|
int a;
|
|
|
|
|
|
|
|
for(a=prop->len; a<newlen; a++) {
|
|
|
|
val.i = 0; /* silence MSVC warning about uninitialized var when debugging */
|
|
|
|
array[a]= IDP_New(IDP_GROUP, val, "IDP_ResizeArray group");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* smaller */
|
|
|
|
IDProperty **array= prop->data.pointer;
|
|
|
|
int a;
|
|
|
|
|
|
|
|
for(a=newlen; a<prop->len; a++) {
|
|
|
|
IDP_FreeProperty(array[a]);
|
|
|
|
MEM_freeN(array[a]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-11-17 04:46:48 +00:00
|
|
|
/*this function works for strings too!*/
|
|
|
|
void IDP_ResizeArray(IDProperty *prop, int newlen)
|
|
|
|
{
|
|
|
|
void *newarr;
|
|
|
|
int newsize=newlen;
|
|
|
|
|
|
|
|
/*first check if the array buffer size has room*/
|
|
|
|
/*if newlen is 200 chars less then totallen, reallocate anyway*/
|
|
|
|
if (newlen <= prop->totallen && prop->totallen - newlen < 200) {
|
2009-01-23 20:36:47 +00:00
|
|
|
idp_resize_group_array(prop, newlen, prop->data.pointer);
|
2006-11-17 04:46:48 +00:00
|
|
|
prop->len = newlen;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* - Note: This code comes from python, here's the corrusponding comment. - */
|
|
|
|
/* This over-allocates proportional to the list size, making room
|
|
|
|
* for additional growth. The over-allocation is mild, but is
|
|
|
|
* enough to give linear-time amortized behavior over a long
|
|
|
|
* sequence of appends() in the presence of a poorly-performing
|
|
|
|
* system realloc().
|
|
|
|
* The growth pattern is: 0, 4, 8, 16, 25, 35, 46, 58, 72, 88, ...
|
|
|
|
*/
|
|
|
|
newsize = (newsize >> 3) + (newsize < 9 ? 3 : 6) + newsize;
|
|
|
|
|
2009-06-22 18:19:18 +00:00
|
|
|
newarr = MEM_callocN(idp_size_table[(int)prop->subtype]*newsize, "idproperty array resized");
|
RNA:
* Added support for using pointers + collections as operator properties,
but with the restriction that they must point to other type derived from
ID property groups. The "add" function for these properties will allocate
a new ID property group and point to that.
* Added support for arrays with type IDP_GROUP in ID properties.
* Fix bug getting/setting float array values.
Example code for collections, note the "OperatorMousePath" type is defined
in rna_wm.c and has a float[2] property named "loc".
Defining the operator property:
prop= RNA_def_property(ot->srna, "path", PROP_COLLECTION, PROP_NONE);
RNA_def_property_struct_runtime(prop, &RNA_OperatorMousePath);
Adding values:
PointerRNA itemptr;
float loc[2] = {1, 1},
RNA_collection_add(op->ptr, "path", &itemptr);
RNA_float_set_array(&itemptr, "loc", loc);
Iterating:
RNA_BEGIN(op->ptr, itemptr, "path") {
float loc[2];
RNA_float_get_array(&itemptr, "loc", loc);
printf("Location: %f %f\n", loc[0], loc[1]);
}
RNA_END;
2008-12-26 20:38:52 +00:00
|
|
|
if (newlen >= prop->len) {
|
|
|
|
/* newlen is bigger*/
|
2009-06-22 18:19:18 +00:00
|
|
|
memcpy(newarr, prop->data.pointer, prop->len*idp_size_table[(int)prop->subtype]);
|
RNA:
* Added support for using pointers + collections as operator properties,
but with the restriction that they must point to other type derived from
ID property groups. The "add" function for these properties will allocate
a new ID property group and point to that.
* Added support for arrays with type IDP_GROUP in ID properties.
* Fix bug getting/setting float array values.
Example code for collections, note the "OperatorMousePath" type is defined
in rna_wm.c and has a float[2] property named "loc".
Defining the operator property:
prop= RNA_def_property(ot->srna, "path", PROP_COLLECTION, PROP_NONE);
RNA_def_property_struct_runtime(prop, &RNA_OperatorMousePath);
Adding values:
PointerRNA itemptr;
float loc[2] = {1, 1},
RNA_collection_add(op->ptr, "path", &itemptr);
RNA_float_set_array(&itemptr, "loc", loc);
Iterating:
RNA_BEGIN(op->ptr, itemptr, "path") {
float loc[2];
RNA_float_get_array(&itemptr, "loc", loc);
printf("Location: %f %f\n", loc[0], loc[1]);
}
RNA_END;
2008-12-26 20:38:52 +00:00
|
|
|
idp_resize_group_array(prop, newlen, newarr);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* newlen is smaller*/
|
|
|
|
idp_resize_group_array(prop, newlen, newarr);
|
2009-06-22 18:19:18 +00:00
|
|
|
memcpy(newarr, prop->data.pointer, newlen*prop->len*idp_size_table[(int)prop->subtype]);
|
RNA:
* Added support for using pointers + collections as operator properties,
but with the restriction that they must point to other type derived from
ID property groups. The "add" function for these properties will allocate
a new ID property group and point to that.
* Added support for arrays with type IDP_GROUP in ID properties.
* Fix bug getting/setting float array values.
Example code for collections, note the "OperatorMousePath" type is defined
in rna_wm.c and has a float[2] property named "loc".
Defining the operator property:
prop= RNA_def_property(ot->srna, "path", PROP_COLLECTION, PROP_NONE);
RNA_def_property_struct_runtime(prop, &RNA_OperatorMousePath);
Adding values:
PointerRNA itemptr;
float loc[2] = {1, 1},
RNA_collection_add(op->ptr, "path", &itemptr);
RNA_float_set_array(&itemptr, "loc", loc);
Iterating:
RNA_BEGIN(op->ptr, itemptr, "path") {
float loc[2];
RNA_float_get_array(&itemptr, "loc", loc);
printf("Location: %f %f\n", loc[0], loc[1]);
}
RNA_END;
2008-12-26 20:38:52 +00:00
|
|
|
}
|
2006-11-17 04:46:48 +00:00
|
|
|
|
|
|
|
MEM_freeN(prop->data.pointer);
|
|
|
|
prop->data.pointer = newarr;
|
|
|
|
prop->len = newlen;
|
|
|
|
prop->totallen = newsize;
|
|
|
|
}
|
|
|
|
|
RNA:
* Added support for using pointers + collections as operator properties,
but with the restriction that they must point to other type derived from
ID property groups. The "add" function for these properties will allocate
a new ID property group and point to that.
* Added support for arrays with type IDP_GROUP in ID properties.
* Fix bug getting/setting float array values.
Example code for collections, note the "OperatorMousePath" type is defined
in rna_wm.c and has a float[2] property named "loc".
Defining the operator property:
prop= RNA_def_property(ot->srna, "path", PROP_COLLECTION, PROP_NONE);
RNA_def_property_struct_runtime(prop, &RNA_OperatorMousePath);
Adding values:
PointerRNA itemptr;
float loc[2] = {1, 1},
RNA_collection_add(op->ptr, "path", &itemptr);
RNA_float_set_array(&itemptr, "loc", loc);
Iterating:
RNA_BEGIN(op->ptr, itemptr, "path") {
float loc[2];
RNA_float_get_array(&itemptr, "loc", loc);
printf("Location: %f %f\n", loc[0], loc[1]);
}
RNA_END;
2008-12-26 20:38:52 +00:00
|
|
|
void IDP_FreeArray(IDProperty *prop)
|
2006-11-17 04:46:48 +00:00
|
|
|
{
|
RNA:
* Added support for using pointers + collections as operator properties,
but with the restriction that they must point to other type derived from
ID property groups. The "add" function for these properties will allocate
a new ID property group and point to that.
* Added support for arrays with type IDP_GROUP in ID properties.
* Fix bug getting/setting float array values.
Example code for collections, note the "OperatorMousePath" type is defined
in rna_wm.c and has a float[2] property named "loc".
Defining the operator property:
prop= RNA_def_property(ot->srna, "path", PROP_COLLECTION, PROP_NONE);
RNA_def_property_struct_runtime(prop, &RNA_OperatorMousePath);
Adding values:
PointerRNA itemptr;
float loc[2] = {1, 1},
RNA_collection_add(op->ptr, "path", &itemptr);
RNA_float_set_array(&itemptr, "loc", loc);
Iterating:
RNA_BEGIN(op->ptr, itemptr, "path") {
float loc[2];
RNA_float_get_array(&itemptr, "loc", loc);
printf("Location: %f %f\n", loc[0], loc[1]);
}
RNA_END;
2008-12-26 20:38:52 +00:00
|
|
|
if (prop->data.pointer) {
|
|
|
|
idp_resize_group_array(prop, 0, NULL);
|
2006-11-17 04:46:48 +00:00
|
|
|
MEM_freeN(prop->data.pointer);
|
RNA:
* Added support for using pointers + collections as operator properties,
but with the restriction that they must point to other type derived from
ID property groups. The "add" function for these properties will allocate
a new ID property group and point to that.
* Added support for arrays with type IDP_GROUP in ID properties.
* Fix bug getting/setting float array values.
Example code for collections, note the "OperatorMousePath" type is defined
in rna_wm.c and has a float[2] property named "loc".
Defining the operator property:
prop= RNA_def_property(ot->srna, "path", PROP_COLLECTION, PROP_NONE);
RNA_def_property_struct_runtime(prop, &RNA_OperatorMousePath);
Adding values:
PointerRNA itemptr;
float loc[2] = {1, 1},
RNA_collection_add(op->ptr, "path", &itemptr);
RNA_float_set_array(&itemptr, "loc", loc);
Iterating:
RNA_BEGIN(op->ptr, itemptr, "path") {
float loc[2];
RNA_float_get_array(&itemptr, "loc", loc);
printf("Location: %f %f\n", loc[0], loc[1]);
}
RNA_END;
2008-12-26 20:38:52 +00:00
|
|
|
}
|
2006-11-17 04:46:48 +00:00
|
|
|
}
|
|
|
|
|
2007-07-09 20:42:14 +00:00
|
|
|
|
|
|
|
static IDProperty *idp_generic_copy(IDProperty *prop)
|
|
|
|
{
|
|
|
|
IDProperty *newp = MEM_callocN(sizeof(IDProperty), "IDProperty array dup");
|
|
|
|
|
2008-12-31 13:16:37 +00:00
|
|
|
BLI_strncpy(newp->name, prop->name, MAX_IDPROP_NAME);
|
2007-07-09 20:42:14 +00:00
|
|
|
newp->type = prop->type;
|
|
|
|
newp->flag = prop->flag;
|
|
|
|
newp->data.val = prop->data.val;
|
2008-10-05 01:15:58 +00:00
|
|
|
newp->data.val2 = prop->data.val2;
|
2007-07-09 20:42:14 +00:00
|
|
|
|
|
|
|
return newp;
|
|
|
|
}
|
|
|
|
|
|
|
|
IDProperty *IDP_CopyArray(IDProperty *prop)
|
|
|
|
{
|
|
|
|
IDProperty *newp = idp_generic_copy(prop);
|
|
|
|
|
RNA:
* Added support for using pointers + collections as operator properties,
but with the restriction that they must point to other type derived from
ID property groups. The "add" function for these properties will allocate
a new ID property group and point to that.
* Added support for arrays with type IDP_GROUP in ID properties.
* Fix bug getting/setting float array values.
Example code for collections, note the "OperatorMousePath" type is defined
in rna_wm.c and has a float[2] property named "loc".
Defining the operator property:
prop= RNA_def_property(ot->srna, "path", PROP_COLLECTION, PROP_NONE);
RNA_def_property_struct_runtime(prop, &RNA_OperatorMousePath);
Adding values:
PointerRNA itemptr;
float loc[2] = {1, 1},
RNA_collection_add(op->ptr, "path", &itemptr);
RNA_float_set_array(&itemptr, "loc", loc);
Iterating:
RNA_BEGIN(op->ptr, itemptr, "path") {
float loc[2];
RNA_float_get_array(&itemptr, "loc", loc);
printf("Location: %f %f\n", loc[0], loc[1]);
}
RNA_END;
2008-12-26 20:38:52 +00:00
|
|
|
if (prop->data.pointer) {
|
|
|
|
newp->data.pointer = MEM_dupallocN(prop->data.pointer);
|
|
|
|
|
|
|
|
if(prop->type == IDP_GROUP) {
|
|
|
|
IDProperty **array= newp->data.pointer;
|
|
|
|
int a;
|
|
|
|
|
|
|
|
for(a=0; a<prop->len; a++)
|
|
|
|
array[a]= IDP_CopyProperty(array[a]);
|
|
|
|
}
|
|
|
|
}
|
2007-07-09 20:42:14 +00:00
|
|
|
newp->len = prop->len;
|
|
|
|
newp->subtype = prop->subtype;
|
|
|
|
newp->totallen = prop->totallen;
|
|
|
|
|
|
|
|
return newp;
|
|
|
|
}
|
|
|
|
|
2006-11-17 04:46:48 +00:00
|
|
|
/*taken from readfile.c*/
|
|
|
|
#define SWITCH_LONGINT(a) { \
|
|
|
|
char s_i, *p_i; \
|
|
|
|
p_i= (char *)&(a); \
|
|
|
|
s_i=p_i[0]; p_i[0]=p_i[7]; p_i[7]=s_i; \
|
|
|
|
s_i=p_i[1]; p_i[1]=p_i[6]; p_i[6]=s_i; \
|
|
|
|
s_i=p_i[2]; p_i[2]=p_i[5]; p_i[5]=s_i; \
|
|
|
|
s_i=p_i[3]; p_i[3]=p_i[4]; p_i[4]=s_i; }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* ---------- String Type ------------ */
|
2007-07-09 20:42:14 +00:00
|
|
|
IDProperty *IDP_CopyString(IDProperty *prop)
|
|
|
|
{
|
|
|
|
IDProperty *newp = idp_generic_copy(prop);
|
|
|
|
|
|
|
|
if (prop->data.pointer) newp->data.pointer = MEM_dupallocN(prop->data.pointer);
|
|
|
|
newp->len = prop->len;
|
|
|
|
newp->subtype = prop->subtype;
|
|
|
|
newp->totallen = prop->totallen;
|
|
|
|
|
|
|
|
return newp;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-11-17 04:46:48 +00:00
|
|
|
void IDP_AssignString(IDProperty *prop, char *st)
|
|
|
|
{
|
|
|
|
int stlen;
|
|
|
|
|
|
|
|
stlen = strlen(st);
|
|
|
|
|
|
|
|
IDP_ResizeArray(prop, stlen+1); /*make room for null byte :) */
|
|
|
|
strcpy(prop->data.pointer, st);
|
|
|
|
}
|
|
|
|
|
|
|
|
void IDP_ConcatStringC(IDProperty *prop, char *st)
|
|
|
|
{
|
|
|
|
int newlen;
|
|
|
|
|
|
|
|
newlen = prop->len + strlen(st);
|
|
|
|
/*we have to remember that prop->len includes the null byte for strings.
|
|
|
|
so there's no need to add +1 to the resize function.*/
|
|
|
|
IDP_ResizeArray(prop, newlen);
|
|
|
|
strcat(prop->data.pointer, st);
|
|
|
|
}
|
|
|
|
|
|
|
|
void IDP_ConcatString(IDProperty *str1, IDProperty *append)
|
|
|
|
{
|
|
|
|
int newlen;
|
|
|
|
|
|
|
|
/*since ->len for strings includes the NULL byte, we have to subtract one or
|
|
|
|
we'll get an extra null byte after each concatination operation.*/
|
|
|
|
newlen = str1->len + append->len - 1;
|
|
|
|
IDP_ResizeArray(str1, newlen);
|
|
|
|
strcat(str1->data.pointer, append->data.pointer);
|
|
|
|
}
|
|
|
|
|
|
|
|
void IDP_FreeString(IDProperty *prop)
|
|
|
|
{
|
2008-12-31 13:16:37 +00:00
|
|
|
if(prop->data.pointer)
|
|
|
|
MEM_freeN(prop->data.pointer);
|
2006-11-17 04:46:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-07-09 20:42:14 +00:00
|
|
|
/*-------- ID Type, not in use yet -------*/
|
2006-11-17 04:46:48 +00:00
|
|
|
|
|
|
|
void IDP_LinkID(IDProperty *prop, ID *id)
|
|
|
|
{
|
|
|
|
if (prop->data.pointer) ((ID*)prop->data.pointer)->us--;
|
|
|
|
prop->data.pointer = id;
|
|
|
|
id_us_plus(id);
|
|
|
|
}
|
|
|
|
|
|
|
|
void IDP_UnlinkID(IDProperty *prop)
|
|
|
|
{
|
|
|
|
((ID*)prop->data.pointer)->us--;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*-------- Group Functions -------*/
|
2007-05-22 04:41:21 +00:00
|
|
|
|
|
|
|
/*checks if a property with the same name as prop exists, and if so replaces it.*/
|
2007-07-09 20:42:14 +00:00
|
|
|
IDProperty *IDP_CopyGroup(IDProperty *prop)
|
|
|
|
{
|
|
|
|
IDProperty *newp = idp_generic_copy(prop), *link;
|
2008-02-11 18:26:19 +00:00
|
|
|
newp->len = prop->len;
|
|
|
|
|
2007-07-09 20:42:14 +00:00
|
|
|
for (link=prop->data.group.first; link; link=link->next) {
|
|
|
|
BLI_addtail(&newp->data.group, IDP_CopyProperty(link));
|
|
|
|
}
|
|
|
|
|
|
|
|
return newp;
|
|
|
|
}
|
|
|
|
|
2010-01-05 03:29:41 +00:00
|
|
|
/*
|
|
|
|
replaces all properties with the same name in a destination group from a source group.
|
|
|
|
*/
|
|
|
|
void IDP_ReplaceGroupInGroup(IDProperty *dest, IDProperty *src)
|
|
|
|
{
|
|
|
|
IDProperty *loop, *prop;
|
|
|
|
for (prop=src->data.group.first; prop; prop=prop->next) {
|
|
|
|
for (loop=dest->data.group.first; loop; loop=loop->next) {
|
|
|
|
if (BSTR_EQ(loop->name, prop->name)) {
|
2010-01-21 21:01:18 +00:00
|
|
|
IDProperty *copy = IDP_CopyProperty(prop);
|
|
|
|
|
|
|
|
BLI_insertlink(&dest->data.group, loop, copy);
|
2010-01-05 03:29:41 +00:00
|
|
|
|
|
|
|
BLI_remlink(&dest->data.group, loop);
|
|
|
|
IDP_FreeProperty(loop);
|
|
|
|
MEM_freeN(loop);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-01-21 21:01:18 +00:00
|
|
|
/* only add at end if not added yet */
|
|
|
|
if (loop == NULL) {
|
|
|
|
IDProperty *copy = IDP_CopyProperty(prop);
|
|
|
|
dest->len++;
|
|
|
|
BLI_addtail(&dest->data.group, copy);
|
|
|
|
}
|
2010-01-05 03:29:41 +00:00
|
|
|
}
|
|
|
|
}
|
2008-10-06 10:24:32 +00:00
|
|
|
/*
|
|
|
|
replaces a property with the same name in a group, or adds
|
|
|
|
it if the propery doesn't exist.
|
|
|
|
*/
|
2007-05-22 04:41:21 +00:00
|
|
|
void IDP_ReplaceInGroup(IDProperty *group, IDProperty *prop)
|
|
|
|
{
|
|
|
|
IDProperty *loop;
|
|
|
|
for (loop=group->data.group.first; loop; loop=loop->next) {
|
|
|
|
if (BSTR_EQ(loop->name, prop->name)) {
|
2010-01-21 21:01:18 +00:00
|
|
|
BLI_insertlink(&group->data.group, loop, prop);
|
2008-02-23 02:12:50 +00:00
|
|
|
|
2007-05-22 04:41:21 +00:00
|
|
|
BLI_remlink(&group->data.group, loop);
|
|
|
|
IDP_FreeProperty(loop);
|
2008-10-06 10:24:32 +00:00
|
|
|
MEM_freeN(loop);
|
2007-05-22 04:41:21 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
group->len++;
|
|
|
|
BLI_addtail(&group->data.group, prop);
|
|
|
|
}
|
|
|
|
|
2006-11-17 08:19:58 +00:00
|
|
|
/*returns 0 if an id property with the same name exists and it failed,
|
|
|
|
or 1 if it succeeded in adding to the group.*/
|
|
|
|
int IDP_AddToGroup(IDProperty *group, IDProperty *prop)
|
2006-11-17 04:46:48 +00:00
|
|
|
{
|
2006-11-17 08:19:58 +00:00
|
|
|
IDProperty *loop;
|
|
|
|
for (loop=group->data.group.first; loop; loop=loop->next) {
|
|
|
|
if (BSTR_EQ(loop->name, prop->name)) return 0;
|
|
|
|
}
|
|
|
|
|
2006-11-17 04:46:48 +00:00
|
|
|
group->len++;
|
|
|
|
BLI_addtail(&group->data.group, prop);
|
2006-11-17 08:19:58 +00:00
|
|
|
|
|
|
|
return 1;
|
2006-11-17 04:46:48 +00:00
|
|
|
}
|
|
|
|
|
2006-12-16 23:54:45 +00:00
|
|
|
int IDP_InsertToGroup(IDProperty *group, IDProperty *previous, IDProperty *pnew)
|
|
|
|
{
|
|
|
|
IDProperty *loop;
|
|
|
|
for (loop=group->data.group.first; loop; loop=loop->next) {
|
|
|
|
if (BSTR_EQ(loop->name, pnew->name)) return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
group->len++;
|
2008-10-06 10:24:32 +00:00
|
|
|
|
2006-12-16 23:54:45 +00:00
|
|
|
BLI_insertlink(&group->data.group, previous, pnew);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2006-11-17 04:46:48 +00:00
|
|
|
void IDP_RemFromGroup(IDProperty *group, IDProperty *prop)
|
|
|
|
{
|
|
|
|
group->len--;
|
|
|
|
BLI_remlink(&group->data.group, prop);
|
|
|
|
}
|
|
|
|
|
2009-11-18 20:01:35 +00:00
|
|
|
IDProperty *IDP_GetPropertyFromGroup(IDProperty *prop, const char *name)
|
2006-11-17 04:46:48 +00:00
|
|
|
{
|
|
|
|
IDProperty *loop;
|
|
|
|
for (loop=prop->data.group.first; loop; loop=loop->next) {
|
2006-12-01 03:04:36 +00:00
|
|
|
if (strcmp(loop->name, name)==0) return loop;
|
2006-11-17 04:46:48 +00:00
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
typedef struct IDPIter {
|
|
|
|
void *next;
|
|
|
|
IDProperty *parent;
|
|
|
|
} IDPIter;
|
|
|
|
|
|
|
|
void *IDP_GetGroupIterator(IDProperty *prop)
|
|
|
|
{
|
|
|
|
IDPIter *iter = MEM_callocN(sizeof(IDPIter), "IDPIter");
|
|
|
|
iter->next = prop->data.group.first;
|
|
|
|
iter->parent = prop;
|
|
|
|
return (void*) iter;
|
|
|
|
}
|
|
|
|
|
2006-12-06 19:20:06 +00:00
|
|
|
IDProperty *IDP_GroupIterNext(void *vself)
|
2006-11-17 04:46:48 +00:00
|
|
|
{
|
|
|
|
IDPIter *self = (IDPIter*) vself;
|
|
|
|
Link *next = (Link*) self->next;
|
|
|
|
if (self->next == NULL) {
|
|
|
|
MEM_freeN(self);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
self->next = next->next;
|
|
|
|
return (void*) next;
|
|
|
|
}
|
|
|
|
|
|
|
|
void IDP_FreeIterBeforeEnd(void *vself)
|
|
|
|
{
|
|
|
|
MEM_freeN(vself);
|
|
|
|
}
|
|
|
|
|
2006-11-17 06:14:15 +00:00
|
|
|
/*Ok, the way things work, Groups free the ID Property structs of their children.
|
2006-11-17 04:46:48 +00:00
|
|
|
This is because all ID Property freeing functions free only direct data (not the ID Property
|
2006-11-17 06:14:15 +00:00
|
|
|
struct itself), but for Groups the child properties *are* considered
|
2006-11-17 04:46:48 +00:00
|
|
|
direct data.*/
|
2008-09-29 17:08:11 +00:00
|
|
|
static void IDP_FreeGroup(IDProperty *prop)
|
2006-11-17 04:46:48 +00:00
|
|
|
{
|
2010-01-21 21:01:18 +00:00
|
|
|
IDProperty *loop;
|
|
|
|
for (loop=prop->data.group.first; loop; loop=loop->next)
|
2006-11-17 04:46:48 +00:00
|
|
|
{
|
|
|
|
IDP_FreeProperty(loop);
|
|
|
|
}
|
2010-01-21 21:01:18 +00:00
|
|
|
BLI_freelistN(&prop->data.group);
|
2006-11-17 04:46:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*-------- Main Functions --------*/
|
2007-07-09 20:42:14 +00:00
|
|
|
IDProperty *IDP_CopyProperty(IDProperty *prop)
|
|
|
|
{
|
|
|
|
switch (prop->type) {
|
|
|
|
case IDP_GROUP: return IDP_CopyGroup(prop);
|
|
|
|
case IDP_STRING: return IDP_CopyString(prop);
|
|
|
|
case IDP_ARRAY: return IDP_CopyArray(prop);
|
2008-12-31 13:16:37 +00:00
|
|
|
case IDP_IDPARRAY: return IDP_CopyIDPArray(prop);
|
2007-07-09 20:42:14 +00:00
|
|
|
default: return idp_generic_copy(prop);
|
|
|
|
}
|
|
|
|
}
|
2006-11-17 04:46:48 +00:00
|
|
|
|
|
|
|
IDProperty *IDP_GetProperties(ID *id, int create_if_needed)
|
|
|
|
{
|
|
|
|
if (id->properties) return id->properties;
|
|
|
|
else {
|
|
|
|
if (create_if_needed) {
|
|
|
|
id->properties = MEM_callocN(sizeof(IDProperty), "IDProperty");
|
|
|
|
id->properties->type = IDP_GROUP;
|
2008-10-08 09:27:26 +00:00
|
|
|
/* dont overwite the data's name and type
|
|
|
|
* some functions might need this if they
|
|
|
|
* dont have a real ID, should be named elsewhere - Campbell */
|
|
|
|
/* strcpy(id->name, "top_level_group");*/
|
2006-11-17 04:46:48 +00:00
|
|
|
}
|
|
|
|
return id->properties;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-01-28 23:29:27 +00:00
|
|
|
int IDP_EqualsProperties(IDProperty *prop1, IDProperty *prop2)
|
|
|
|
{
|
|
|
|
if(prop1 == NULL && prop2 == NULL)
|
|
|
|
return 1;
|
|
|
|
else if(prop1 == NULL || prop2 == NULL)
|
|
|
|
return 0;
|
|
|
|
else if(prop1->type != prop2->type)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if(prop1->type == IDP_INT)
|
|
|
|
return (IDP_Int(prop1) == IDP_Int(prop2));
|
|
|
|
else if(prop1->type == IDP_FLOAT)
|
|
|
|
return (IDP_Float(prop1) == IDP_Float(prop2));
|
|
|
|
else if(prop1->type == IDP_DOUBLE)
|
|
|
|
return (IDP_Double(prop1) == IDP_Double(prop2));
|
|
|
|
else if(prop1->type == IDP_STRING)
|
|
|
|
return BSTR_EQ(IDP_String(prop1), IDP_String(prop2));
|
|
|
|
else if(prop1->type == IDP_ARRAY) {
|
|
|
|
if(prop1->len == prop2->len && prop1->subtype == prop2->subtype)
|
2009-06-22 18:19:18 +00:00
|
|
|
return memcmp(IDP_Array(prop1), IDP_Array(prop2), idp_size_table[(int)prop1->subtype]*prop1->len);
|
2009-01-28 23:29:27 +00:00
|
|
|
else
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
else if(prop1->type == IDP_GROUP) {
|
|
|
|
IDProperty *link1, *link2;
|
|
|
|
|
|
|
|
if(BLI_countlist(&prop1->data.group) != BLI_countlist(&prop2->data.group))
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
for(link1=prop1->data.group.first; link1; link1=link1->next) {
|
|
|
|
link2= IDP_GetPropertyFromGroup(prop2, link1->name);
|
|
|
|
|
|
|
|
if(!IDP_EqualsProperties(link1, link2))
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
else if(prop1->type == IDP_IDPARRAY) {
|
|
|
|
IDProperty *array1= IDP_IDPArray(prop1);
|
|
|
|
IDProperty *array2= IDP_IDPArray(prop2);
|
|
|
|
int i;
|
|
|
|
|
|
|
|
if(prop1->len != prop2->len)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
for(i=0; i<prop1->len; i++)
|
|
|
|
if(!IDP_EqualsProperties(&array1[i], &array2[i]))
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2008-12-31 13:16:37 +00:00
|
|
|
IDProperty *IDP_New(int type, IDPropertyTemplate val, const char *name)
|
2006-11-17 04:46:48 +00:00
|
|
|
{
|
|
|
|
IDProperty *prop=NULL;
|
|
|
|
|
|
|
|
switch (type) {
|
|
|
|
case IDP_INT:
|
|
|
|
prop = MEM_callocN(sizeof(IDProperty), "IDProperty int");
|
|
|
|
prop->data.val = val.i;
|
|
|
|
break;
|
|
|
|
case IDP_FLOAT:
|
|
|
|
prop = MEM_callocN(sizeof(IDProperty), "IDProperty float");
|
|
|
|
*(float*)&prop->data.val = val.f;
|
|
|
|
break;
|
2008-07-24 19:22:17 +00:00
|
|
|
case IDP_DOUBLE:
|
|
|
|
prop = MEM_callocN(sizeof(IDProperty), "IDProperty float");
|
|
|
|
*(double*)&prop->data.val = val.d;
|
|
|
|
break;
|
2006-11-17 04:46:48 +00:00
|
|
|
case IDP_ARRAY:
|
|
|
|
{
|
2008-07-24 19:22:17 +00:00
|
|
|
/*for now, we only support float and int and double arrays*/
|
RNA:
* Added support for using pointers + collections as operator properties,
but with the restriction that they must point to other type derived from
ID property groups. The "add" function for these properties will allocate
a new ID property group and point to that.
* Added support for arrays with type IDP_GROUP in ID properties.
* Fix bug getting/setting float array values.
Example code for collections, note the "OperatorMousePath" type is defined
in rna_wm.c and has a float[2] property named "loc".
Defining the operator property:
prop= RNA_def_property(ot->srna, "path", PROP_COLLECTION, PROP_NONE);
RNA_def_property_struct_runtime(prop, &RNA_OperatorMousePath);
Adding values:
PointerRNA itemptr;
float loc[2] = {1, 1},
RNA_collection_add(op->ptr, "path", &itemptr);
RNA_float_set_array(&itemptr, "loc", loc);
Iterating:
RNA_BEGIN(op->ptr, itemptr, "path") {
float loc[2];
RNA_float_get_array(&itemptr, "loc", loc);
printf("Location: %f %f\n", loc[0], loc[1]);
}
RNA_END;
2008-12-26 20:38:52 +00:00
|
|
|
if (val.array.type == IDP_FLOAT || val.array.type == IDP_INT || val.array.type == IDP_DOUBLE || val.array.type == IDP_GROUP) {
|
2006-11-17 04:46:48 +00:00
|
|
|
prop = MEM_callocN(sizeof(IDProperty), "IDProperty array");
|
|
|
|
prop->subtype = val.array.type;
|
2008-12-31 13:16:37 +00:00
|
|
|
if (val.array.len)
|
|
|
|
prop->data.pointer = MEM_callocN(idp_size_table[val.array.type]*val.array.len, "id property array");
|
RNA:
* Added support for using pointers + collections as operator properties,
but with the restriction that they must point to other type derived from
ID property groups. The "add" function for these properties will allocate
a new ID property group and point to that.
* Added support for arrays with type IDP_GROUP in ID properties.
* Fix bug getting/setting float array values.
Example code for collections, note the "OperatorMousePath" type is defined
in rna_wm.c and has a float[2] property named "loc".
Defining the operator property:
prop= RNA_def_property(ot->srna, "path", PROP_COLLECTION, PROP_NONE);
RNA_def_property_struct_runtime(prop, &RNA_OperatorMousePath);
Adding values:
PointerRNA itemptr;
float loc[2] = {1, 1},
RNA_collection_add(op->ptr, "path", &itemptr);
RNA_float_set_array(&itemptr, "loc", loc);
Iterating:
RNA_BEGIN(op->ptr, itemptr, "path") {
float loc[2];
RNA_float_get_array(&itemptr, "loc", loc);
printf("Location: %f %f\n", loc[0], loc[1]);
}
RNA_END;
2008-12-26 20:38:52 +00:00
|
|
|
prop->len = prop->totallen = val.array.len;
|
2006-11-17 04:46:48 +00:00
|
|
|
break;
|
|
|
|
} else {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
case IDP_STRING:
|
|
|
|
{
|
|
|
|
char *st = val.str;
|
|
|
|
int stlen;
|
|
|
|
|
|
|
|
prop = MEM_callocN(sizeof(IDProperty), "IDProperty string");
|
|
|
|
if (st == NULL) {
|
|
|
|
prop->data.pointer = MEM_callocN(DEFAULT_ALLOC_FOR_NULL_STRINGS, "id property string 1");
|
|
|
|
prop->totallen = DEFAULT_ALLOC_FOR_NULL_STRINGS;
|
|
|
|
prop->len = 1; /*NULL string, has len of 1 to account for null byte.*/
|
|
|
|
} else {
|
|
|
|
stlen = strlen(st) + 1;
|
|
|
|
prop->data.pointer = MEM_callocN(stlen, "id property string 2");
|
|
|
|
prop->len = prop->totallen = stlen;
|
|
|
|
strcpy(prop->data.pointer, st);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case IDP_GROUP:
|
|
|
|
{
|
|
|
|
prop = MEM_callocN(sizeof(IDProperty), "IDProperty group");
|
|
|
|
/* heh I think all needed values are set properly by calloc anyway :) */
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
{
|
|
|
|
prop = MEM_callocN(sizeof(IDProperty), "IDProperty array");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
prop->type = type;
|
2008-12-31 13:16:37 +00:00
|
|
|
BLI_strncpy(prop->name, name, MAX_IDPROP_NAME);
|
2008-07-24 19:22:17 +00:00
|
|
|
|
|
|
|
/*security null byte*/
|
|
|
|
prop->name[MAX_IDPROP_NAME-1] = 0;
|
|
|
|
|
2006-11-17 04:46:48 +00:00
|
|
|
return prop;
|
|
|
|
}
|
|
|
|
|
2008-10-06 10:24:32 +00:00
|
|
|
/*NOTE: this will free all child properties including list arrays and groups!
|
2006-11-17 04:46:48 +00:00
|
|
|
Also, note that this does NOT unlink anything! Plus it doesn't free
|
|
|
|
the actual IDProperty struct either.*/
|
|
|
|
void IDP_FreeProperty(IDProperty *prop)
|
|
|
|
{
|
|
|
|
switch (prop->type) {
|
|
|
|
case IDP_ARRAY:
|
|
|
|
IDP_FreeArray(prop);
|
|
|
|
break;
|
|
|
|
case IDP_STRING:
|
|
|
|
IDP_FreeString(prop);
|
|
|
|
break;
|
|
|
|
case IDP_GROUP:
|
|
|
|
IDP_FreeGroup(prop);
|
|
|
|
break;
|
2008-12-31 13:16:37 +00:00
|
|
|
case IDP_IDPARRAY:
|
|
|
|
IDP_FreeIDPArray(prop);
|
|
|
|
break;
|
2006-11-17 04:46:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-10-06 10:24:32 +00:00
|
|
|
/*Unlinks any IDProperty<->ID linkage that might be going on.
|
|
|
|
note: currently unused.*/
|
2006-11-17 04:46:48 +00:00
|
|
|
void IDP_UnlinkProperty(IDProperty *prop)
|
|
|
|
{
|
|
|
|
switch (prop->type) {
|
|
|
|
case IDP_ID:
|
|
|
|
IDP_UnlinkID(prop);
|
|
|
|
}
|
|
|
|
}
|