Changeset View
Changeset View
Standalone View
Standalone View
source/blender/python/intern/bpy_rna.c
| Show First 20 Lines • Show All 1,630 Lines • ▼ Show 20 Lines | else { | ||||
| /* see if we can coerce into a python type - PropertyType */ | /* see if we can coerce into a python type - PropertyType */ | ||||
| switch (type) { | switch (type) { | ||||
| case PROP_BOOLEAN: | case PROP_BOOLEAN: | ||||
| { | { | ||||
| int param; | int param; | ||||
| /* prefer not to have an exception here | /* prefer not to have an exception here | ||||
| * however so many poll functions return None or a valid Object. | * however so many poll functions return None or a valid Object. | ||||
| * its a hassle to convert these into a bool before returning, */ | * its a hassle to convert these into a bool before returning, */ | ||||
| if (RNA_property_flag(prop) & PROP_OUTPUT) { | if (RNA_parameter_flag(prop) & PARM_OUTPUT) { | ||||
| param = PyObject_IsTrue(value); | param = PyObject_IsTrue(value); | ||||
| } | } | ||||
| else { | else { | ||||
| param = PyLong_AsLong(value); | param = PyLong_AsLong(value); | ||||
| if (UNLIKELY(param & ~1)) { /* only accept 0/1 */ | if (UNLIKELY(param & ~1)) { /* only accept 0/1 */ | ||||
| param = -1; /* error out below */ | param = -1; /* error out below */ | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 171 Lines • ▼ Show 20 Lines | #endif /* USE_STRING_COERCE */ | ||||
| break; | break; | ||||
| } | } | ||||
| case PROP_POINTER: | case PROP_POINTER: | ||||
| { | { | ||||
| PyObject *value_new = NULL; | PyObject *value_new = NULL; | ||||
| StructRNA *ptr_type = RNA_property_pointer_type(ptr, prop); | StructRNA *ptr_type = RNA_property_pointer_type(ptr, prop); | ||||
| int flag = RNA_property_flag(prop); | int flag = RNA_property_flag(prop); | ||||
| int flag_parameter = RNA_parameter_flag(prop); | |||||
| /* this is really nasty!, so we can fake the operator having direct properties eg: | /* this is really nasty!, so we can fake the operator having direct properties eg: | ||||
| * layout.prop(self, "filepath") | * layout.prop(self, "filepath") | ||||
| * ... which in fact should be | * ... which in fact should be | ||||
| * layout.prop(self.properties, "filepath") | * layout.prop(self.properties, "filepath") | ||||
| * | * | ||||
| * we need to do this trick. | * we need to do this trick. | ||||
| * if the prop is not an operator type and the pyobject is an operator, | * if the prop is not an operator type and the pyobject is an operator, | ||||
| ▲ Show 20 Lines • Show All 60 Lines • ▼ Show 20 Lines | #endif /* USE_STRING_COERCE */ | ||||
| RNA_property_identifier(prop)); | RNA_property_identifier(prop)); | ||||
| Py_XDECREF(value_new); return -1; | Py_XDECREF(value_new); return -1; | ||||
| } | } | ||||
| else { | else { | ||||
| BPy_StructRNA *param = (BPy_StructRNA *)value; | BPy_StructRNA *param = (BPy_StructRNA *)value; | ||||
| bool raise_error = false; | bool raise_error = false; | ||||
| if (data) { | if (data) { | ||||
| if (flag & PROP_RNAPTR) { | if (flag_parameter & PARM_RNAPTR) { | ||||
| if (flag & PROP_THICK_WRAP) { | if (flag & PROP_THICK_WRAP) { | ||||
| if (value == Py_None) | if (value == Py_None) | ||||
| memset(data, 0, sizeof(PointerRNA)); | memset(data, 0, sizeof(PointerRNA)); | ||||
| else if (RNA_struct_is_a(param->ptr.type, ptr_type)) | else if (RNA_struct_is_a(param->ptr.type, ptr_type)) | ||||
| *((PointerRNA *)data) = param->ptr; | *((PointerRNA *)data) = param->ptr; | ||||
| else | else | ||||
| raise_error = true; | raise_error = true; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 3,199 Lines • ▼ Show 20 Lines | static PyObject *pyrna_prop_new(PyTypeObject *type, PyObject *args, PyObject *UNUSED(kwds)) | ||||
| } | } | ||||
| } | } | ||||
| static PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *data) | static PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *data) | ||||
| { | { | ||||
| PyObject *ret; | PyObject *ret; | ||||
| const int type = RNA_property_type(prop); | const int type = RNA_property_type(prop); | ||||
| const int flag = RNA_property_flag(prop); | const int flag = RNA_property_flag(prop); | ||||
| const int flag_parameter = RNA_parameter_flag(prop); | |||||
| if (RNA_property_array_check(prop)) { | if (RNA_property_array_check(prop)) { | ||||
| int a, len; | int a, len; | ||||
| if (flag & PROP_DYNAMIC) { | if (flag & PROP_DYNAMIC) { | ||||
| ParameterDynAlloc *data_alloc = data; | ParameterDynAlloc *data_alloc = data; | ||||
| len = data_alloc->array_tot; | len = data_alloc->array_tot; | ||||
| data = data_alloc->array; | data = data_alloc->array; | ||||
| ▲ Show 20 Lines • Show All 101 Lines • ▼ Show 20 Lines | #endif | ||||
| ret = pyrna_enum_to_py(ptr, prop, *(int *)data); | ret = pyrna_enum_to_py(ptr, prop, *(int *)data); | ||||
| break; | break; | ||||
| } | } | ||||
| case PROP_POINTER: | case PROP_POINTER: | ||||
| { | { | ||||
| PointerRNA newptr; | PointerRNA newptr; | ||||
| StructRNA *ptype = RNA_property_pointer_type(ptr, prop); | StructRNA *ptype = RNA_property_pointer_type(ptr, prop); | ||||
| if (flag & PROP_RNAPTR) { | if (flag_parameter & PARM_RNAPTR) { | ||||
| /* in this case we get the full ptr */ | /* in this case we get the full ptr */ | ||||
| newptr = *(PointerRNA *)data; | newptr = *(PointerRNA *)data; | ||||
| } | } | ||||
| else { | else { | ||||
| if (RNA_struct_is_ID(ptype)) { | if (RNA_struct_is_ID(ptype)) { | ||||
| RNA_id_pointer_create(*(void **)data, &newptr); | RNA_id_pointer_create(*(void **)data, &newptr); | ||||
| } | } | ||||
| else { | else { | ||||
| ▲ Show 20 Lines • Show All 65 Lines • ▼ Show 20 Lines | static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject *kw) | ||||
| PointerRNA *self_ptr = &self->ptr; | PointerRNA *self_ptr = &self->ptr; | ||||
| FunctionRNA *self_func = self->func; | FunctionRNA *self_func = self->func; | ||||
| PointerRNA funcptr; | PointerRNA funcptr; | ||||
| ParameterList parms; | ParameterList parms; | ||||
| ParameterIterator iter; | ParameterIterator iter; | ||||
| PropertyRNA *parm; | PropertyRNA *parm; | ||||
| PyObject *ret, *item; | PyObject *ret, *item; | ||||
| int i, pyargs_len, pykw_len, parms_len, ret_len, flag, err = 0, kw_tot = 0; | int i, pyargs_len, pykw_len, parms_len, ret_len, flag_parameter, err = 0, kw_tot = 0; | ||||
| bool kw_arg; | bool kw_arg; | ||||
| PropertyRNA *pret_single = NULL; | PropertyRNA *pret_single = NULL; | ||||
| void *retdata_single = NULL; | void *retdata_single = NULL; | ||||
| /* enable this so all strings are copied and freed after calling. | /* enable this so all strings are copied and freed after calling. | ||||
| * this exposes bugs where the pointer to the string is held and re-used */ | * this exposes bugs where the pointer to the string is held and re-used */ | ||||
| // #define DEBUG_STRING_FREE | // #define DEBUG_STRING_FREE | ||||
| ▲ Show 20 Lines • Show All 48 Lines • ▼ Show 20 Lines | PyErr_Format(PyExc_TypeError, | ||||
| RNA_struct_identifier(self_ptr->type), RNA_function_identifier(self_func), | RNA_struct_identifier(self_ptr->type), RNA_function_identifier(self_func), | ||||
| parms_len, pyargs_len + pykw_len); | parms_len, pyargs_len + pykw_len); | ||||
| err = -1; | err = -1; | ||||
| } | } | ||||
| /* parse function parameters */ | /* parse function parameters */ | ||||
| for (i = 0; iter.valid && err == 0; RNA_parameter_list_next(&iter)) { | for (i = 0; iter.valid && err == 0; RNA_parameter_list_next(&iter)) { | ||||
| parm = iter.parm; | parm = iter.parm; | ||||
| flag = RNA_property_flag(parm); | flag_parameter = RNA_parameter_flag(parm); | ||||
| /* only useful for single argument returns, we'll need another list loop for multiple */ | /* only useful for single argument returns, we'll need another list loop for multiple */ | ||||
| if (flag & PROP_OUTPUT) { | if (flag_parameter & PARM_OUTPUT) { | ||||
| ret_len++; | ret_len++; | ||||
| if (pret_single == NULL) { | if (pret_single == NULL) { | ||||
| pret_single = parm; | pret_single = parm; | ||||
| retdata_single = iter.data; | retdata_single = iter.data; | ||||
| } | } | ||||
| continue; | continue; | ||||
| } | } | ||||
| Show All 14 Lines | #endif | ||||
| kw_tot++; /* make sure invalid keywords are not given */ | kw_tot++; /* make sure invalid keywords are not given */ | ||||
| kw_arg = true; | kw_arg = true; | ||||
| } | } | ||||
| i++; /* current argument */ | i++; /* current argument */ | ||||
| if (item == NULL) { | if (item == NULL) { | ||||
| if (flag & PROP_REQUIRED) { | if (flag_parameter & PARM_REQUIRED) { | ||||
| PyErr_Format(PyExc_TypeError, | PyErr_Format(PyExc_TypeError, | ||||
| "%.200s.%.200s(): required parameter \"%.200s\" not specified", | "%.200s.%.200s(): required parameter \"%.200s\" not specified", | ||||
| RNA_struct_identifier(self_ptr->type), | RNA_struct_identifier(self_ptr->type), | ||||
| RNA_function_identifier(self_func), | RNA_function_identifier(self_func), | ||||
| RNA_property_identifier(parm)); | RNA_property_identifier(parm)); | ||||
| err = -1; | err = -1; | ||||
| break; | break; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 83 Lines • ▼ Show 20 Lines | if (err == 0 && kw && (pykw_len > kw_tot)) { | ||||
| } | } | ||||
| /* list good args */ | /* list good args */ | ||||
| first = true; | first = true; | ||||
| RNA_parameter_list_begin(&parms, &iter); | RNA_parameter_list_begin(&parms, &iter); | ||||
| for (; iter.valid; RNA_parameter_list_next(&iter)) { | for (; iter.valid; RNA_parameter_list_next(&iter)) { | ||||
| parm = iter.parm; | parm = iter.parm; | ||||
| if (RNA_property_flag(parm) & PROP_OUTPUT) | if (RNA_parameter_flag(parm) & PARM_OUTPUT) | ||||
| continue; | continue; | ||||
| BLI_dynstr_appendf(good_args, first ? "%s" : ", %s", RNA_property_identifier(parm)); | BLI_dynstr_appendf(good_args, first ? "%s" : ", %s", RNA_property_identifier(parm)); | ||||
| first = false; | first = false; | ||||
| } | } | ||||
| RNA_parameter_list_end(&iter); | RNA_parameter_list_end(&iter); | ||||
| Show All 30 Lines | if (err != -1) { | ||||
| if (ret_len > 1) { | if (ret_len > 1) { | ||||
| ret = PyTuple_New(ret_len); | ret = PyTuple_New(ret_len); | ||||
| i = 0; /* arg index */ | i = 0; /* arg index */ | ||||
| RNA_parameter_list_begin(&parms, &iter); | RNA_parameter_list_begin(&parms, &iter); | ||||
| for (; iter.valid; RNA_parameter_list_next(&iter)) { | for (; iter.valid; RNA_parameter_list_next(&iter)) { | ||||
| parm = iter.parm; | parm = iter.parm; | ||||
| flag = RNA_property_flag(parm); | |||||
| if (flag & PROP_OUTPUT) | if (RNA_parameter_flag(parm) & PARM_OUTPUT) | ||||
| PyTuple_SET_ITEM(ret, i++, pyrna_param_to_py(&funcptr, parm, iter.data)); | PyTuple_SET_ITEM(ret, i++, pyrna_param_to_py(&funcptr, parm, iter.data)); | ||||
| } | } | ||||
| RNA_parameter_list_end(&iter); | RNA_parameter_list_end(&iter); | ||||
| } | } | ||||
| else | else | ||||
| ret = pyrna_param_to_py(&funcptr, pret_single, retdata_single); | ret = pyrna_param_to_py(&funcptr, pret_single, retdata_single); | ||||
| ▲ Show 20 Lines • Show All 1,636 Lines • ▼ Show 20 Lines | static int rna_function_arg_count(FunctionRNA *func, int *min_count) | ||||
| Link *link; | Link *link; | ||||
| int flag = RNA_function_flag(func); | int flag = RNA_function_flag(func); | ||||
| const bool is_staticmethod = (flag & FUNC_NO_SELF) && !(flag & FUNC_USE_SELF_TYPE); | const bool is_staticmethod = (flag & FUNC_NO_SELF) && !(flag & FUNC_USE_SELF_TYPE); | ||||
| int count = is_staticmethod ? 0 : 1; | int count = is_staticmethod ? 0 : 1; | ||||
| bool done_min_count = false; | bool done_min_count = false; | ||||
| for (link = lb->first; link; link = link->next) { | for (link = lb->first; link; link = link->next) { | ||||
| parm = (PropertyRNA *)link; | parm = (PropertyRNA *)link; | ||||
| if (!(RNA_property_flag(parm) & PROP_OUTPUT)) { | if (!(RNA_parameter_flag(parm) & PARM_OUTPUT)) { | ||||
| if (!done_min_count && (RNA_property_flag(parm) & PROP_PYFUNC_OPTIONAL)) { | if (!done_min_count && (RNA_parameter_flag(parm) & PARM_PYFUNC_OPTIONAL)) { | ||||
| /* From now on, following parameters are optional in py func */ | /* From now on, following parameters are optional in py func */ | ||||
| if (min_count) | if (min_count) | ||||
| *min_count = count; | *min_count = count; | ||||
| done_min_count = true; | done_min_count = true; | ||||
| } | } | ||||
| count++; | count++; | ||||
| } | } | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 341 Lines • ▼ Show 20 Lines | // args = PyTuple_New(rna_function_arg_count(func)); /* first arg is included in 'item' */ | ||||
| i = 1; | i = 1; | ||||
| } | } | ||||
| RNA_parameter_list_begin(parms, &iter); | RNA_parameter_list_begin(parms, &iter); | ||||
| /* parse function parameters */ | /* parse function parameters */ | ||||
| for (; iter.valid; RNA_parameter_list_next(&iter)) { | for (; iter.valid; RNA_parameter_list_next(&iter)) { | ||||
| parm = iter.parm; | parm = iter.parm; | ||||
| flag = RNA_property_flag(parm); | |||||
| /* only useful for single argument returns, we'll need another list loop for multiple */ | /* only useful for single argument returns, we'll need another list loop for multiple */ | ||||
| if (flag & PROP_OUTPUT) { | if (RNA_parameter_flag(parm) & PARM_OUTPUT) { | ||||
| ret_len++; | ret_len++; | ||||
| if (pret_single == NULL) { | if (pret_single == NULL) { | ||||
| pret_single = parm; | pret_single = parm; | ||||
| retdata_single = iter.data; | retdata_single = iter.data; | ||||
| } | } | ||||
| continue; | continue; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 83 Lines • ▼ Show 20 Lines | else if (ret_len > 1) { | ||||
| } | } | ||||
| else { | else { | ||||
| RNA_parameter_list_begin(parms, &iter); | RNA_parameter_list_begin(parms, &iter); | ||||
| /* parse function parameters */ | /* parse function parameters */ | ||||
| for (i = 0; iter.valid; RNA_parameter_list_next(&iter)) { | for (i = 0; iter.valid; RNA_parameter_list_next(&iter)) { | ||||
| parm = iter.parm; | parm = iter.parm; | ||||
| flag = RNA_property_flag(parm); | |||||
| /* only useful for single argument returns, we'll need another list loop for multiple */ | /* only useful for single argument returns, we'll need another list loop for multiple */ | ||||
| if (flag & PROP_OUTPUT) { | if (RNA_parameter_flag(parm) & PARM_OUTPUT) { | ||||
| err = pyrna_py_to_prop(&funcptr, parm, iter.data, | err = pyrna_py_to_prop(&funcptr, parm, iter.data, | ||||
| PyTuple_GET_ITEM(ret, i++), | PyTuple_GET_ITEM(ret, i++), | ||||
| "calling class function:"); | "calling class function:"); | ||||
| if (err) { | if (err) { | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 269 Lines • ▼ Show 20 Lines | static int pyrna_srna_contains_pointer_prop_srna( | ||||
| PropertyRNA *prop; | PropertyRNA *prop; | ||||
| LinkData *link; | LinkData *link; | ||||
| /* verify properties */ | /* verify properties */ | ||||
| const ListBase *lb = RNA_struct_type_properties(srna); | const ListBase *lb = RNA_struct_type_properties(srna); | ||||
| for (link = lb->first; link; link = link->next) { | for (link = lb->first; link; link = link->next) { | ||||
| prop = (PropertyRNA *)link; | prop = (PropertyRNA *)link; | ||||
| if (RNA_property_type(prop) == PROP_POINTER && !(RNA_property_flag(prop) & PROP_BUILTIN)) { | if (RNA_property_type(prop) == PROP_POINTER && !RNA_property_builtin(prop)) { | ||||
| PointerRNA tptr; | PointerRNA tptr; | ||||
| RNA_pointer_create(NULL, &RNA_Struct, srna_props, &tptr); | RNA_pointer_create(NULL, &RNA_Struct, srna_props, &tptr); | ||||
| if (RNA_property_pointer_type(&tptr, prop) == srna) { | if (RNA_property_pointer_type(&tptr, prop) == srna) { | ||||
| *r_prop_identifier = RNA_property_identifier(prop); | *r_prop_identifier = RNA_property_identifier(prop); | ||||
| return 1; | return 1; | ||||
| } | } | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 153 Lines • Show Last 20 Lines | |||||