2008-10-31 23:50:02 +00:00
|
|
|
/**
|
|
|
|
* $Id$
|
|
|
|
*
|
|
|
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
|
|
|
*
|
|
|
|
* 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
|
|
|
|
* of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* 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.
|
|
|
|
*
|
|
|
|
* Contributor(s): Blender Foundation (2008).
|
|
|
|
*
|
|
|
|
* ***** END GPL LICENSE BLOCK *****
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
#include "MEM_guardedalloc.h"
|
|
|
|
|
2008-11-11 18:28:00 +00:00
|
|
|
#include "BLI_blenlib.h"
|
|
|
|
#include "BLI_dynstr.h"
|
|
|
|
|
2008-10-31 23:50:02 +00:00
|
|
|
#include "RNA_access.h"
|
|
|
|
#include "RNA_types.h"
|
|
|
|
|
2008-11-07 02:58:25 +00:00
|
|
|
#include "rna_internal.h"
|
2008-10-31 23:50:02 +00:00
|
|
|
|
2008-11-07 02:58:25 +00:00
|
|
|
/* Pointer */
|
|
|
|
|
|
|
|
void RNA_pointer_main_get(struct Main *main, struct PointerRNA *r_ptr)
|
2008-10-31 23:50:02 +00:00
|
|
|
{
|
2008-11-07 02:58:25 +00:00
|
|
|
r_ptr->data= main;
|
|
|
|
r_ptr->type= &RNA_Main;
|
|
|
|
r_ptr->id.data= NULL;
|
|
|
|
r_ptr->id.type= NULL;
|
2008-10-31 23:50:02 +00:00
|
|
|
}
|
|
|
|
|
2008-11-07 02:58:25 +00:00
|
|
|
static void rna_pointer_inherit_id(PointerRNA *parent, PointerRNA *ptr)
|
|
|
|
{
|
|
|
|
if(ptr->type && ptr->type->flag & STRUCT_ID) {
|
|
|
|
ptr->id.data= ptr->data;
|
|
|
|
ptr->id.type= ptr->type;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
ptr->id.data= parent->id.data;
|
|
|
|
ptr->id.type= parent->id.type;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-11-14 14:34:19 +00:00
|
|
|
/* Structs */
|
|
|
|
|
2008-11-14 18:46:57 +00:00
|
|
|
const char *RNA_struct_identifier(PointerRNA *ptr)
|
2008-11-14 14:34:19 +00:00
|
|
|
{
|
2008-11-14 18:46:57 +00:00
|
|
|
return ptr->type->identifier;
|
2008-11-14 14:34:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
const char *RNA_struct_ui_name(PointerRNA *ptr)
|
|
|
|
{
|
|
|
|
return ptr->type->name;
|
|
|
|
}
|
|
|
|
|
|
|
|
PropertyRNA *RNA_struct_name_property(PointerRNA *ptr)
|
|
|
|
{
|
|
|
|
return ptr->type->nameproperty;
|
|
|
|
}
|
|
|
|
|
|
|
|
PropertyRNA *RNA_struct_iterator_property(PointerRNA *ptr)
|
|
|
|
{
|
|
|
|
return ptr->type->iteratorproperty;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Property Information */
|
|
|
|
|
2008-11-14 18:46:57 +00:00
|
|
|
const char *RNA_property_identifier(PropertyRNA *prop, PointerRNA *ptr)
|
2008-11-14 14:34:19 +00:00
|
|
|
{
|
2008-11-14 18:46:57 +00:00
|
|
|
return prop->identifier;
|
2008-11-14 14:34:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
PropertyType RNA_property_type(PropertyRNA *prop, PointerRNA *ptr)
|
|
|
|
{
|
|
|
|
return prop->type;
|
|
|
|
}
|
|
|
|
|
|
|
|
PropertySubType RNA_property_subtype(PropertyRNA *prop, PointerRNA *ptr)
|
|
|
|
{
|
|
|
|
return prop->subtype;
|
|
|
|
}
|
|
|
|
|
|
|
|
int RNA_property_array_length(PropertyRNA *prop, PointerRNA *ptr)
|
|
|
|
{
|
|
|
|
return prop->arraylength;
|
|
|
|
}
|
|
|
|
|
|
|
|
void RNA_property_int_range(PropertyRNA *prop, PointerRNA *ptr, int *hardmin, int *hardmax)
|
|
|
|
{
|
|
|
|
IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
|
|
|
|
|
|
|
|
*hardmin= iprop->hardmin;
|
|
|
|
*hardmax= iprop->hardmax;
|
|
|
|
}
|
|
|
|
|
|
|
|
void RNA_property_int_ui_range(PropertyRNA *prop, PointerRNA *ptr, int *softmin, int *softmax, int *step)
|
|
|
|
{
|
|
|
|
IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
|
|
|
|
|
|
|
|
*softmin= iprop->softmin;
|
|
|
|
*softmax= iprop->softmax;
|
|
|
|
*step= iprop->step;
|
|
|
|
}
|
|
|
|
|
|
|
|
void RNA_property_float_range(PropertyRNA *prop, PointerRNA *ptr, float *hardmin, float *hardmax)
|
|
|
|
{
|
|
|
|
FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
|
|
|
|
|
|
|
|
*hardmin= fprop->hardmin;
|
|
|
|
*hardmax= fprop->hardmax;
|
|
|
|
}
|
|
|
|
|
|
|
|
void RNA_property_float_ui_range(PropertyRNA *prop, PointerRNA *ptr, float *softmin, float *softmax, float *step, float *precision)
|
|
|
|
{
|
|
|
|
FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
|
|
|
|
|
|
|
|
*softmin= fprop->softmin;
|
|
|
|
*softmax= fprop->softmax;
|
|
|
|
*step= fprop->step;
|
|
|
|
*precision= fprop->precision;
|
|
|
|
}
|
|
|
|
|
|
|
|
int RNA_property_string_maxlength(PropertyRNA *prop, PointerRNA *ptr)
|
|
|
|
{
|
|
|
|
StringPropertyRNA *sprop= (StringPropertyRNA*)prop;
|
|
|
|
|
|
|
|
return sprop->maxlength;
|
|
|
|
}
|
|
|
|
|
2008-11-14 18:46:57 +00:00
|
|
|
void RNA_property_enum_items(PropertyRNA *prop, PointerRNA *ptr, const EnumPropertyItem **item, int *totitem)
|
2008-11-14 14:34:19 +00:00
|
|
|
{
|
|
|
|
EnumPropertyRNA *eprop= (EnumPropertyRNA*)prop;
|
|
|
|
|
|
|
|
*item= eprop->item;
|
|
|
|
*totitem= eprop->totitem;
|
|
|
|
}
|
|
|
|
|
|
|
|
const char *RNA_property_ui_name(PropertyRNA *prop, PointerRNA *ptr)
|
|
|
|
{
|
|
|
|
return prop->name;
|
|
|
|
}
|
|
|
|
|
|
|
|
const char *RNA_property_ui_description(PropertyRNA *prop, PointerRNA *ptr)
|
|
|
|
{
|
|
|
|
return prop->description;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Property Data */
|
2008-11-07 02:58:25 +00:00
|
|
|
|
|
|
|
int RNA_property_editable(PropertyRNA *prop, PointerRNA *ptr)
|
2008-10-31 23:50:02 +00:00
|
|
|
{
|
2008-11-14 14:34:19 +00:00
|
|
|
return !(prop->flag & PROP_NOT_EDITABLE);
|
2008-10-31 23:50:02 +00:00
|
|
|
}
|
|
|
|
|
2008-11-07 02:58:25 +00:00
|
|
|
int RNA_property_evaluated(PropertyRNA *prop, PointerRNA *ptr)
|
2008-10-31 23:50:02 +00:00
|
|
|
{
|
2008-11-07 02:58:25 +00:00
|
|
|
return (prop->flag & PROP_EVALUATED);
|
2008-10-31 23:50:02 +00:00
|
|
|
}
|
|
|
|
|
2008-11-07 02:58:25 +00:00
|
|
|
void RNA_property_notify(PropertyRNA *prop, struct bContext *C, PointerRNA *ptr)
|
|
|
|
{
|
|
|
|
if(prop->notify)
|
|
|
|
prop->notify(C, ptr);
|
|
|
|
}
|
|
|
|
|
|
|
|
int RNA_property_boolean_get(PropertyRNA *prop, PointerRNA *ptr)
|
2008-10-31 23:50:02 +00:00
|
|
|
{
|
|
|
|
BooleanPropertyRNA *bprop= (BooleanPropertyRNA*)prop;
|
|
|
|
|
2008-11-07 02:58:25 +00:00
|
|
|
return bprop->get(ptr);
|
2008-10-31 23:50:02 +00:00
|
|
|
}
|
|
|
|
|
2008-11-07 02:58:25 +00:00
|
|
|
void RNA_property_boolean_set(PropertyRNA *prop, PointerRNA *ptr, int value)
|
2008-10-31 23:50:02 +00:00
|
|
|
{
|
|
|
|
BooleanPropertyRNA *bprop= (BooleanPropertyRNA*)prop;
|
|
|
|
|
2008-11-14 14:34:19 +00:00
|
|
|
if(bprop->set)
|
|
|
|
bprop->set(ptr, value);
|
2008-10-31 23:50:02 +00:00
|
|
|
}
|
|
|
|
|
2008-11-07 02:58:25 +00:00
|
|
|
int RNA_property_boolean_get_array(PropertyRNA *prop, PointerRNA *ptr, int index)
|
2008-10-31 23:50:02 +00:00
|
|
|
{
|
|
|
|
BooleanPropertyRNA *bprop= (BooleanPropertyRNA*)prop;
|
|
|
|
|
2008-11-07 02:58:25 +00:00
|
|
|
return bprop->getarray(ptr, index);
|
2008-10-31 23:50:02 +00:00
|
|
|
}
|
|
|
|
|
2008-11-07 02:58:25 +00:00
|
|
|
void RNA_property_boolean_set_array(PropertyRNA *prop, PointerRNA *ptr, int index, int value)
|
2008-10-31 23:50:02 +00:00
|
|
|
{
|
|
|
|
BooleanPropertyRNA *bprop= (BooleanPropertyRNA*)prop;
|
|
|
|
|
2008-11-14 14:34:19 +00:00
|
|
|
if(bprop->setarray)
|
|
|
|
bprop->setarray(ptr, index, value);
|
2008-10-31 23:50:02 +00:00
|
|
|
}
|
|
|
|
|
2008-11-07 02:58:25 +00:00
|
|
|
int RNA_property_int_get(PropertyRNA *prop, PointerRNA *ptr)
|
2008-10-31 23:50:02 +00:00
|
|
|
{
|
|
|
|
IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
|
|
|
|
|
2008-11-07 02:58:25 +00:00
|
|
|
return iprop->get(ptr);
|
2008-10-31 23:50:02 +00:00
|
|
|
}
|
|
|
|
|
2008-11-07 02:58:25 +00:00
|
|
|
void RNA_property_int_set(PropertyRNA *prop, PointerRNA *ptr, int value)
|
2008-10-31 23:50:02 +00:00
|
|
|
{
|
|
|
|
IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
|
|
|
|
|
2008-11-14 14:34:19 +00:00
|
|
|
if(iprop->set)
|
|
|
|
iprop->set(ptr, value);
|
2008-10-31 23:50:02 +00:00
|
|
|
}
|
|
|
|
|
2008-11-07 02:58:25 +00:00
|
|
|
int RNA_property_int_get_array(PropertyRNA *prop, PointerRNA *ptr, int index)
|
2008-10-31 23:50:02 +00:00
|
|
|
{
|
|
|
|
IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
|
|
|
|
|
2008-11-07 02:58:25 +00:00
|
|
|
return iprop->getarray(ptr, index);
|
2008-10-31 23:50:02 +00:00
|
|
|
}
|
|
|
|
|
2008-11-07 02:58:25 +00:00
|
|
|
void RNA_property_int_set_array(PropertyRNA *prop, PointerRNA *ptr, int index, int value)
|
2008-10-31 23:50:02 +00:00
|
|
|
{
|
|
|
|
IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
|
|
|
|
|
2008-11-14 14:34:19 +00:00
|
|
|
if(iprop->setarray)
|
|
|
|
iprop->setarray(ptr, index, value);
|
2008-10-31 23:50:02 +00:00
|
|
|
}
|
|
|
|
|
2008-11-07 02:58:25 +00:00
|
|
|
float RNA_property_float_get(PropertyRNA *prop, PointerRNA *ptr)
|
2008-10-31 23:50:02 +00:00
|
|
|
{
|
|
|
|
FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
|
|
|
|
|
2008-11-07 02:58:25 +00:00
|
|
|
return fprop->get(ptr);
|
2008-10-31 23:50:02 +00:00
|
|
|
}
|
|
|
|
|
2008-11-07 02:58:25 +00:00
|
|
|
void RNA_property_float_set(PropertyRNA *prop, PointerRNA *ptr, float value)
|
2008-10-31 23:50:02 +00:00
|
|
|
{
|
|
|
|
FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
|
|
|
|
|
2008-11-14 14:34:19 +00:00
|
|
|
if(fprop->set)
|
|
|
|
fprop->set(ptr, value);
|
2008-10-31 23:50:02 +00:00
|
|
|
}
|
|
|
|
|
2008-11-07 02:58:25 +00:00
|
|
|
float RNA_property_float_get_array(PropertyRNA *prop, PointerRNA *ptr, int index)
|
2008-10-31 23:50:02 +00:00
|
|
|
{
|
|
|
|
FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
|
|
|
|
|
2008-11-07 02:58:25 +00:00
|
|
|
return fprop->getarray(ptr, index);
|
2008-10-31 23:50:02 +00:00
|
|
|
}
|
|
|
|
|
2008-11-07 02:58:25 +00:00
|
|
|
void RNA_property_float_set_array(PropertyRNA *prop, PointerRNA *ptr, int index, float value)
|
2008-10-31 23:50:02 +00:00
|
|
|
{
|
|
|
|
FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
|
|
|
|
|
2008-11-14 14:34:19 +00:00
|
|
|
if(fprop->setarray)
|
|
|
|
fprop->setarray(ptr, index, value);
|
2008-10-31 23:50:02 +00:00
|
|
|
}
|
|
|
|
|
2008-11-07 02:58:25 +00:00
|
|
|
void RNA_property_string_get(PropertyRNA *prop, PointerRNA *ptr, char *value)
|
2008-10-31 23:50:02 +00:00
|
|
|
{
|
|
|
|
StringPropertyRNA *sprop= (StringPropertyRNA*)prop;
|
|
|
|
|
2008-11-07 02:58:25 +00:00
|
|
|
sprop->get(ptr, value);
|
2008-10-31 23:50:02 +00:00
|
|
|
}
|
|
|
|
|
2008-11-11 15:03:26 +00:00
|
|
|
char *RNA_property_string_get_alloc(PropertyRNA *prop, PointerRNA *ptr, char *fixedbuf, int fixedlen)
|
|
|
|
{
|
|
|
|
char *buf;
|
|
|
|
int length;
|
|
|
|
|
|
|
|
length= RNA_property_string_length(prop, ptr);
|
|
|
|
|
|
|
|
if(length+1 < fixedlen)
|
|
|
|
buf= fixedbuf;
|
|
|
|
else
|
|
|
|
buf= MEM_callocN(sizeof(char)*(length+1), "RNA_string_get_alloc");
|
|
|
|
|
|
|
|
RNA_property_string_get(prop, ptr, buf);
|
|
|
|
|
|
|
|
return buf;
|
|
|
|
}
|
|
|
|
|
2008-11-07 02:58:25 +00:00
|
|
|
int RNA_property_string_length(PropertyRNA *prop, PointerRNA *ptr)
|
2008-10-31 23:50:02 +00:00
|
|
|
{
|
|
|
|
StringPropertyRNA *sprop= (StringPropertyRNA*)prop;
|
|
|
|
|
2008-11-07 02:58:25 +00:00
|
|
|
return sprop->length(ptr);
|
2008-10-31 23:50:02 +00:00
|
|
|
}
|
|
|
|
|
2008-11-07 02:58:25 +00:00
|
|
|
void RNA_property_string_set(PropertyRNA *prop, PointerRNA *ptr, const char *value)
|
2008-10-31 23:50:02 +00:00
|
|
|
{
|
|
|
|
StringPropertyRNA *sprop= (StringPropertyRNA*)prop;
|
|
|
|
|
2008-11-14 14:34:19 +00:00
|
|
|
if(sprop->set)
|
|
|
|
sprop->set(ptr, value);
|
2008-10-31 23:50:02 +00:00
|
|
|
}
|
|
|
|
|
2008-11-07 02:58:25 +00:00
|
|
|
int RNA_property_enum_get(PropertyRNA *prop, PointerRNA *ptr)
|
2008-10-31 23:50:02 +00:00
|
|
|
{
|
|
|
|
EnumPropertyRNA *eprop= (EnumPropertyRNA*)prop;
|
|
|
|
|
2008-11-07 02:58:25 +00:00
|
|
|
return eprop->get(ptr);
|
2008-10-31 23:50:02 +00:00
|
|
|
}
|
|
|
|
|
2008-11-07 02:58:25 +00:00
|
|
|
void RNA_property_enum_set(PropertyRNA *prop, PointerRNA *ptr, int value)
|
2008-10-31 23:50:02 +00:00
|
|
|
{
|
|
|
|
EnumPropertyRNA *eprop= (EnumPropertyRNA*)prop;
|
|
|
|
|
2008-11-14 14:34:19 +00:00
|
|
|
if(eprop->set)
|
|
|
|
eprop->set(ptr, value);
|
2008-10-31 23:50:02 +00:00
|
|
|
}
|
|
|
|
|
2008-11-07 02:58:25 +00:00
|
|
|
void RNA_property_pointer_get(PropertyRNA *prop, PointerRNA *ptr, PointerRNA *r_ptr)
|
2008-10-31 23:50:02 +00:00
|
|
|
{
|
|
|
|
PointerPropertyRNA *pprop= (PointerPropertyRNA*)prop;
|
|
|
|
|
2008-11-07 02:58:25 +00:00
|
|
|
r_ptr->data= pprop->get(ptr);
|
|
|
|
|
|
|
|
if(r_ptr->data) {
|
|
|
|
r_ptr->type= RNA_property_pointer_type(prop, ptr);
|
|
|
|
rna_pointer_inherit_id(ptr, r_ptr);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
memset(r_ptr, 0, sizeof(*r_ptr));
|
2008-10-31 23:50:02 +00:00
|
|
|
}
|
|
|
|
|
2008-11-07 02:58:25 +00:00
|
|
|
void RNA_property_pointer_set(PropertyRNA *prop, PointerRNA *ptr, PointerRNA *ptr_value)
|
2008-10-31 23:50:02 +00:00
|
|
|
{
|
|
|
|
PointerPropertyRNA *pprop= (PointerPropertyRNA*)prop;
|
|
|
|
|
2008-11-14 14:34:19 +00:00
|
|
|
if(pprop->set)
|
|
|
|
pprop->set(ptr, ptr_value->data);
|
2008-10-31 23:50:02 +00:00
|
|
|
}
|
|
|
|
|
2008-11-07 02:58:25 +00:00
|
|
|
StructRNA *RNA_property_pointer_type(PropertyRNA *prop, PointerRNA *ptr)
|
2008-10-31 23:50:02 +00:00
|
|
|
{
|
|
|
|
PointerPropertyRNA *pprop= (PointerPropertyRNA*)prop;
|
|
|
|
|
|
|
|
if(pprop->type)
|
2008-11-07 02:58:25 +00:00
|
|
|
return pprop->type(ptr);
|
2008-10-31 23:50:02 +00:00
|
|
|
|
|
|
|
return pprop->structtype;
|
|
|
|
}
|
|
|
|
|
2008-11-14 17:05:25 +00:00
|
|
|
static StructRNA *rna_property_collection_type(PropertyRNA *prop, CollectionPropertyIterator *iter)
|
2008-10-31 23:50:02 +00:00
|
|
|
{
|
|
|
|
CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
|
|
|
|
|
2008-11-14 17:05:25 +00:00
|
|
|
if(cprop->type)
|
|
|
|
return cprop->type(iter);
|
|
|
|
|
|
|
|
return cprop->structtype;
|
2008-10-31 23:50:02 +00:00
|
|
|
}
|
|
|
|
|
2008-11-14 17:05:25 +00:00
|
|
|
static void rna_property_collection_get(PropertyRNA *prop, CollectionPropertyIterator *iter, PointerRNA *r_ptr)
|
2008-10-31 23:50:02 +00:00
|
|
|
{
|
|
|
|
CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
|
|
|
|
|
2008-11-14 17:05:25 +00:00
|
|
|
r_ptr->data= cprop->get(iter);
|
|
|
|
|
|
|
|
if(r_ptr->data) {
|
|
|
|
r_ptr->type= rna_property_collection_type(prop, iter);
|
|
|
|
rna_pointer_inherit_id(&iter->parent, r_ptr);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
memset(r_ptr, 0, sizeof(*r_ptr));
|
2008-10-31 23:50:02 +00:00
|
|
|
}
|
|
|
|
|
2008-11-14 17:05:25 +00:00
|
|
|
void RNA_property_collection_begin(PropertyRNA *prop, CollectionPropertyIterator *iter, PointerRNA *ptr)
|
2008-10-31 23:50:02 +00:00
|
|
|
{
|
|
|
|
CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
|
|
|
|
|
2008-11-14 17:05:25 +00:00
|
|
|
iter->parent= *ptr;
|
|
|
|
cprop->begin(iter, ptr);
|
|
|
|
|
|
|
|
if(iter->valid)
|
|
|
|
rna_property_collection_get(prop, iter, &iter->ptr);
|
|
|
|
else
|
|
|
|
memset(&iter->ptr, 0, sizeof(iter->ptr));
|
2008-10-31 23:50:02 +00:00
|
|
|
}
|
|
|
|
|
2008-11-14 17:05:25 +00:00
|
|
|
void RNA_property_collection_next(PropertyRNA *prop, CollectionPropertyIterator *iter)
|
2008-10-31 23:50:02 +00:00
|
|
|
{
|
|
|
|
CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
|
|
|
|
|
2008-11-14 17:05:25 +00:00
|
|
|
cprop->next(iter);
|
2008-11-07 02:58:25 +00:00
|
|
|
|
2008-11-14 17:05:25 +00:00
|
|
|
if(iter->valid)
|
|
|
|
rna_property_collection_get(prop, iter, &iter->ptr);
|
2008-11-07 02:58:25 +00:00
|
|
|
else
|
2008-11-14 17:05:25 +00:00
|
|
|
memset(&iter->ptr, 0, sizeof(iter->ptr));
|
2008-10-31 23:50:02 +00:00
|
|
|
}
|
|
|
|
|
2008-11-14 17:05:25 +00:00
|
|
|
void RNA_property_collection_end(PropertyRNA *prop, CollectionPropertyIterator *iter)
|
2008-10-31 23:50:02 +00:00
|
|
|
{
|
|
|
|
CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
|
|
|
|
|
2008-11-14 17:05:25 +00:00
|
|
|
if(cprop->end)
|
|
|
|
cprop->end(iter);
|
2008-10-31 23:50:02 +00:00
|
|
|
}
|
|
|
|
|
2008-11-07 02:58:25 +00:00
|
|
|
int RNA_property_collection_length(PropertyRNA *prop, PointerRNA *ptr)
|
2008-10-31 23:50:02 +00:00
|
|
|
{
|
|
|
|
CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
|
|
|
|
|
|
|
|
if(cprop->length) {
|
2008-11-07 02:58:25 +00:00
|
|
|
return cprop->length(ptr);
|
2008-10-31 23:50:02 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
CollectionPropertyIterator iter;
|
|
|
|
int length= 0;
|
|
|
|
|
2008-11-07 02:58:25 +00:00
|
|
|
for(cprop->begin(&iter, ptr); iter.valid; cprop->next(&iter))
|
2008-10-31 23:50:02 +00:00
|
|
|
length++;
|
|
|
|
|
|
|
|
if(cprop->end)
|
|
|
|
cprop->end(&iter);
|
|
|
|
|
|
|
|
return length;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-11-07 02:58:25 +00:00
|
|
|
int RNA_property_collection_lookup_int(PropertyRNA *prop, PointerRNA *ptr, int key, PointerRNA *r_ptr)
|
2008-10-31 23:50:02 +00:00
|
|
|
{
|
|
|
|
CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
|
|
|
|
|
|
|
|
if(cprop->lookupint) {
|
2008-11-07 02:58:25 +00:00
|
|
|
/* we have a callback defined, use it */
|
|
|
|
r_ptr->data= cprop->lookupint(ptr, key, &r_ptr->type);
|
2008-10-31 23:50:02 +00:00
|
|
|
|
2008-11-07 02:58:25 +00:00
|
|
|
if(r_ptr->data) {
|
|
|
|
if(!r_ptr->type)
|
|
|
|
r_ptr->type= cprop->structtype;
|
|
|
|
rna_pointer_inherit_id(ptr, r_ptr);
|
2008-10-31 23:50:02 +00:00
|
|
|
|
2008-11-07 02:58:25 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
memset(r_ptr, 0, sizeof(*r_ptr));
|
|
|
|
return 0;
|
|
|
|
}
|
2008-10-31 23:50:02 +00:00
|
|
|
}
|
|
|
|
else {
|
2008-11-07 02:58:25 +00:00
|
|
|
/* no callback defined, just iterate and find the nth item */
|
2008-10-31 23:50:02 +00:00
|
|
|
CollectionPropertyIterator iter;
|
2008-11-07 02:58:25 +00:00
|
|
|
int i;
|
2008-10-31 23:50:02 +00:00
|
|
|
|
2008-11-07 02:58:25 +00:00
|
|
|
RNA_property_collection_begin(prop, &iter, ptr);
|
|
|
|
for(i=0; iter.valid; RNA_property_collection_next(prop, &iter), i++) {
|
|
|
|
if(i == key) {
|
2008-11-14 17:05:25 +00:00
|
|
|
*r_ptr= iter.ptr;
|
2008-10-31 23:50:02 +00:00
|
|
|
break;
|
2008-11-07 02:58:25 +00:00
|
|
|
}
|
2008-10-31 23:50:02 +00:00
|
|
|
}
|
2008-11-07 02:58:25 +00:00
|
|
|
RNA_property_collection_end(prop, &iter);
|
2008-10-31 23:50:02 +00:00
|
|
|
|
2008-11-07 02:58:25 +00:00
|
|
|
if(!iter.valid)
|
|
|
|
memset(r_ptr, 0, sizeof(*r_ptr));
|
2008-10-31 23:50:02 +00:00
|
|
|
|
2008-11-07 02:58:25 +00:00
|
|
|
return iter.valid;
|
2008-10-31 23:50:02 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-11-07 02:58:25 +00:00
|
|
|
int RNA_property_collection_lookup_string(PropertyRNA *prop, PointerRNA *ptr, const char *key, PointerRNA *r_ptr)
|
2008-10-31 23:50:02 +00:00
|
|
|
{
|
|
|
|
CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
|
|
|
|
|
|
|
|
if(cprop->lookupstring) {
|
2008-11-07 02:58:25 +00:00
|
|
|
/* we have a callback defined, use it */
|
|
|
|
r_ptr->data= cprop->lookupstring(ptr, key, &r_ptr->type);
|
2008-10-31 23:50:02 +00:00
|
|
|
|
2008-11-07 02:58:25 +00:00
|
|
|
if(r_ptr->data) {
|
|
|
|
if(!r_ptr->type)
|
|
|
|
r_ptr->type= cprop->structtype;
|
|
|
|
rna_pointer_inherit_id(ptr, r_ptr);
|
2008-10-31 23:50:02 +00:00
|
|
|
|
2008-11-07 02:58:25 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
memset(r_ptr, 0, sizeof(*r_ptr));
|
|
|
|
return 0;
|
|
|
|
}
|
2008-10-31 23:50:02 +00:00
|
|
|
}
|
|
|
|
else {
|
2008-11-07 02:58:25 +00:00
|
|
|
/* no callback defined, compare with name properties if they exist */
|
2008-10-31 23:50:02 +00:00
|
|
|
CollectionPropertyIterator iter;
|
2008-11-11 18:28:00 +00:00
|
|
|
PropertyRNA *nameprop;
|
2008-10-31 23:50:02 +00:00
|
|
|
char name[256], *nameptr;
|
|
|
|
int length, alloc, found= 0;
|
|
|
|
|
2008-11-07 02:58:25 +00:00
|
|
|
RNA_property_collection_begin(prop, &iter, ptr);
|
|
|
|
for(; iter.valid; RNA_property_collection_next(prop, &iter)) {
|
2008-11-14 17:05:25 +00:00
|
|
|
if(iter.ptr.data && iter.ptr.type->nameproperty) {
|
|
|
|
nameprop= iter.ptr.type->nameproperty;
|
2008-10-31 23:50:02 +00:00
|
|
|
|
2008-11-14 17:05:25 +00:00
|
|
|
length= RNA_property_string_length(nameprop, &iter.ptr);
|
2008-10-31 23:50:02 +00:00
|
|
|
|
2008-11-07 02:58:25 +00:00
|
|
|
if(sizeof(name)-1 < length) {
|
|
|
|
nameptr= name;
|
|
|
|
alloc= 0;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
nameptr= MEM_mallocN(sizeof(char)*length+1, "RNA_lookup_string");
|
|
|
|
alloc= 1;
|
|
|
|
}
|
2008-10-31 23:50:02 +00:00
|
|
|
|
2008-11-14 17:05:25 +00:00
|
|
|
RNA_property_string_get(nameprop, &iter.ptr, nameptr);
|
2008-10-31 23:50:02 +00:00
|
|
|
|
2008-11-07 02:58:25 +00:00
|
|
|
if(strcmp(nameptr, key) == 0) {
|
2008-11-14 17:05:25 +00:00
|
|
|
*r_ptr= iter.ptr;
|
2008-11-07 02:58:25 +00:00
|
|
|
found= 1;
|
2008-10-31 23:50:02 +00:00
|
|
|
}
|
2008-11-07 02:58:25 +00:00
|
|
|
|
|
|
|
if(alloc)
|
|
|
|
MEM_freeN(nameptr);
|
|
|
|
|
|
|
|
if(found)
|
|
|
|
break;
|
2008-10-31 23:50:02 +00:00
|
|
|
}
|
|
|
|
}
|
2008-11-07 02:58:25 +00:00
|
|
|
RNA_property_collection_end(prop, &iter);
|
2008-10-31 23:50:02 +00:00
|
|
|
|
2008-11-07 02:58:25 +00:00
|
|
|
if(!iter.valid)
|
|
|
|
memset(r_ptr, 0, sizeof(*r_ptr));
|
2008-10-31 23:50:02 +00:00
|
|
|
|
2008-11-07 02:58:25 +00:00
|
|
|
return iter.valid;
|
2008-10-31 23:50:02 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Standard iterator functions */
|
|
|
|
|
|
|
|
void rna_iterator_listbase_begin(CollectionPropertyIterator *iter, ListBase *lb)
|
|
|
|
{
|
|
|
|
iter->internal= lb->first;
|
|
|
|
iter->valid= (iter->internal != NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
void rna_iterator_listbase_next(CollectionPropertyIterator *iter)
|
|
|
|
{
|
|
|
|
iter->internal= ((Link*)iter->internal)->next;
|
|
|
|
iter->valid= (iter->internal != NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
void *rna_iterator_listbase_get(CollectionPropertyIterator *iter)
|
|
|
|
{
|
|
|
|
return iter->internal;
|
|
|
|
}
|
|
|
|
|
|
|
|
void rna_iterator_array_begin(CollectionPropertyIterator *iter, void *ptr, int itemsize, int length)
|
|
|
|
{
|
|
|
|
ArrayIterator *internal;
|
|
|
|
|
|
|
|
internal= MEM_callocN(sizeof(ArrayIterator), "ArrayIterator");
|
|
|
|
internal->ptr= ptr;
|
2008-11-01 00:23:08 +00:00
|
|
|
internal->endptr= ((char*)ptr)+length*itemsize;
|
2008-11-07 02:58:25 +00:00
|
|
|
internal->itemsize= itemsize;
|
2008-10-31 23:50:02 +00:00
|
|
|
|
|
|
|
iter->internal= internal;
|
|
|
|
iter->valid= (internal->ptr != internal->endptr);
|
|
|
|
}
|
|
|
|
|
|
|
|
void rna_iterator_array_next(CollectionPropertyIterator *iter)
|
|
|
|
{
|
|
|
|
ArrayIterator *internal= iter->internal;
|
|
|
|
|
|
|
|
internal->ptr += internal->itemsize;
|
|
|
|
iter->valid= (internal->ptr != internal->endptr);
|
|
|
|
}
|
|
|
|
|
|
|
|
void *rna_iterator_array_get(CollectionPropertyIterator *iter)
|
|
|
|
{
|
|
|
|
ArrayIterator *internal= iter->internal;
|
|
|
|
|
|
|
|
return internal->ptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
void rna_iterator_array_end(CollectionPropertyIterator *iter)
|
|
|
|
{
|
|
|
|
MEM_freeN(iter->internal);
|
|
|
|
}
|
|
|
|
|
2008-11-07 02:58:25 +00:00
|
|
|
/* RNA Path - Experiment */
|
|
|
|
|
|
|
|
static char *rna_path_token(const char **path, char *fixedbuf, int fixedlen, int bracket)
|
|
|
|
{
|
|
|
|
const char *p;
|
|
|
|
char *buf;
|
|
|
|
int i, j, len, escape;
|
|
|
|
|
|
|
|
len= 0;
|
|
|
|
|
|
|
|
if(bracket) {
|
|
|
|
/* get data between [], check escaping ] with \] */
|
|
|
|
if(**path == '[') (*path)++;
|
|
|
|
else return NULL;
|
|
|
|
|
|
|
|
p= *path;
|
|
|
|
|
|
|
|
escape= 0;
|
|
|
|
while(*p && (*p != ']' || escape)) {
|
|
|
|
escape= (*p == '\\');
|
|
|
|
len++;
|
|
|
|
p++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(*p != ']') return NULL;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* get data until . or [ */
|
|
|
|
p= *path;
|
|
|
|
|
|
|
|
while(*p && *p != '.' && *p != '[') {
|
|
|
|
len++;
|
|
|
|
p++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* empty, return */
|
|
|
|
if(len == 0)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
/* try to use fixed buffer if possible */
|
|
|
|
if(len+1 < fixedlen)
|
|
|
|
buf= fixedbuf;
|
|
|
|
else
|
|
|
|
buf= MEM_callocN(sizeof(char)*(len+1), "rna_path_token");
|
|
|
|
|
|
|
|
/* copy string, taking into account escaped ] */
|
|
|
|
for(p=*path, i=0, j=0; i<len; i++, p++) {
|
|
|
|
if(*p == '\\' && *(p+1) == ']');
|
|
|
|
else buf[j++]= *p;
|
|
|
|
}
|
|
|
|
|
|
|
|
buf[j]= 0;
|
|
|
|
|
|
|
|
/* set path to start of next token */
|
|
|
|
if(*p == ']') p++;
|
|
|
|
if(*p == '.') p++;
|
|
|
|
*path= p;
|
|
|
|
|
|
|
|
return buf;
|
|
|
|
}
|
|
|
|
|
|
|
|
int RNA_path_resolve(PointerRNA *ptr, const char *path, PointerRNA *r_ptr, PropertyRNA **r_prop)
|
|
|
|
{
|
2008-11-14 14:34:19 +00:00
|
|
|
CollectionPropertyIterator iter;
|
|
|
|
PropertyRNA *prop, *iterprop;
|
2008-11-07 02:58:25 +00:00
|
|
|
PointerRNA curptr, nextptr;
|
|
|
|
char fixedbuf[256], *token;
|
|
|
|
int len, intkey;
|
|
|
|
|
|
|
|
prop= NULL;
|
|
|
|
curptr= *ptr;
|
|
|
|
|
|
|
|
while(*path) {
|
|
|
|
/* look up property name in current struct */
|
|
|
|
token= rna_path_token(&path, fixedbuf, sizeof(fixedbuf), 0);
|
|
|
|
|
|
|
|
if(!token)
|
|
|
|
return 0;
|
|
|
|
|
2008-11-14 14:34:19 +00:00
|
|
|
iterprop= RNA_struct_iterator_property(&curptr);
|
|
|
|
RNA_property_collection_begin(iterprop, &iter, &curptr);
|
|
|
|
prop= NULL;
|
|
|
|
|
|
|
|
for(; iter.valid; RNA_property_collection_next(iterprop, &iter)) {
|
2008-11-14 18:46:57 +00:00
|
|
|
if(strcmp(token, RNA_property_identifier(iter.ptr.data, &iter.ptr)) == 0) {
|
2008-11-14 17:05:25 +00:00
|
|
|
prop= iter.ptr.data;
|
2008-11-07 02:58:25 +00:00
|
|
|
break;
|
2008-11-14 14:34:19 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
RNA_property_collection_end(iterprop, &iter);
|
2008-11-07 02:58:25 +00:00
|
|
|
|
|
|
|
if(token != fixedbuf)
|
|
|
|
MEM_freeN(token);
|
|
|
|
|
|
|
|
if(!prop)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
/* now look up the value of this property if it is a pointer or
|
|
|
|
* collection, otherwise return the property rna so that the
|
|
|
|
* caller can read the value of the property itself */
|
|
|
|
if(prop->type == PROP_POINTER) {
|
|
|
|
RNA_property_pointer_get(prop, &curptr, &nextptr);
|
|
|
|
|
|
|
|
if(nextptr.data)
|
|
|
|
curptr= nextptr;
|
|
|
|
else
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
else if(prop->type == PROP_COLLECTION && *path) {
|
|
|
|
/* resolve the lookup with [] brackets */
|
|
|
|
token= rna_path_token(&path, fixedbuf, sizeof(fixedbuf), 1);
|
|
|
|
|
|
|
|
if(!token)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
len= strlen(token);
|
|
|
|
|
|
|
|
/* check for "" to see if it is a string */
|
|
|
|
if(len >= 2 && *token == '"' && token[len-2] == '"') {
|
|
|
|
/* strip away "" */
|
|
|
|
token[len-2]= 0;
|
|
|
|
RNA_property_collection_lookup_string(prop, &curptr, token+1, &nextptr);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* otherwise do int lookup */
|
|
|
|
intkey= atoi(token);
|
|
|
|
RNA_property_collection_lookup_int(prop, &curptr, intkey, &nextptr);
|
|
|
|
}
|
|
|
|
|
|
|
|
if(token != fixedbuf)
|
|
|
|
MEM_freeN(token);
|
|
|
|
|
|
|
|
if(nextptr.data)
|
|
|
|
curptr= nextptr;
|
|
|
|
else
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
*r_ptr= curptr;
|
|
|
|
*r_prop= prop;
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
char *RNA_path_append(const char *path, PropertyRNA *prop, int intkey, const char *strkey)
|
|
|
|
{
|
|
|
|
DynStr *dynstr;
|
|
|
|
const char *s;
|
|
|
|
char appendstr[128], *result;
|
|
|
|
|
|
|
|
dynstr= BLI_dynstr_new();
|
|
|
|
|
2008-11-14 18:46:57 +00:00
|
|
|
/* add .identifier */
|
2008-11-07 02:58:25 +00:00
|
|
|
if(path) {
|
|
|
|
BLI_dynstr_append(dynstr, (char*)path);
|
|
|
|
if(*path)
|
|
|
|
BLI_dynstr_append(dynstr, ".");
|
|
|
|
}
|
|
|
|
|
2008-11-14 18:46:57 +00:00
|
|
|
BLI_dynstr_append(dynstr, (char*)prop->identifier);
|
2008-11-07 02:58:25 +00:00
|
|
|
|
|
|
|
if(prop->type == PROP_COLLECTION) {
|
|
|
|
/* add ["strkey"] or [intkey] */
|
|
|
|
BLI_dynstr_append(dynstr, "[");
|
|
|
|
|
|
|
|
if(strkey) {
|
|
|
|
BLI_dynstr_append(dynstr, "\"");
|
|
|
|
for(s=strkey; *s; s++) {
|
|
|
|
if(*s == '[') {
|
|
|
|
appendstr[0]= '\\';
|
|
|
|
appendstr[1]= *s;
|
|
|
|
appendstr[2]= 0;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
appendstr[0]= *s;
|
|
|
|
appendstr[1]= 0;
|
|
|
|
}
|
|
|
|
BLI_dynstr_append(dynstr, appendstr);
|
|
|
|
}
|
|
|
|
BLI_dynstr_append(dynstr, "\"");
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
sprintf(appendstr, "%d", intkey);
|
|
|
|
BLI_dynstr_append(dynstr, appendstr);
|
|
|
|
}
|
|
|
|
|
|
|
|
BLI_dynstr_append(dynstr, "]");
|
|
|
|
}
|
|
|
|
|
|
|
|
result= BLI_dynstr_get_cstring(dynstr);
|
|
|
|
BLI_dynstr_free(dynstr);
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
char *RNA_path_back(const char *path)
|
|
|
|
{
|
|
|
|
char fixedbuf[256];
|
|
|
|
const char *previous, *current;
|
|
|
|
char *result, *token;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
if(!path)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
previous= NULL;
|
|
|
|
current= path;
|
|
|
|
|
|
|
|
/* parse token by token until the end, then we back up to the previous
|
|
|
|
* position and strip of the next token to get the path one step back */
|
|
|
|
while(*current) {
|
|
|
|
token= rna_path_token(¤t, fixedbuf, sizeof(fixedbuf), 0);
|
|
|
|
|
|
|
|
if(!token)
|
|
|
|
return NULL;
|
|
|
|
if(token != fixedbuf)
|
|
|
|
MEM_freeN(token);
|
|
|
|
|
|
|
|
/* in case of collection we also need to strip off [] */
|
|
|
|
token= rna_path_token(¤t, fixedbuf, sizeof(fixedbuf), 1);
|
|
|
|
if(token && token != fixedbuf)
|
|
|
|
MEM_freeN(token);
|
|
|
|
|
|
|
|
if(!*current)
|
|
|
|
break;
|
|
|
|
|
|
|
|
previous= current;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!previous)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
/* copy and strip off last token */
|
|
|
|
i= previous - path;
|
|
|
|
result= BLI_strdup(path);
|
|
|
|
|
|
|
|
if(i > 0 && result[i-1] == '.') i--;
|
|
|
|
result[i]= 0;
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|