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,
|
|
|
|
|
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
|
*
|
|
|
|
|
* 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
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* ----------- 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) {
|
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);
|
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;
|
|
|
|
|
|
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
|
|
|
newarr = MEM_callocN(idp_size_table[prop->subtype]*newsize, "idproperty array resized");
|
|
|
|
|
if (newlen >= prop->len) {
|
|
|
|
|
/* newlen is bigger*/
|
|
|
|
|
memcpy(newarr, prop->data.pointer, prop->len*idp_size_table[prop->subtype]);
|
|
|
|
|
idp_resize_group_array(prop, newlen, newarr);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* newlen is smaller*/
|
|
|
|
|
idp_resize_group_array(prop, newlen, newarr);
|
|
|
|
|
memcpy(newarr, prop->data.pointer, newlen*prop->len*idp_size_table[prop->subtype]);
|
|
|
|
|
}
|
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");
|
|
|
|
|
|
|
|
|
|
strncpy(newp->name, prop->name, MAX_IDPROP_NAME);
|
|
|
|
|
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)
|
|
|
|
|
{
|
|
|
|
|
MEM_freeN(prop->data.pointer);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
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)) {
|
|
|
|
|
if (loop->next) BLI_insertlinkbefore(&group->data.group, loop->next, prop);
|
|
|
|
|
else BLI_addtail(&group->data.group, 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);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
IDProperty *IDP_GetPropertyFromGroup(IDProperty *prop, char *name)
|
|
|
|
|
{
|
|
|
|
|
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
|
|
|
{
|
|
|
|
|
IDProperty *loop, *next;
|
|
|
|
|
for (loop=prop->data.group.first; loop; loop=next)
|
|
|
|
|
{
|
|
|
|
|
next = loop->next;
|
2007-06-18 07:41:21 +00:00
|
|
|
BLI_remlink(&prop->data.group, loop);
|
2006-11-17 04:46:48 +00:00
|
|
|
IDP_FreeProperty(loop);
|
|
|
|
|
MEM_freeN(loop);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*-------- 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);
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
IDProperty *IDP_New(int type, IDPropertyTemplate val, char *name)
|
|
|
|
|
{
|
|
|
|
|
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;
|
|
|
|
|
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
|
|
|
idp_resize_group_array(prop, val.array.len, prop->data.pointer);
|
|
|
|
|
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;
|
|
|
|
|
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-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);
|
|
|
|
|
}
|
|
|
|
|
}
|