diff options
author | Tamito Kajiyama <rd6t-kjym@asahi-net.or.jp> | 2013-01-12 06:02:53 +0400 |
---|---|---|
committer | Tamito Kajiyama <rd6t-kjym@asahi-net.or.jp> | 2013-01-12 06:02:53 +0400 |
commit | 94ae0232b0337ab70cecaef03cd845887cd36eaa (patch) | |
tree | caea2819c7fe0400fb91c9bdf0e99a9e0fd50cf6 /source/blender/python | |
parent | 9a109c22ae1ef8a5c75932d661610b23ec685bd7 (diff) | |
parent | f68e9db583489d541d535791536ea20bc1ae1d76 (diff) |
Merged changes in the trunk up to revision 53729.
Conflicts resolved:
release/datafiles/startup.blend
source/blender/blenloader/intern/readfile.c
Diffstat (limited to 'source/blender/python')
24 files changed, 1835 insertions, 479 deletions
diff --git a/source/blender/python/BPY_extern.h b/source/blender/python/BPY_extern.h index 9bd45d2b759..13cb11d1301 100644 --- a/source/blender/python/BPY_extern.h +++ b/source/blender/python/BPY_extern.h @@ -66,7 +66,7 @@ void BPY_python_end(void); /* 2.5 UI Scripts */ int BPY_filepath_exec(struct bContext *C, const char *filepath, struct ReportList *reports); -int BPY_text_exec(struct bContext *C, struct Text *text, struct ReportList *reports, const short do_jump); +int BPY_text_exec(struct bContext *C, struct Text *text, struct ReportList *reports, const bool do_jump); void BPY_text_free_code(struct Text *text); void BPY_modules_update(struct bContext *C); // XXX - annoying, need this for pointers that get out of date void BPY_modules_load_user(struct bContext *C); diff --git a/source/blender/python/bmesh/bmesh_py_ops_call.c b/source/blender/python/bmesh/bmesh_py_ops_call.c index ded35363287..32315195072 100644 --- a/source/blender/python/bmesh/bmesh_py_ops_call.c +++ b/source/blender/python/bmesh/bmesh_py_ops_call.c @@ -523,7 +523,7 @@ static int bpy_slot_from_py(BMesh *bm, BMOperator *bmop, BMOpSlot *slot, PyObjec * * \note Don't throw any exceptions and should always return a valid (PyObject *). */ -static PyObject* bpy_slot_to_py(BMesh *bm, BMOpSlot *slot) +static PyObject *bpy_slot_to_py(BMesh *bm, BMOpSlot *slot) { PyObject *item = NULL; diff --git a/source/blender/python/bmesh/bmesh_py_types.c b/source/blender/python/bmesh/bmesh_py_types.c index f39e170c481..37376cc7610 100644 --- a/source/blender/python/bmesh/bmesh_py_types.c +++ b/source/blender/python/bmesh/bmesh_py_types.c @@ -1631,6 +1631,21 @@ static PyObject *bpy_bmface_normal_update(BPy_BMFace *self) } +PyDoc_STRVAR(bpy_bmface_normal_flip_doc, +".. method:: normal_flip()\n" +"\n" +" Reverses winding of a face, which flips its normal.\n" +); +static PyObject *bpy_bmface_normal_flip(BPy_BMFace *self) +{ + BPY_BM_CHECK_OBJ(self); + + BM_face_normal_flip(self->bm, self->f); + + Py_RETURN_NONE; +} + + /* Loop * ---- */ @@ -2439,6 +2454,7 @@ static struct PyMethodDef bpy_bmface_methods[] = { {"calc_center_bounds", (PyCFunction)bpy_bmface_calc_center_bounds, METH_NOARGS, bpy_bmface_calc_center_bounds_doc}, {"normal_update", (PyCFunction)bpy_bmface_normal_update, METH_NOARGS, bpy_bmface_normal_update_doc}, + {"normal_flip", (PyCFunction)bpy_bmface_normal_flip, METH_NOARGS, bpy_bmface_normal_flip_doc}, {NULL, NULL, 0, NULL} }; diff --git a/source/blender/python/bmesh/bmesh_py_types_customdata.c b/source/blender/python/bmesh/bmesh_py_types_customdata.c index fd31f3c40cc..4a8f8d49f35 100644 --- a/source/blender/python/bmesh/bmesh_py_types_customdata.c +++ b/source/blender/python/bmesh/bmesh_py_types_customdata.c @@ -981,7 +981,7 @@ PyObject *BPy_BMLayerItem_GetItem(BPy_BMElem *py_ele, BPy_BMLayerItem *py_layer) case CD_PROP_STR: { MStringProperty *mstring = value; - ret = PyBytes_FromStringAndSize(mstring->s, BLI_strnlen(mstring->s, sizeof(mstring->s))); + ret = PyBytes_FromStringAndSize(mstring->s, mstring->s_len); break; } case CD_MTEXPOLY: @@ -1067,13 +1067,17 @@ int BPy_BMLayerItem_SetItem(BPy_BMElem *py_ele, BPy_BMLayerItem *py_layer, PyObj case CD_PROP_STR: { MStringProperty *mstring = value; - const char *tmp_val = PyBytes_AsString(py_value); - if (UNLIKELY(tmp_val == NULL)) { + char *tmp_val; + Py_ssize_t tmp_val_len; + if (UNLIKELY(PyBytes_AsStringAndSize(py_value, &tmp_val, &tmp_val_len) == -1)) { PyErr_Format(PyExc_TypeError, "expected bytes, not a %.200s", Py_TYPE(py_value)->tp_name); ret = -1; } else { - BLI_strncpy(mstring->s, tmp_val, min_ii(PyBytes_Size(py_value), sizeof(mstring->s))); + if (tmp_val_len > sizeof(mstring->s)) + tmp_val_len = sizeof(mstring->s); + memcpy(mstring->s, tmp_val, tmp_val_len); + mstring->s_len = tmp_val_len; } break; } diff --git a/source/blender/python/generic/bpy_internal_import.h b/source/blender/python/generic/bpy_internal_import.h index 1592ec52b4c..56cdf677ccb 100644 --- a/source/blender/python/generic/bpy_internal_import.h +++ b/source/blender/python/generic/bpy_internal_import.h @@ -48,9 +48,9 @@ struct Text; void bpy_import_init(PyObject *builtins); -PyObject* bpy_text_import(struct Text *text); -PyObject* bpy_text_import_name(const char *name, int *found); -PyObject* bpy_text_reimport(PyObject *module, int *found); +PyObject *bpy_text_import(struct Text *text); +PyObject *bpy_text_import_name(const char *name, int *found); +PyObject *bpy_text_reimport(PyObject *module, int *found); /* void bpy_text_clear_modules(int clear_all);*/ /* Clear user modules */ void bpy_text_filename_get(char *fn, size_t fn_len, struct Text *text); diff --git a/source/blender/python/generic/py_capi_utils.c b/source/blender/python/generic/py_capi_utils.c index 9a064923736..56d9e2ac0dd 100644 --- a/source/blender/python/generic/py_capi_utils.c +++ b/source/blender/python/generic/py_capi_utils.c @@ -33,6 +33,8 @@ #include <Python.h> #include <frameobject.h> +#include "BLI_utildefines.h" /* for bool */ + #include "py_capi_utils.h" /* only for BLI_strncpy_wchar_from_utf8, should replace with py funcs but too late in release now */ @@ -44,7 +46,7 @@ /* array utility function */ int PyC_AsArray(void *array, PyObject *value, const Py_ssize_t length, - const PyTypeObject *type, const short is_double, const char *error_prefix) + const PyTypeObject *type, const bool is_double, const char *error_prefix) { PyObject *value_fast; Py_ssize_t value_len; @@ -112,6 +114,54 @@ int PyC_AsArray(void *array, PyObject *value, const Py_ssize_t length, return 0; } +/* array utility function */ +PyObject *PyC_FromArray(const void *array, int length, const PyTypeObject *type, + const bool is_double, const char *error_prefix) +{ + PyObject *tuple; + int i; + + tuple = PyTuple_New(length); + + /* for each type */ + if (type == &PyFloat_Type) { + if (is_double) { + const double *array_double = array; + for (i = 0; i < length; ++i) { + PyTuple_SET_ITEM(tuple, i, PyFloat_FromDouble(array_double[i])); + } + } + else { + const float *array_float = array; + for (i = 0; i < length; ++i) { + PyTuple_SET_ITEM(tuple, i, PyFloat_FromDouble(array_float[i])); + } + } + } + else if (type == &PyLong_Type) { + /* could use is_double for 'long int' but no use now */ + const int *array_int = array; + for (i = 0; i < length; ++i) { + PyTuple_SET_ITEM(tuple, i, PyLong_FromLong(array_int[i])); + } + } + else if (type == &PyBool_Type) { + const int *array_bool = array; + for (i = 0; i < length; ++i) { + PyTuple_SET_ITEM(tuple, i, PyBool_FromLong(array_bool[i])); + } + } + else { + Py_DECREF(tuple); + PyErr_Format(PyExc_TypeError, + "%s: internal error %s is invalid", + error_prefix, type->tp_name); + return NULL; + } + + return tuple; +} + /* for debugging */ void PyC_ObSpit(const char *name, PyObject *var) diff --git a/source/blender/python/generic/py_capi_utils.h b/source/blender/python/generic/py_capi_utils.h index db582bd7086..239858032de 100644 --- a/source/blender/python/generic/py_capi_utils.h +++ b/source/blender/python/generic/py_capi_utils.h @@ -38,7 +38,9 @@ PyObject * PyC_Err_Format_Prefix(PyObject *exception_type_prefix, const char *f void PyC_FileAndNum(const char **filename, int *lineno); void PyC_FileAndNum_Safe(const char **filename, int *lineno); /* checks python is running */ int PyC_AsArray(void *array, PyObject *value, const Py_ssize_t length, - const PyTypeObject *type, const short is_double, const char *error_prefix); + const PyTypeObject *type, const bool is_double, const char *error_prefix); +PyObject * PyC_FromArray(const void *array, int length, const PyTypeObject *type, + const bool is_double, const char *error_prefix); /* follow http://www.python.org/dev/peps/pep-0383/ */ PyObject * PyC_UnicodeFromByte(const char *str); diff --git a/source/blender/python/intern/bpy.c b/source/blender/python/intern/bpy.c index c4d8f8ee9b8..1f8385288bd 100644 --- a/source/blender/python/intern/bpy.c +++ b/source/blender/python/intern/bpy.c @@ -35,19 +35,19 @@ #include "RNA_types.h" #include "RNA_access.h" -#include "bpy.h" -#include "bpy_util.h" +#include "BLI_path_util.h" +#include "BLI_string.h" +#include "BKE_bpath.h" +#include "BLI_utildefines.h" + +#include "bpy.h" +#include "bpy_util.h" #include "bpy_rna.h" #include "bpy_app.h" #include "bpy_props.h" #include "bpy_library.h" #include "bpy_operator.h" -#include "BLI_path_util.h" -#include "BLI_string.h" -#include "BKE_bpath.h" -#include "BLI_utildefines.h" - #include "BKE_main.h" #include "BKE_global.h" /* XXX, G.main only */ #include "BKE_blender.h" @@ -98,7 +98,7 @@ static int bpy_blend_paths_visit_cb(void *userdata, char *UNUSED(path_dst), cons PyObject *item = PyUnicode_DecodeFSDefault(path_src); PyList_Append(list, item); Py_DECREF(item); - return FALSE; /* never edits the path */ + return false; /* never edits the path */ } PyDoc_STRVAR(bpy_blend_paths_doc, @@ -120,9 +120,9 @@ static PyObject *bpy_blend_paths(PyObject *UNUSED(self), PyObject *args, PyObjec int flag = 0; PyObject *list; - int absolute = FALSE; - int packed = FALSE; - int local = FALSE; + int absolute = false; + int packed = false; + int local = false; static const char *kwlist[] = {"absolute", "packed", "local", NULL}; if (!PyArg_ParseTupleAndKeywords(args, kw, "|iii:blend_paths", @@ -209,7 +209,7 @@ static PyObject *bpy_resource_path(PyObject *UNUSED(self), PyObject *args, PyObj return NULL; } - path = BLI_get_folder_version(folder_id, (major * 100) + minor, FALSE); + path = BLI_get_folder_version(folder_id, (major * 100) + minor, false); return PyUnicode_DecodeFSDefault(path ? path : ""); } diff --git a/source/blender/python/intern/bpy_app.c b/source/blender/python/intern/bpy_app.c index 784ce2f93e0..65568e9a0c1 100644 --- a/source/blender/python/intern/bpy_app.c +++ b/source/blender/python/intern/bpy_app.c @@ -182,7 +182,7 @@ static int bpy_app_debug_set(PyObject *UNUSED(self), PyObject *value, void *clos const int flag = GET_INT_FROM_POINTER(closure); const int param = PyObject_IsTrue(value); - if (param < 0) { + if (param == -1) { PyErr_SetString(PyExc_TypeError, "bpy.app.debug can only be True/False"); return -1; } diff --git a/source/blender/python/intern/bpy_app_ffmpeg.c b/source/blender/python/intern/bpy_app_ffmpeg.c index 5ae2a11710a..3bf3dec3872 100644 --- a/source/blender/python/intern/bpy_app_ffmpeg.c +++ b/source/blender/python/intern/bpy_app_ffmpeg.c @@ -41,16 +41,16 @@ static PyTypeObject BlenderAppFFmpegType; #define DEF_FFMPEG_LIB_VERSION(lib) \ {(char *)(#lib "_version"), (char *)("The " #lib " version as a tuple of 3 numbers")}, \ - {(char *)(#lib "_version_string"), (char *)("The " #lib " version formatted as a string")}, + {(char *)(#lib "_version_string"), (char *)("The " #lib " version formatted as a string")} static PyStructSequence_Field app_ffmpeg_info_fields[] = { {(char *)"supported", (char *)("Boolean, True when Blender is built with FFmpeg support")}, - DEF_FFMPEG_LIB_VERSION(avcodec) - DEF_FFMPEG_LIB_VERSION(avdevice) - DEF_FFMPEG_LIB_VERSION(avformat) - DEF_FFMPEG_LIB_VERSION(avutil) - DEF_FFMPEG_LIB_VERSION(swscale) + DEF_FFMPEG_LIB_VERSION(avcodec), + DEF_FFMPEG_LIB_VERSION(avdevice), + DEF_FFMPEG_LIB_VERSION(avformat), + DEF_FFMPEG_LIB_VERSION(avutil), + DEF_FFMPEG_LIB_VERSION(swscale), {NULL} }; diff --git a/source/blender/python/intern/bpy_driver.c b/source/blender/python/intern/bpy_driver.c index 9a79616c23b..c49794ad37a 100644 --- a/source/blender/python/intern/bpy_driver.c +++ b/source/blender/python/intern/bpy_driver.c @@ -122,7 +122,7 @@ static void bpy_pydriver_update_dict(const float evaltime) void BPY_driver_reset(void) { PyGILState_STATE gilstate; - int use_gil = TRUE; /* !PYC_INTERPRETER_ACTIVE; */ + bool use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */ if (use_gil) gilstate = PyGILState_Ensure(); @@ -175,7 +175,7 @@ float BPY_driver_exec(ChannelDriver *driver, const float evaltime) PyObject *expr_vars; /* speed up by pre-hashing string & avoids re-converting unicode strings for every execution */ PyObject *expr_code; PyGILState_STATE gilstate; - int use_gil; + bool use_gil; DriverVar *dvar; double result = 0.0; /* default return */ @@ -193,7 +193,7 @@ float BPY_driver_exec(ChannelDriver *driver, const float evaltime) return 0.0f; } - use_gil = TRUE; /* !PYC_INTERPRETER_ACTIVE; */ + use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */ if (use_gil) gilstate = PyGILState_Ensure(); diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c index 7bce8673943..e9fa00c7868 100644 --- a/source/blender/python/intern/bpy_interface.c +++ b/source/blender/python/intern/bpy_interface.c @@ -39,6 +39,15 @@ #include "MEM_guardedalloc.h" +#include "BLI_path_util.h" +#include "BLI_fileops.h" +#include "BLI_listbase.h" +#include "BLI_math_base.h" +#include "BLI_string.h" +#include "BLI_string_utf8.h" +#include "BLI_utildefines.h" +#include "BLI_threads.h" + #include "RNA_types.h" #include "bpy.h" @@ -52,15 +61,6 @@ #include "DNA_space_types.h" #include "DNA_text_types.h" -#include "BLI_path_util.h" -#include "BLI_fileops.h" -#include "BLI_listbase.h" -#include "BLI_math_base.h" -#include "BLI_string.h" -#include "BLI_string_utf8.h" -#include "BLI_utildefines.h" -#include "BLI_threads.h" - #include "BKE_context.h" #include "BKE_text.h" #include "BKE_main.h" @@ -166,7 +166,7 @@ void BPY_text_free_code(Text *text) { if (text->compiled) { PyGILState_STATE gilstate; - int use_gil = !PYC_INTERPRETER_ACTIVE; + bool use_gil = !PYC_INTERPRETER_ACTIVE; if (use_gil) gilstate = PyGILState_Ensure(); @@ -378,8 +378,8 @@ static void python_script_error_jump_text(struct Text *text) python_script_error_jump(text->id.name + 2, &lineno, &offset); if (lineno != -1) { /* select the line with the error */ - txt_move_to(text, lineno - 1, INT_MAX, FALSE); - txt_move_to(text, lineno - 1, offset, TRUE); + txt_move_to(text, lineno - 1, INT_MAX, false); + txt_move_to(text, lineno - 1, offset, true); } } @@ -397,7 +397,7 @@ typedef struct { #endif static int python_script_exec(bContext *C, const char *fn, struct Text *text, - struct ReportList *reports, const short do_jump) + struct ReportList *reports, const bool do_jump) { Main *bmain_old = CTX_data_main(C); PyObject *main_mod = NULL; @@ -514,11 +514,11 @@ static int python_script_exec(bContext *C, const char *fn, struct Text *text, /* Can run a file or text block */ int BPY_filepath_exec(bContext *C, const char *filepath, struct ReportList *reports) { - return python_script_exec(C, filepath, NULL, reports, FALSE); + return python_script_exec(C, filepath, NULL, reports, false); } -int BPY_text_exec(bContext *C, struct Text *text, struct ReportList *reports, const short do_jump) +int BPY_text_exec(bContext *C, struct Text *text, struct ReportList *reports, const bool do_jump) { return python_script_exec(C, NULL, text, reports, do_jump); } @@ -719,12 +719,12 @@ void BPY_modules_load_user(bContext *C) int BPY_context_member_get(bContext *C, const char *member, bContextDataResult *result) { PyGILState_STATE gilstate; - int use_gil = !PYC_INTERPRETER_ACTIVE; + bool use_gil = !PYC_INTERPRETER_ACTIVE; PyObject *pyctx; PyObject *item; PointerRNA *ptr = NULL; - int done = FALSE; + bool done = false; if (use_gil) gilstate = PyGILState_Ensure(); @@ -743,7 +743,7 @@ int BPY_context_member_get(bContext *C, const char *member, bContextDataResult * //result->ptr = ((BPy_StructRNA *)item)->ptr; CTX_data_pointer_set(result, ptr->id.data, ptr->type, ptr->data); - done = TRUE; + done = true; } else if (PySequence_Check(item)) { PyObject *seq_fast = PySequence_Fast(item, "bpy_context_get sequence conversion"); @@ -774,7 +774,7 @@ int BPY_context_member_get(bContext *C, const char *member, bContextDataResult * } Py_DECREF(seq_fast); - done = TRUE; + done = true; } } diff --git a/source/blender/python/intern/bpy_interface_atexit.c b/source/blender/python/intern/bpy_interface_atexit.c index 13d8cedf907..d1d33a01e55 100644 --- a/source/blender/python/intern/bpy_interface_atexit.c +++ b/source/blender/python/intern/bpy_interface_atexit.c @@ -31,13 +31,13 @@ #include <Python.h> +#include "BLI_utildefines.h" + #include "bpy_util.h" #include "bpy.h" /* own include */ #include "WM_api.h" -#include "BLI_utildefines.h" - static PyObject *bpy_atexit(PyObject *UNUSED(self), PyObject *UNUSED(args), PyObject *UNUSED(kw)) { /* close down enough of blender at least not to crash */ diff --git a/source/blender/python/intern/bpy_library.c b/source/blender/python/intern/bpy_library.c index 7571fe0f75e..ec6322a1a11 100644 --- a/source/blender/python/intern/bpy_library.c +++ b/source/blender/python/intern/bpy_library.c @@ -244,7 +244,7 @@ static PyObject *bpy_lib_enter(BPy_Library *self, PyObject *UNUSED(args)) self->blo_handle = BLO_blendhandle_from_file(self->abspath, &reports); if (self->blo_handle == NULL) { - if (BPy_reports_to_error(&reports, PyExc_IOError, TRUE) != -1) { + if (BPy_reports_to_error(&reports, PyExc_IOError, true) != -1) { PyErr_Format(PyExc_IOError, "load: %s failed to open blend file", self->abspath); diff --git a/source/blender/python/intern/bpy_operator.c b/source/blender/python/intern/bpy_operator.c index 55ef217e781..ee885684e03 100644 --- a/source/blender/python/intern/bpy_operator.c +++ b/source/blender/python/intern/bpy_operator.c @@ -35,6 +35,9 @@ #include "RNA_types.h" +#include "BLI_utildefines.h" +#include "BLI_string.h" + #include "BPY_extern.h" #include "bpy_operator.h" #include "bpy_operator_wrap.h" @@ -42,9 +45,6 @@ #include "bpy_util.h" #include "../generic/bpy_internal_import.h" -#include "BLI_utildefines.h" -#include "BLI_string.h" - #include "RNA_access.h" #include "RNA_enum_types.h" @@ -85,7 +85,7 @@ static PyObject *pyop_poll(PyObject *UNUSED(self), PyObject *args) if (!PyArg_ParseTuple(args, "s|Os:_bpy.ops.poll", &opname, &context_dict, &context_str)) return NULL; - ot = WM_operatortype_find(opname, TRUE); + ot = WM_operatortype_find(opname, true); if (ot == NULL) { PyErr_Format(PyExc_AttributeError, @@ -147,7 +147,7 @@ static PyObject *pyop_call(PyObject *UNUSED(self), PyObject *args) /* note that context is an int, python does the conversion in this case */ int context = WM_OP_EXEC_DEFAULT; - int is_undo = FALSE; + int is_undo = false; /* XXX Todo, work out a better solution for passing on context, * could make a tuple from self and pack the name and Context into it... */ @@ -164,7 +164,7 @@ static PyObject *pyop_call(PyObject *UNUSED(self), PyObject *args) return NULL; } - ot = WM_operatortype_find(opname, TRUE); + ot = WM_operatortype_find(opname, true); if (ot == NULL) { PyErr_Format(PyExc_AttributeError, @@ -209,7 +209,7 @@ static PyObject *pyop_call(PyObject *UNUSED(self), PyObject *args) CTX_py_dict_set(C, (void *)context_dict); Py_XINCREF(context_dict); /* so we done loose it */ - if (WM_operator_poll_context((bContext *)C, ot, context) == FALSE) { + if (WM_operator_poll_context((bContext *)C, ot, context) == false) { const char *msg = CTX_wm_operator_poll_msg_get(C); PyErr_Format(PyExc_RuntimeError, "Operator bpy.ops.%.200s.poll() %.200s", @@ -248,7 +248,7 @@ static PyObject *pyop_call(PyObject *UNUSED(self), PyObject *args) } #endif - error_val = BPy_reports_to_error(reports, PyExc_RuntimeError, FALSE); + error_val = BPy_reports_to_error(reports, PyExc_RuntimeError, false); /* operator output is nice to have in the terminal/console too */ if (reports->list.first) { @@ -328,7 +328,7 @@ static PyObject *pyop_as_string(PyObject *UNUSED(self), PyObject *args) if (!PyArg_ParseTuple(args, "s|O!i:_bpy.ops.as_string", &opname, &PyDict_Type, &kw, &all_args)) return NULL; - ot = WM_operatortype_find(opname, TRUE); + ot = WM_operatortype_find(opname, true); if (ot == NULL) { PyErr_Format(PyExc_AttributeError, @@ -392,7 +392,7 @@ static PyObject *pyop_getrna(PyObject *UNUSED(self), PyObject *value) PyErr_SetString(PyExc_TypeError, "_bpy.ops.get_rna() expects a string argument"); return NULL; } - ot = WM_operatortype_find(opname, TRUE); + ot = WM_operatortype_find(opname, true); if (ot == NULL) { PyErr_Format(PyExc_KeyError, "_bpy.ops.get_rna(\"%s\") not found", opname); return NULL; @@ -408,7 +408,7 @@ static PyObject *pyop_getrna(PyObject *UNUSED(self), PyObject *value) pyrna = (BPy_StructRNA *)pyrna_struct_CreatePyObject(&ptr); #ifdef PYRNA_FREE_SUPPORT - pyrna->freeptr = TRUE; + pyrna->freeptr = true; #endif return (PyObject *)pyrna; } @@ -425,7 +425,7 @@ static PyObject *pyop_getinstance(PyObject *UNUSED(self), PyObject *value) PyErr_SetString(PyExc_TypeError, "_bpy.ops.get_instance() expects a string argument"); return NULL; } - ot = WM_operatortype_find(opname, TRUE); + ot = WM_operatortype_find(opname, true); if (ot == NULL) { PyErr_Format(PyExc_KeyError, "_bpy.ops.get_instance(\"%s\") not found", opname); return NULL; @@ -444,7 +444,7 @@ static PyObject *pyop_getinstance(PyObject *UNUSED(self), PyObject *value) pyrna = (BPy_StructRNA *)pyrna_struct_CreatePyObject(&ptr); #ifdef PYRNA_FREE_SUPPORT - pyrna->freeptr = TRUE; + pyrna->freeptr = true; #endif op->ptr = &pyrna->ptr; diff --git a/source/blender/python/intern/bpy_operator_wrap.c b/source/blender/python/intern/bpy_operator_wrap.c index 1caec294aa0..cb2e12ba996 100644 --- a/source/blender/python/intern/bpy_operator_wrap.c +++ b/source/blender/python/intern/bpy_operator_wrap.c @@ -112,7 +112,7 @@ PyObject *PYOP_wrap_macro_define(PyObject *UNUSED(self), PyObject *args) if (!PyArg_ParseTuple(args, "Os:_bpy.ops.macro_define", ¯o, &opname)) return NULL; - if (WM_operatortype_find(opname, TRUE) == NULL) { + if (WM_operatortype_find(opname, true) == NULL) { PyErr_Format(PyExc_ValueError, "Macro Define: '%s' is not a valid operator id", opname); @@ -123,7 +123,7 @@ PyObject *PYOP_wrap_macro_define(PyObject *UNUSED(self), PyObject *args) srna = srna_from_self(macro, "Macro Define:"); macroname = RNA_struct_identifier(srna); - ot = WM_operatortype_find(macroname, TRUE); + ot = WM_operatortype_find(macroname, true); if (!ot) { PyErr_Format(PyExc_ValueError, diff --git a/source/blender/python/intern/bpy_path.c b/source/blender/python/intern/bpy_path.c index 8df7ed2364f..1d554b60bbe 100644 --- a/source/blender/python/intern/bpy_path.c +++ b/source/blender/python/intern/bpy_path.c @@ -28,6 +28,8 @@ #include <Python.h> +#include "BLI_utildefines.h" + #include "bpy_path.h" #include "../generic/py_capi_utils.h" diff --git a/source/blender/python/intern/bpy_props.c b/source/blender/python/intern/bpy_props.c index 57ddee0c8c0..f3fa0c9a0a9 100644 --- a/source/blender/python/intern/bpy_props.c +++ b/source/blender/python/intern/bpy_props.c @@ -33,12 +33,12 @@ #include "RNA_types.h" +#include "BLI_utildefines.h" + #include "bpy_props.h" #include "bpy_rna.h" #include "bpy_util.h" -#include "BLI_utildefines.h" - #include "BKE_idprop.h" #include "RNA_access.h" @@ -50,9 +50,11 @@ #include "../generic/py_capi_utils.h" /* initial definition of callback slots we'll probably have more then 1 */ -#define BPY_DATA_CB_SLOT_SIZE 1 +#define BPY_DATA_CB_SLOT_SIZE 3 #define BPY_DATA_CB_SLOT_UPDATE 0 +#define BPY_DATA_CB_SLOT_GET 1 +#define BPY_DATA_CB_SLOT_SET 2 extern BPy_StructRNA *bpy_context_module; @@ -197,7 +199,7 @@ static void bpy_prop_update_cb(struct bContext *C, struct PointerRNA *ptr, struc BLI_assert(py_data != NULL); if (!is_write_ok) { - pyrna_write_set(TRUE); + pyrna_write_set(true); } bpy_context_set(C, &gilstate); @@ -230,25 +232,1260 @@ static void bpy_prop_update_cb(struct bContext *C, struct PointerRNA *ptr, struc bpy_context_clear(C, &gilstate); if (!is_write_ok) { - pyrna_write_set(FALSE); + pyrna_write_set(false); + } +} + +static int bpy_prop_boolean_get_cb(struct PointerRNA *ptr, struct PropertyRNA *prop) +{ + PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop); + PyObject *py_func; + PyObject *args; + PyObject *self; + PyObject *ret; + PyGILState_STATE gilstate; + bool use_gil; + const int is_write_ok = pyrna_write_check(); + int value; + + BLI_assert(py_data != NULL); + + if (!is_write_ok) { + pyrna_write_set(true); + } + + use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */ + + if (use_gil) + gilstate = PyGILState_Ensure(); + + py_func = py_data[BPY_DATA_CB_SLOT_GET]; + + args = PyTuple_New(1); + self = pyrna_struct_as_instance(ptr); + PyTuple_SET_ITEM(args, 0, self); + + ret = PyObject_CallObject(py_func, args); + + Py_DECREF(args); + + if (ret == NULL) { + printf_func_error(py_func); + value = false; + } + else { + value = PyLong_AsLong(ret); + + if (value == -1 && PyErr_Occurred()) { + printf_func_error(py_func); + value = false; + } + + Py_DECREF(ret); + } + + if (use_gil) + PyGILState_Release(gilstate); + + if (!is_write_ok) { + pyrna_write_set(false); } + + return value; } -static int bpy_prop_callback_check(PyObject *py_func, int argcount) +static void bpy_prop_boolean_set_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, int value) +{ + PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop); + PyObject *py_func; + PyObject *args; + PyObject *self; + PyObject *ret; + PyGILState_STATE gilstate; + bool use_gil; + const int is_write_ok = pyrna_write_check(); + + BLI_assert(py_data != NULL); + + if (!is_write_ok) { + pyrna_write_set(true); + } + + use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */ + + if (use_gil) + gilstate = PyGILState_Ensure(); + + py_func = py_data[BPY_DATA_CB_SLOT_SET]; + + args = PyTuple_New(2); + self = pyrna_struct_as_instance(ptr); + PyTuple_SET_ITEM(args, 0, self); + + PyTuple_SET_ITEM(args, 1, PyBool_FromLong(value)); + + ret = PyObject_CallObject(py_func, args); + + Py_DECREF(args); + + if (ret == NULL) { + printf_func_error(py_func); + } + else { + if (ret != Py_None) { + PyErr_SetString(PyExc_ValueError, "the return value must be None"); + printf_func_error(py_func); + } + + Py_DECREF(ret); + } + + if (use_gil) + PyGILState_Release(gilstate); + + if (!is_write_ok) { + pyrna_write_set(false); + } +} + +static void bpy_prop_boolean_array_get_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, int *values) +{ + PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop); + PyObject *py_func; + PyObject *args; + PyObject *self; + PyObject *ret; + PyGILState_STATE gilstate; + bool use_gil; + const int is_write_ok = pyrna_write_check(); + int i, len = RNA_property_array_length(ptr, prop); + + BLI_assert(py_data != NULL); + + if (!is_write_ok) { + pyrna_write_set(true); + } + + use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */ + + if (use_gil) + gilstate = PyGILState_Ensure(); + + py_func = py_data[BPY_DATA_CB_SLOT_GET]; + + args = PyTuple_New(1); + self = pyrna_struct_as_instance(ptr); + PyTuple_SET_ITEM(args, 0, self); + + ret = PyObject_CallObject(py_func, args); + + Py_DECREF(args); + + if (ret == NULL) { + printf_func_error(py_func); + + for (i = 0; i < len; ++i) + values[i] = false; + } + else { + if (PyC_AsArray(values, ret, len, &PyBool_Type, false, "BoolVectorProperty get") == -1) { + printf_func_error(py_func); + + for (i = 0; i < len; ++i) + values[i] = false; + + /* PyC_AsArray decrements refcount internally on error */ + } + else { + Py_DECREF(ret); + } + } + + if (use_gil) + PyGILState_Release(gilstate); + + if (!is_write_ok) { + pyrna_write_set(false); + } +} + +static void bpy_prop_boolean_array_set_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, const int *values) +{ + PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop); + PyObject *py_func; + PyObject *args; + PyObject *self; + PyObject *ret; + PyObject *py_values; + PyGILState_STATE gilstate; + bool use_gil; + const int is_write_ok = pyrna_write_check(); + int len = RNA_property_array_length(ptr, prop); + + BLI_assert(py_data != NULL); + + if (!is_write_ok) { + pyrna_write_set(true); + } + + use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */ + + if (use_gil) + gilstate = PyGILState_Ensure(); + + py_func = py_data[BPY_DATA_CB_SLOT_SET]; + + args = PyTuple_New(2); + self = pyrna_struct_as_instance(ptr); + PyTuple_SET_ITEM(args, 0, self); + + py_values = PyC_FromArray(values, len, &PyBool_Type, false, "BoolVectorProperty set"); + if (!py_values) { + printf_func_error(py_func); + } + else + PyTuple_SET_ITEM(args, 1, py_values); + + ret = PyObject_CallObject(py_func, args); + + Py_DECREF(args); + + if (ret == NULL) { + printf_func_error(py_func); + } + else { + if (ret != Py_None) { + PyErr_SetString(PyExc_ValueError, "the return value must be None"); + printf_func_error(py_func); + } + + Py_DECREF(ret); + } + + if (use_gil) + PyGILState_Release(gilstate); + + if (!is_write_ok) { + pyrna_write_set(false); + } +} + +static int bpy_prop_int_get_cb(struct PointerRNA *ptr, struct PropertyRNA *prop) +{ + PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop); + PyObject *py_func; + PyObject *args; + PyObject *self; + PyObject *ret; + PyGILState_STATE gilstate; + bool use_gil; + const int is_write_ok = pyrna_write_check(); + int value; + + BLI_assert(py_data != NULL); + + if (!is_write_ok) { + pyrna_write_set(true); + } + + use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */ + + if (use_gil) + gilstate = PyGILState_Ensure(); + + py_func = py_data[BPY_DATA_CB_SLOT_GET]; + + args = PyTuple_New(1); + self = pyrna_struct_as_instance(ptr); + PyTuple_SET_ITEM(args, 0, self); + + ret = PyObject_CallObject(py_func, args); + + Py_DECREF(args); + + if (ret == NULL) { + printf_func_error(py_func); + value = 0.0f; + } + else { + value = PyLong_AsLong(ret); + + if (value == -1 && PyErr_Occurred()) { + printf_func_error(py_func); + value = 0; + } + + Py_DECREF(ret); + } + + if (use_gil) + PyGILState_Release(gilstate); + + if (!is_write_ok) { + pyrna_write_set(false); + } + + return value; +} + +static void bpy_prop_int_set_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, int value) +{ + PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop); + PyObject *py_func; + PyObject *args; + PyObject *self; + PyObject *ret; + PyGILState_STATE gilstate; + bool use_gil; + const int is_write_ok = pyrna_write_check(); + + BLI_assert(py_data != NULL); + + if (!is_write_ok) { + pyrna_write_set(true); + } + + use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */ + + if (use_gil) + gilstate = PyGILState_Ensure(); + + py_func = py_data[BPY_DATA_CB_SLOT_SET]; + + args = PyTuple_New(2); + self = pyrna_struct_as_instance(ptr); + PyTuple_SET_ITEM(args, 0, self); + + PyTuple_SET_ITEM(args, 1, PyLong_FromLong(value)); + + ret = PyObject_CallObject(py_func, args); + + Py_DECREF(args); + + if (ret == NULL) { + printf_func_error(py_func); + } + else { + if (ret != Py_None) { + PyErr_SetString(PyExc_ValueError, "the return value must be None"); + printf_func_error(py_func); + } + + Py_DECREF(ret); + } + + if (use_gil) + PyGILState_Release(gilstate); + + if (!is_write_ok) { + pyrna_write_set(false); + } +} + +static void bpy_prop_int_array_get_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, int *values) +{ + PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop); + PyObject *py_func; + PyObject *args; + PyObject *self; + PyObject *ret; + PyGILState_STATE gilstate; + bool use_gil; + const int is_write_ok = pyrna_write_check(); + int i, len = RNA_property_array_length(ptr, prop); + + BLI_assert(py_data != NULL); + + if (!is_write_ok) { + pyrna_write_set(true); + } + + use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */ + + if (use_gil) + gilstate = PyGILState_Ensure(); + + py_func = py_data[BPY_DATA_CB_SLOT_GET]; + + args = PyTuple_New(1); + self = pyrna_struct_as_instance(ptr); + PyTuple_SET_ITEM(args, 0, self); + + ret = PyObject_CallObject(py_func, args); + + Py_DECREF(args); + + if (ret == NULL) { + printf_func_error(py_func); + + for (i = 0; i < len; ++i) + values[i] = 0; + } + else { + if (PyC_AsArray(values, ret, len, &PyLong_Type, false, "IntVectorProperty get") == -1) { + printf_func_error(py_func); + + for (i = 0; i < len; ++i) + values[i] = 0; + + /* PyC_AsArray decrements refcount internally on error */ + } + else { + Py_DECREF(ret); + } + } + + if (use_gil) + PyGILState_Release(gilstate); + + if (!is_write_ok) { + pyrna_write_set(false); + } +} + +static void bpy_prop_int_array_set_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, const int *values) +{ + PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop); + PyObject *py_func; + PyObject *args; + PyObject *self; + PyObject *ret; + PyObject *py_values; + PyGILState_STATE gilstate; + bool use_gil; + const int is_write_ok = pyrna_write_check(); + int len = RNA_property_array_length(ptr, prop); + + BLI_assert(py_data != NULL); + + if (!is_write_ok) { + pyrna_write_set(true); + } + + use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */ + + if (use_gil) + gilstate = PyGILState_Ensure(); + + py_func = py_data[BPY_DATA_CB_SLOT_SET]; + + args = PyTuple_New(2); + self = pyrna_struct_as_instance(ptr); + PyTuple_SET_ITEM(args, 0, self); + + py_values = PyC_FromArray(values, len, &PyLong_Type, false, "IntVectorProperty set"); + if (!py_values) { + printf_func_error(py_func); + } + else + PyTuple_SET_ITEM(args, 1, py_values); + + ret = PyObject_CallObject(py_func, args); + + Py_DECREF(args); + + if (ret == NULL) { + printf_func_error(py_func); + } + else { + if (ret != Py_None) { + PyErr_SetString(PyExc_ValueError, "the return value must be None"); + printf_func_error(py_func); + } + + Py_DECREF(ret); + } + + if (use_gil) + PyGILState_Release(gilstate); + + if (!is_write_ok) { + pyrna_write_set(false); + } +} + +static float bpy_prop_float_get_cb(struct PointerRNA *ptr, struct PropertyRNA *prop) +{ + PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop); + PyObject *py_func; + PyObject *args; + PyObject *self; + PyObject *ret; + PyGILState_STATE gilstate; + bool use_gil; + const int is_write_ok = pyrna_write_check(); + float value; + + BLI_assert(py_data != NULL); + + if (!is_write_ok) { + pyrna_write_set(true); + } + + use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */ + + if (use_gil) + gilstate = PyGILState_Ensure(); + + py_func = py_data[BPY_DATA_CB_SLOT_GET]; + + args = PyTuple_New(1); + self = pyrna_struct_as_instance(ptr); + PyTuple_SET_ITEM(args, 0, self); + + ret = PyObject_CallObject(py_func, args); + + Py_DECREF(args); + + if (ret == NULL) { + printf_func_error(py_func); + value = 0.0f; + } + else { + value = PyFloat_AsDouble(ret); + + if (value == -1.0f && PyErr_Occurred()) { + printf_func_error(py_func); + value = 0.0f; + } + + Py_DECREF(ret); + } + + if (use_gil) + PyGILState_Release(gilstate); + + if (!is_write_ok) { + pyrna_write_set(false); + } + + return value; +} + +static void bpy_prop_float_set_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, float value) +{ + PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop); + PyObject *py_func; + PyObject *args; + PyObject *self; + PyObject *ret; + PyGILState_STATE gilstate; + bool use_gil; + const int is_write_ok = pyrna_write_check(); + + BLI_assert(py_data != NULL); + + if (!is_write_ok) { + pyrna_write_set(true); + } + + use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */ + + if (use_gil) + gilstate = PyGILState_Ensure(); + + py_func = py_data[BPY_DATA_CB_SLOT_SET]; + + args = PyTuple_New(2); + self = pyrna_struct_as_instance(ptr); + PyTuple_SET_ITEM(args, 0, self); + + PyTuple_SET_ITEM(args, 1, PyFloat_FromDouble(value)); + + ret = PyObject_CallObject(py_func, args); + + Py_DECREF(args); + + if (ret == NULL) { + printf_func_error(py_func); + } + else { + if (ret != Py_None) { + PyErr_SetString(PyExc_ValueError, "the return value must be None"); + printf_func_error(py_func); + } + + Py_DECREF(ret); + } + + if (use_gil) + PyGILState_Release(gilstate); + + if (!is_write_ok) { + pyrna_write_set(false); + } +} + +static void bpy_prop_float_array_get_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, float *values) +{ + PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop); + PyObject *py_func; + PyObject *args; + PyObject *self; + PyObject *ret; + PyGILState_STATE gilstate; + bool use_gil; + const int is_write_ok = pyrna_write_check(); + int i, len = RNA_property_array_length(ptr, prop); + + BLI_assert(py_data != NULL); + + if (!is_write_ok) { + pyrna_write_set(true); + } + + use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */ + + if (use_gil) + gilstate = PyGILState_Ensure(); + + py_func = py_data[BPY_DATA_CB_SLOT_GET]; + + args = PyTuple_New(1); + self = pyrna_struct_as_instance(ptr); + PyTuple_SET_ITEM(args, 0, self); + + ret = PyObject_CallObject(py_func, args); + + Py_DECREF(args); + + if (ret == NULL) { + printf_func_error(py_func); + + for (i = 0; i < len; ++i) + values[i] = 0.0f; + } + else { + if (PyC_AsArray(values, ret, len, &PyFloat_Type, false, "FloatVectorProperty get") == -1) { + printf_func_error(py_func); + + for (i = 0; i < len; ++i) + values[i] = 0.0f; + + /* PyC_AsArray decrements refcount internally on error */ + } + else { + Py_DECREF(ret); + } + } + + if (use_gil) + PyGILState_Release(gilstate); + + if (!is_write_ok) { + pyrna_write_set(false); + } +} + +static void bpy_prop_float_array_set_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, const float *values) +{ + PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop); + PyObject *py_func; + PyObject *args; + PyObject *self; + PyObject *ret; + PyObject *py_values; + PyGILState_STATE gilstate; + bool use_gil; + const int is_write_ok = pyrna_write_check(); + int len = RNA_property_array_length(ptr, prop); + + BLI_assert(py_data != NULL); + + if (!is_write_ok) { + pyrna_write_set(true); + } + + use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */ + + if (use_gil) + gilstate = PyGILState_Ensure(); + + py_func = py_data[BPY_DATA_CB_SLOT_SET]; + + args = PyTuple_New(2); + self = pyrna_struct_as_instance(ptr); + PyTuple_SET_ITEM(args, 0, self); + + py_values = PyC_FromArray(values, len, &PyFloat_Type, false, "FloatVectorProperty set"); + if (!py_values) { + printf_func_error(py_func); + } + else + PyTuple_SET_ITEM(args, 1, py_values); + + ret = PyObject_CallObject(py_func, args); + + Py_DECREF(args); + + if (ret == NULL) { + printf_func_error(py_func); + } + else { + if (ret != Py_None) { + PyErr_SetString(PyExc_ValueError, "the return value must be None"); + printf_func_error(py_func); + } + + Py_DECREF(ret); + } + + if (use_gil) + PyGILState_Release(gilstate); + + if (!is_write_ok) { + pyrna_write_set(false); + } +} + +static void bpy_prop_string_get_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, char *value) +{ + PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop); + PyObject *py_func; + PyObject *args; + PyObject *self; + PyObject *ret; + PyGILState_STATE gilstate; + bool use_gil; + const int is_write_ok = pyrna_write_check(); + + BLI_assert(py_data != NULL); + + if (!is_write_ok) { + pyrna_write_set(true); + } + + use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */ + + if (use_gil) + gilstate = PyGILState_Ensure(); + + py_func = py_data[BPY_DATA_CB_SLOT_GET]; + + args = PyTuple_New(1); + self = pyrna_struct_as_instance(ptr); + PyTuple_SET_ITEM(args, 0, self); + + ret = PyObject_CallObject(py_func, args); + + Py_DECREF(args); + + if (ret == NULL) { + printf_func_error(py_func); + value[0] = '\0'; + } + else if (!PyUnicode_Check(ret)) { + PyErr_Format(PyExc_TypeError, + "return value must be a string, not %.200s", + Py_TYPE(ret)->tp_name); + printf_func_error(py_func); + value[0] = '\0'; + Py_DECREF(ret); + } + else { + Py_ssize_t length; + const char *buffer = _PyUnicode_AsStringAndSize(ret, &length); + memcpy(value, buffer, length + 1); + Py_DECREF(ret); + } + + if (use_gil) + PyGILState_Release(gilstate); + + if (!is_write_ok) { + pyrna_write_set(false); + } +} + +static int bpy_prop_string_length_cb(struct PointerRNA *ptr, struct PropertyRNA *prop) +{ + PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop); + PyObject *py_func; + PyObject *args; + PyObject *self; + PyObject *ret; + PyGILState_STATE gilstate; + bool use_gil; + const int is_write_ok = pyrna_write_check(); + int length; + + BLI_assert(py_data != NULL); + + if (!is_write_ok) { + pyrna_write_set(true); + } + + use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */ + + if (use_gil) + gilstate = PyGILState_Ensure(); + + py_func = py_data[BPY_DATA_CB_SLOT_GET]; + + args = PyTuple_New(1); + self = pyrna_struct_as_instance(ptr); + PyTuple_SET_ITEM(args, 0, self); + + ret = PyObject_CallObject(py_func, args); + + Py_DECREF(args); + + if (ret == NULL) { + printf_func_error(py_func); + length = 0; + } + else if (!PyUnicode_Check(ret)) { + PyErr_Format(PyExc_TypeError, + "return value must be a string, not %.200s", + Py_TYPE(ret)->tp_name); + printf_func_error(py_func); + length = 0; + Py_DECREF(ret); + } + else { + Py_ssize_t length_ssize_t = 0; + _PyUnicode_AsStringAndSize(ret, &length_ssize_t); + length = length_ssize_t; + Py_DECREF(ret); + } + + if (use_gil) + PyGILState_Release(gilstate); + + if (!is_write_ok) { + pyrna_write_set(false); + } + + return length; +} + +static void bpy_prop_string_set_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, const char *value) +{ + PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop); + PyObject *py_func; + PyObject *args; + PyObject *self; + PyObject *ret; + PyGILState_STATE gilstate; + bool use_gil; + const int is_write_ok = pyrna_write_check(); + PyObject *py_value; + + BLI_assert(py_data != NULL); + + if (!is_write_ok) { + pyrna_write_set(true); + } + + use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */ + + if (use_gil) + gilstate = PyGILState_Ensure(); + + py_func = py_data[BPY_DATA_CB_SLOT_SET]; + + args = PyTuple_New(2); + self = pyrna_struct_as_instance(ptr); + PyTuple_SET_ITEM(args, 0, self); + + py_value = PyUnicode_FromString(value); + if (!py_value) { + PyErr_SetString(PyExc_ValueError, "the return value must be a string"); + printf_func_error(py_func); + } + else + PyTuple_SET_ITEM(args, 1, py_value); + + ret = PyObject_CallObject(py_func, args); + + Py_DECREF(args); + + if (ret == NULL) { + printf_func_error(py_func); + } + else { + if (ret != Py_None) { + PyErr_SetString(PyExc_ValueError, "the return value must be None"); + printf_func_error(py_func); + } + + Py_DECREF(ret); + } + + if (use_gil) + PyGILState_Release(gilstate); + + if (!is_write_ok) { + pyrna_write_set(false); + } +} + +static int bpy_prop_enum_get_cb(struct PointerRNA *ptr, struct PropertyRNA *prop) +{ + PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop); + PyObject *py_func; + PyObject *args; + PyObject *self; + PyObject *ret; + PyGILState_STATE gilstate; + bool use_gil; + const int is_write_ok = pyrna_write_check(); + int value; + + BLI_assert(py_data != NULL); + + if (!is_write_ok) { + pyrna_write_set(true); + } + + use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */ + + if (use_gil) + gilstate = PyGILState_Ensure(); + + py_func = py_data[BPY_DATA_CB_SLOT_GET]; + + args = PyTuple_New(1); + self = pyrna_struct_as_instance(ptr); + PyTuple_SET_ITEM(args, 0, self); + + ret = PyObject_CallObject(py_func, args); + + Py_DECREF(args); + + if (ret == NULL) { + printf_func_error(py_func); + value = RNA_property_enum_get_default(ptr, prop); + } + else { + value = PyLong_AsLong(ret); + + if (value == -1 && PyErr_Occurred()) { + printf_func_error(py_func); + value = RNA_property_enum_get_default(ptr, prop); + } + + Py_DECREF(ret); + } + + if (use_gil) + PyGILState_Release(gilstate); + + if (!is_write_ok) { + pyrna_write_set(false); + } + + return value; +} + +static void bpy_prop_enum_set_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, int value) +{ + PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop); + PyObject *py_func; + PyObject *args; + PyObject *self; + PyObject *ret; + PyGILState_STATE gilstate; + bool use_gil; + const int is_write_ok = pyrna_write_check(); + + BLI_assert(py_data != NULL); + + if (!is_write_ok) { + pyrna_write_set(true); + } + + use_gil = true; /* !PYC_INTERPRETER_ACTIVE; */ + + if (use_gil) + gilstate = PyGILState_Ensure(); + + py_func = py_data[BPY_DATA_CB_SLOT_SET]; + + args = PyTuple_New(2); + self = pyrna_struct_as_instance(ptr); + PyTuple_SET_ITEM(args, 0, self); + + PyTuple_SET_ITEM(args, 1, PyLong_FromLong(value)); + + ret = PyObject_CallObject(py_func, args); + + Py_DECREF(args); + + if (ret == NULL) { + printf_func_error(py_func); + } + else { + if (ret != Py_None) { + PyErr_SetString(PyExc_ValueError, "the return value must be None"); + printf_func_error(py_func); + } + + Py_DECREF(ret); + } + + if (use_gil) + PyGILState_Release(gilstate); + + if (!is_write_ok) { + pyrna_write_set(false); + } +} + +/* utility function we need for parsing int's in an if statement */ +static int py_long_as_int(PyObject *py_long, int *r_int) +{ + if (PyLong_CheckExact(py_long)) { + *r_int = (int)PyLong_AS_LONG(py_long); + return 0; + } + else { + return -1; + } +} + +#if 0 +/* copies orig to buf, then sets orig to buf, returns copy length */ +static size_t strswapbufcpy(char *buf, const char **orig) +{ + const char *src = *orig; + char *dst = buf; + size_t i = 0; + *orig = buf; + while ((*dst = *src)) { dst++; src++; i++; } + return i + 1; /* include '\0' */ +} +#endif + +static EnumPropertyItem *enum_items_from_py(PyObject *seq_fast, PyObject *def, int *defvalue, const short is_enum_flag) +{ + EnumPropertyItem *items; + PyObject *item; + const Py_ssize_t seq_len = PySequence_Fast_GET_SIZE(seq_fast); + Py_ssize_t totbuf = 0; + int i; + short def_used = 0; + const char *def_cmp = NULL; + + if (is_enum_flag) { + if (seq_len > RNA_ENUM_BITFLAG_SIZE) { + PyErr_SetString(PyExc_TypeError, + "EnumProperty(...): maximum " + STRINGIFY(RNA_ENUM_BITFLAG_SIZE) + " members for a ENUM_FLAG type property"); + return NULL; + } + if (def && !PySet_Check(def)) { + PyErr_Format(PyExc_TypeError, + "EnumProperty(...): default option must be a 'set' " + "type when ENUM_FLAG is enabled, not a '%.200s'", + Py_TYPE(def)->tp_name); + return NULL; + } + } + else { + if (def) { + def_cmp = _PyUnicode_AsString(def); + if (def_cmp == NULL) { + PyErr_Format(PyExc_TypeError, + "EnumProperty(...): default option must be a 'str' " + "type when ENUM_FLAG is disabled, not a '%.200s'", + Py_TYPE(def)->tp_name); + return NULL; + } + } + } + + /* blank value */ + *defvalue = 0; + + items = MEM_callocN(sizeof(EnumPropertyItem) * (seq_len + 1), "enum_items_from_py1"); + + for (i = 0; i < seq_len; i++) { + EnumPropertyItem tmp = {0, "", 0, "", ""}; + Py_ssize_t item_size; + Py_ssize_t id_str_size; + Py_ssize_t name_str_size; + Py_ssize_t desc_str_size; + + item = PySequence_Fast_GET_ITEM(seq_fast, i); + + if ((PyTuple_CheckExact(item)) && + (item_size = PyTuple_GET_SIZE(item)) && + (item_size == 3 || item_size == 4) && + (tmp.identifier = _PyUnicode_AsStringAndSize(PyTuple_GET_ITEM(item, 0), &id_str_size)) && + (tmp.name = _PyUnicode_AsStringAndSize(PyTuple_GET_ITEM(item, 1), &name_str_size)) && + (tmp.description = _PyUnicode_AsStringAndSize(PyTuple_GET_ITEM(item, 2), &desc_str_size)) && + /* TODO, number isn't ensured to be unique from the script author */ + (item_size < 4 || py_long_as_int(PyTuple_GET_ITEM(item, 3), &tmp.value) != -1)) + { + if (is_enum_flag) { + if (item_size < 4) { + tmp.value = 1 << i; + } + + if (def && PySet_Contains(def, PyTuple_GET_ITEM(item, 0))) { + *defvalue |= tmp.value; + def_used++; + } + } + else { + if (item_size < 4) { + tmp.value = i; + } + + if (def && def_used == 0 && strcmp(def_cmp, tmp.identifier) == 0) { + *defvalue = tmp.value; + def_used++; /* only ever 1 */ + } + } + + items[i] = tmp; + + /* calculate combine string length */ + totbuf += id_str_size + name_str_size + desc_str_size + 3; /* 3 is for '\0's */ + } + else { + MEM_freeN(items); + PyErr_SetString(PyExc_TypeError, + "EnumProperty(...): expected a tuple containing " + "(identifier, name, description) and optionally a " + "unique number"); + return NULL; + } + + } + + if (is_enum_flag) { + /* strict check that all set members were used */ + if (def && def_used != PySet_GET_SIZE(def)) { + MEM_freeN(items); + + PyErr_Format(PyExc_TypeError, + "EnumProperty(..., default={...}): set has %d unused member(s)", + PySet_GET_SIZE(def) - def_used); + return NULL; + } + } + else { + if (def && def_used == 0) { + MEM_freeN(items); + + PyErr_Format(PyExc_TypeError, + "EnumProperty(..., default=\'%s\'): not found in enum members", + def_cmp); + return NULL; + } + } + + /* disabled duplicating strings because the array can still be freed and + * the strings from it referenced, for now we can't support dynamically + * created strings from python. */ +#if 0 + /* this would all work perfectly _but_ the python strings may be freed + * immediately after use, so we need to duplicate them, ugh. + * annoying because it works most of the time without this. */ + { + EnumPropertyItem *items_dup = MEM_mallocN((sizeof(EnumPropertyItem) * (seq_len + 1)) + (sizeof(char) * totbuf), + "enum_items_from_py2"); + EnumPropertyItem *items_ptr = items_dup; + char *buf = ((char *)items_dup) + (sizeof(EnumPropertyItem) * (seq_len + 1)); + memcpy(items_dup, items, sizeof(EnumPropertyItem) * (seq_len + 1)); + for (i = 0; i < seq_len; i++, items_ptr++) { + buf += strswapbufcpy(buf, &items_ptr->identifier); + buf += strswapbufcpy(buf, &items_ptr->name); + buf += strswapbufcpy(buf, &items_ptr->description); + } + MEM_freeN(items); + items = items_dup; + } + /* end string duplication */ +#endif + + return items; +} + +static EnumPropertyItem *bpy_prop_enum_itemf_cb(struct bContext *C, PointerRNA *ptr, PropertyRNA *prop, int *free) +{ + PyGILState_STATE gilstate; + + PyObject *py_func = RNA_property_enum_py_data_get(prop); + PyObject *self = NULL; + PyObject *args; + PyObject *items; /* returned from the function call */ + + EnumPropertyItem *eitems = NULL; + int err = 0; + + bpy_context_set(C, &gilstate); + + args = PyTuple_New(2); + self = pyrna_struct_as_instance(ptr); + PyTuple_SET_ITEM(args, 0, self); + + /* now get the context */ + PyTuple_SET_ITEM(args, 1, (PyObject *)bpy_context_module); + Py_INCREF(bpy_context_module); + + items = PyObject_CallObject(py_func, args); + + Py_DECREF(args); + + if (items == NULL) { + err = -1; + } + else { + PyObject *items_fast; + int defvalue_dummy = 0; + + if (!(items_fast = PySequence_Fast(items, "EnumProperty(...): " + "return value from the callback was not a sequence"))) + { + err = -1; + } + else { + eitems = enum_items_from_py(items_fast, NULL, &defvalue_dummy, + (RNA_property_flag(prop) & PROP_ENUM_FLAG) != 0); + + Py_DECREF(items_fast); + + if (!eitems) { + err = -1; + } + } + + Py_DECREF(items); + } + + if (err != -1) { /* worked */ + *free = 1; + } + else { + printf_func_error(py_func); + + eitems = DummyRNA_NULL_items; + } + + + bpy_context_clear(C, &gilstate); + return eitems; +} + +static int bpy_prop_callback_check(PyObject *py_func, const char *keyword, int argcount) { if (py_func && py_func != Py_None) { if (!PyFunction_Check(py_func)) { PyErr_Format(PyExc_TypeError, - "update keyword: expected a function type, not a %.200s", - Py_TYPE(py_func)->tp_name); + "%s keyword: expected a function type, not a %.200s", + keyword, Py_TYPE(py_func)->tp_name); return -1; } else { PyCodeObject *f_code = (PyCodeObject *)PyFunction_GET_CODE(py_func); if (f_code->co_argcount != argcount) { PyErr_Format(PyExc_TypeError, - "update keyword: expected a function taking %d arguments, not %d", - argcount, f_code->co_argcount); + "%s keyword: expected a function taking %d arguments, not %d", + keyword, argcount, f_code->co_argcount); return -1; } } @@ -257,32 +1494,215 @@ static int bpy_prop_callback_check(PyObject *py_func, int argcount) return 0; } +static PyObject **bpy_prop_py_data_get(struct PropertyRNA *prop) +{ + PyObject **py_data = RNA_property_py_data_get(prop); + if (!py_data) { + py_data = MEM_callocN(sizeof(PyObject *) * BPY_DATA_CB_SLOT_SIZE, __func__); + RNA_def_py_data(prop, py_data); + } + return py_data; +} -static int bpy_prop_callback_assign(struct PropertyRNA *prop, PyObject *update_cb) +static void bpy_prop_callback_assign_update(struct PropertyRNA *prop, PyObject *update_cb) { /* assume this is already checked for type and arg length */ if (update_cb && update_cb != Py_None) { - PyObject **py_data = MEM_callocN(sizeof(PyObject *) * BPY_DATA_CB_SLOT_SIZE, __func__); + PyObject **py_data = bpy_prop_py_data_get(prop); + RNA_def_property_update_runtime(prop, (void *)bpy_prop_update_cb); py_data[BPY_DATA_CB_SLOT_UPDATE] = update_cb; - RNA_def_py_data(prop, py_data); RNA_def_property_flag(prop, PROP_CONTEXT_PROPERTY_UPDATE); } +} - return 0; +static void bpy_prop_callback_assign_boolean(struct PropertyRNA *prop, PyObject *get_cb, PyObject *set_cb) +{ + BooleanPropertyGetFunc rna_get_cb = NULL; + BooleanPropertySetFunc rna_set_cb = NULL; + + if (get_cb && get_cb != Py_None) { + PyObject **py_data = bpy_prop_py_data_get(prop); + + rna_get_cb = bpy_prop_boolean_get_cb; + py_data[BPY_DATA_CB_SLOT_GET] = get_cb; + } + + if (set_cb && set_cb != Py_None) { + PyObject **py_data = bpy_prop_py_data_get(prop); + + rna_set_cb = bpy_prop_boolean_set_cb; + py_data[BPY_DATA_CB_SLOT_SET] = set_cb; + } + + RNA_def_property_boolean_funcs_runtime(prop, rna_get_cb, rna_set_cb); } -/* utility function we need for parsing int's in an if statement */ -static int py_long_as_int(PyObject *py_long, int *r_int) +static void bpy_prop_callback_assign_boolean_array(struct PropertyRNA *prop, PyObject *get_cb, PyObject *set_cb) { - if (PyLong_CheckExact(py_long)) { - *r_int = (int)PyLong_AS_LONG(py_long); - return 0; + BooleanArrayPropertyGetFunc rna_get_cb = NULL; + BooleanArrayPropertySetFunc rna_set_cb = NULL; + + if (get_cb && get_cb != Py_None) { + PyObject **py_data = bpy_prop_py_data_get(prop); + + rna_get_cb = bpy_prop_boolean_array_get_cb; + py_data[BPY_DATA_CB_SLOT_GET] = get_cb; } - else { - return -1; + + if (set_cb && set_cb != Py_None) { + PyObject **py_data = bpy_prop_py_data_get(prop); + + rna_set_cb = bpy_prop_boolean_array_set_cb; + py_data[BPY_DATA_CB_SLOT_SET] = set_cb; + } + + RNA_def_property_boolean_array_funcs_runtime(prop, rna_get_cb, rna_set_cb); +} + +static void bpy_prop_callback_assign_int(struct PropertyRNA *prop, PyObject *get_cb, PyObject *set_cb) +{ + IntPropertyGetFunc rna_get_cb = NULL; + IntPropertySetFunc rna_set_cb = NULL; + + if (get_cb && get_cb != Py_None) { + PyObject **py_data = bpy_prop_py_data_get(prop); + + rna_get_cb = bpy_prop_int_get_cb; + py_data[BPY_DATA_CB_SLOT_GET] = get_cb; + } + + if (set_cb && set_cb != Py_None) { + PyObject **py_data = bpy_prop_py_data_get(prop); + + rna_set_cb = bpy_prop_int_set_cb; + py_data[BPY_DATA_CB_SLOT_SET] = set_cb; + } + + RNA_def_property_int_funcs_runtime(prop, rna_get_cb, rna_set_cb, NULL); +} + +static void bpy_prop_callback_assign_int_array(struct PropertyRNA *prop, PyObject *get_cb, PyObject *set_cb) +{ + IntArrayPropertyGetFunc rna_get_cb = NULL; + IntArrayPropertySetFunc rna_set_cb = NULL; + + if (get_cb && get_cb != Py_None) { + PyObject **py_data = bpy_prop_py_data_get(prop); + + rna_get_cb = bpy_prop_int_array_get_cb; + py_data[BPY_DATA_CB_SLOT_GET] = get_cb; + } + + if (set_cb && set_cb != Py_None) { + PyObject **py_data = bpy_prop_py_data_get(prop); + + rna_set_cb = bpy_prop_int_array_set_cb; + py_data[BPY_DATA_CB_SLOT_SET] = set_cb; + } + + RNA_def_property_int_array_funcs_runtime(prop, rna_get_cb, rna_set_cb, NULL); +} + +static void bpy_prop_callback_assign_float(struct PropertyRNA *prop, PyObject *get_cb, PyObject *set_cb) +{ + FloatPropertyGetFunc rna_get_cb = NULL; + FloatPropertySetFunc rna_set_cb = NULL; + + if (get_cb && get_cb != Py_None) { + PyObject **py_data = bpy_prop_py_data_get(prop); + + rna_get_cb = bpy_prop_float_get_cb; + py_data[BPY_DATA_CB_SLOT_GET] = get_cb; } + + if (set_cb && set_cb != Py_None) { + PyObject **py_data = bpy_prop_py_data_get(prop); + + rna_set_cb = bpy_prop_float_set_cb; + py_data[BPY_DATA_CB_SLOT_SET] = set_cb; + } + + RNA_def_property_float_funcs_runtime(prop, rna_get_cb, rna_set_cb, NULL); +} + +static void bpy_prop_callback_assign_float_array(struct PropertyRNA *prop, PyObject *get_cb, PyObject *set_cb) +{ + FloatArrayPropertyGetFunc rna_get_cb = NULL; + FloatArrayPropertySetFunc rna_set_cb = NULL; + + if (get_cb && get_cb != Py_None) { + PyObject **py_data = bpy_prop_py_data_get(prop); + + rna_get_cb = bpy_prop_float_array_get_cb; + py_data[BPY_DATA_CB_SLOT_GET] = get_cb; + } + + if (set_cb && set_cb != Py_None) { + PyObject **py_data = bpy_prop_py_data_get(prop); + + rna_set_cb = bpy_prop_float_array_set_cb; + py_data[BPY_DATA_CB_SLOT_SET] = set_cb; + } + + RNA_def_property_float_array_funcs_runtime(prop, rna_get_cb, rna_set_cb, NULL); +} + +static void bpy_prop_callback_assign_string(struct PropertyRNA *prop, PyObject *get_cb, PyObject *set_cb) +{ + StringPropertyGetFunc rna_get_cb = NULL; + StringPropertyLengthFunc rna_length_cb = NULL; + StringPropertySetFunc rna_set_cb = NULL; + + if (get_cb && get_cb != Py_None) { + PyObject **py_data = bpy_prop_py_data_get(prop); + + rna_get_cb = bpy_prop_string_get_cb; + rna_length_cb = bpy_prop_string_length_cb; + py_data[BPY_DATA_CB_SLOT_GET] = get_cb; + } + + if (set_cb && set_cb != Py_None) { + PyObject **py_data = bpy_prop_py_data_get(prop); + + rna_set_cb = bpy_prop_string_set_cb; + py_data[BPY_DATA_CB_SLOT_SET] = set_cb; + } + + RNA_def_property_string_funcs_runtime(prop, rna_get_cb, rna_length_cb, rna_set_cb); +} + +static void bpy_prop_callback_assign_enum(struct PropertyRNA *prop, PyObject *get_cb, PyObject *set_cb, PyObject *itemf_cb) +{ + EnumPropertyGetFunc rna_get_cb = NULL; + EnumPropertyItemFunc rna_itemf_cb = NULL; + EnumPropertySetFunc rna_set_cb = NULL; + + if (get_cb && get_cb != Py_None) { + PyObject **py_data = bpy_prop_py_data_get(prop); + + rna_get_cb = bpy_prop_enum_get_cb; + py_data[BPY_DATA_CB_SLOT_GET] = get_cb; + } + + if (set_cb && set_cb != Py_None) { + PyObject **py_data = bpy_prop_py_data_get(prop); + + rna_set_cb = bpy_prop_enum_set_cb; + py_data[BPY_DATA_CB_SLOT_SET] = set_cb; + } + + if (itemf_cb && itemf_cb != Py_None) { + rna_itemf_cb = bpy_prop_enum_itemf_cb; + RNA_def_property_enum_py_data(prop, (void *)itemf_cb); + + /* watch out!, if a user is tricky they can probably crash blender + * if they manage to free the callback, take care! */ + /* Py_INCREF(itemf_cb); */ + } + + RNA_def_property_enum_funcs_runtime(prop, rna_get_cb, rna_set_cb, rna_itemf_cb); } /* this define runs at the start of each function and deals with @@ -386,7 +1806,9 @@ PyDoc_STRVAR(BPy_BoolProperty_doc, "default=False, " "options={'ANIMATABLE'}, " "subtype='NONE', " - "update=None)\n" + "update=None, " + "get=None, " + "set=None)\n" "\n" " Returns a new boolean property definition.\n" "\n" @@ -406,7 +1828,7 @@ static PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw) if (srna) { static const char *kwlist[] = {"attr", "name", "description", "default", - "options", "subtype", "update", NULL}; + "options", "subtype", "update", "get", "set", NULL}; const char *id = NULL, *name = NULL, *description = ""; int id_len; int def = 0; @@ -416,20 +1838,28 @@ static PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw) char *pysubtype = NULL; int subtype = PROP_NONE; PyObject *update_cb = NULL; + PyObject *get_cb = NULL; + PyObject *set_cb = NULL; if (!PyArg_ParseTupleAndKeywords(args, kw, - "s#|ssiO!sO:BoolProperty", + "s#|ssiO!sOOO:BoolProperty", (char **)kwlist, &id, &id_len, &name, &description, &def, &PySet_Type, &pyopts, &pysubtype, - &update_cb)) + &update_cb, &get_cb, &set_cb)) { return NULL; } BPY_PROPDEF_SUBTYPE_CHECK(BoolProperty, property_flag_items, property_subtype_number_items); - if (bpy_prop_callback_check(update_cb, 2) == -1) { + if (bpy_prop_callback_check(update_cb, "update", 2) == -1) { + return NULL; + } + if (bpy_prop_callback_check(get_cb, "get", 1) == -1) { + return NULL; + } + if (bpy_prop_callback_check(set_cb, "set", 2) == -1) { return NULL; } @@ -443,7 +1873,8 @@ static PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw) if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE); if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION); } - bpy_prop_callback_assign(prop, update_cb); + bpy_prop_callback_assign_update(prop, update_cb); + bpy_prop_callback_assign_boolean(prop, get_cb, set_cb); RNA_def_property_duplicate_pointers(srna, prop); } @@ -457,7 +1888,9 @@ PyDoc_STRVAR(BPy_BoolVectorProperty_doc, "options={'ANIMATABLE'}, " "subtype='NONE', " "size=3, " - "update=None)\n" + "update=None, " + "get=None, " + "set=None)\n" "\n" " Returns a new vector boolean property definition.\n" "\n" @@ -483,7 +1916,7 @@ static PyObject *BPy_BoolVectorProperty(PyObject *self, PyObject *args, PyObject if (srna) { static const char *kwlist[] = {"attr", "name", "description", "default", - "options", "subtype", "size", "update", NULL}; + "options", "subtype", "size", "update", "get", "set", NULL}; const char *id = NULL, *name = NULL, *description = ""; int id_len; int def[PYRNA_STACK_ARRAY] = {0}; @@ -495,13 +1928,15 @@ static PyObject *BPy_BoolVectorProperty(PyObject *self, PyObject *args, PyObject char *pysubtype = NULL; int subtype = PROP_NONE; PyObject *update_cb = NULL; + PyObject *get_cb = NULL; + PyObject *set_cb = NULL; if (!PyArg_ParseTupleAndKeywords(args, kw, - "s#|ssOO!siO:BoolVectorProperty", + "s#|ssOO!siOOO:BoolVectorProperty", (char **)kwlist, &id, &id_len, &name, &description, &pydef, &PySet_Type, &pyopts, &pysubtype, &size, - &update_cb)) + &update_cb, &get_cb, &set_cb)) { return NULL; } @@ -515,10 +1950,16 @@ static PyObject *BPy_BoolVectorProperty(PyObject *self, PyObject *args, PyObject return NULL; } - if (pydef && PyC_AsArray(def, pydef, size, &PyBool_Type, FALSE, "BoolVectorProperty(default=sequence)") < 0) + if (pydef && PyC_AsArray(def, pydef, size, &PyBool_Type, false, "BoolVectorProperty(default=sequence)") == -1) return NULL; - if (bpy_prop_callback_check(update_cb, 2) == -1) { + if (bpy_prop_callback_check(update_cb, "update", 2) == -1) { + return NULL; + } + if (bpy_prop_callback_check(get_cb, "get", 1) == -1) { + return NULL; + } + if (bpy_prop_callback_check(set_cb, "set", 2) == -1) { return NULL; } @@ -534,7 +1975,8 @@ static PyObject *BPy_BoolVectorProperty(PyObject *self, PyObject *args, PyObject if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE); if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION); } - bpy_prop_callback_assign(prop, update_cb); + bpy_prop_callback_assign_update(prop, update_cb); + bpy_prop_callback_assign_boolean_array(prop, get_cb, set_cb); RNA_def_property_duplicate_pointers(srna, prop); } @@ -550,7 +1992,9 @@ PyDoc_STRVAR(BPy_IntProperty_doc, "step=1, " "options={'ANIMATABLE'}, " "subtype='NONE', " - "update=None)\n" + "update=None, " + "get=None, " + "set=None)\n" "\n" " Returns a new int property definition.\n" "\n" @@ -571,7 +2015,7 @@ static PyObject *BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw) if (srna) { static const char *kwlist[] = {"attr", "name", "description", "default", "min", "max", "soft_min", "soft_max", - "step", "options", "subtype", "update", NULL}; + "step", "options", "subtype", "update", "get", "set", NULL}; const char *id = NULL, *name = NULL, *description = ""; int id_len; int min = INT_MIN, max = INT_MAX, soft_min = INT_MIN, soft_max = INT_MAX, step = 1, def = 0; @@ -581,21 +2025,29 @@ static PyObject *BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw) char *pysubtype = NULL; int subtype = PROP_NONE; PyObject *update_cb = NULL; + PyObject *get_cb = NULL; + PyObject *set_cb = NULL; if (!PyArg_ParseTupleAndKeywords(args, kw, - "s#|ssiiiiiiO!sO:IntProperty", + "s#|ssiiiiiiO!sOOO:IntProperty", (char **)kwlist, &id, &id_len, &name, &description, &def, &min, &max, &soft_min, &soft_max, &step, &PySet_Type, &pyopts, &pysubtype, - &update_cb)) + &update_cb, &get_cb, &set_cb)) { return NULL; } BPY_PROPDEF_SUBTYPE_CHECK(IntProperty, property_flag_items, property_subtype_number_items); - if (bpy_prop_callback_check(update_cb, 2) == -1) { + if (bpy_prop_callback_check(update_cb, "update", 2) == -1) { + return NULL; + } + if (bpy_prop_callback_check(get_cb, "get", 1) == -1) { + return NULL; + } + if (bpy_prop_callback_check(set_cb, "set", 2) == -1) { return NULL; } @@ -611,7 +2063,8 @@ static PyObject *BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw) if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE); if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION); } - bpy_prop_callback_assign(prop, update_cb); + bpy_prop_callback_assign_update(prop, update_cb); + bpy_prop_callback_assign_int(prop, get_cb, set_cb); RNA_def_property_duplicate_pointers(srna, prop); } Py_RETURN_NONE; @@ -626,7 +2079,9 @@ PyDoc_STRVAR(BPy_IntVectorProperty_doc, "options={'ANIMATABLE'}, " "subtype='NONE', " "size=3, " - "update=None)\n" + "update=None, " + "get=None, " + "set=None)\n" "\n" " Returns a new vector int property definition.\n" "\n" @@ -653,7 +2108,7 @@ static PyObject *BPy_IntVectorProperty(PyObject *self, PyObject *args, PyObject if (srna) { static const char *kwlist[] = {"attr", "name", "description", "default", "min", "max", "soft_min", "soft_max", - "step", "options", "subtype", "size", "update", NULL}; + "step", "options", "subtype", "size", "update", "get", "set", NULL}; const char *id = NULL, *name = NULL, *description = ""; int id_len; int min = INT_MIN, max = INT_MAX, soft_min = INT_MIN, soft_max = INT_MAX, step = 1; @@ -666,15 +2121,17 @@ static PyObject *BPy_IntVectorProperty(PyObject *self, PyObject *args, PyObject char *pysubtype = NULL; int subtype = PROP_NONE; PyObject *update_cb = NULL; + PyObject *get_cb = NULL; + PyObject *set_cb = NULL; if (!PyArg_ParseTupleAndKeywords(args, kw, - "s#|ssOiiiiiO!siO:IntVectorProperty", + "s#|ssOiiiiiO!siOOO:IntVectorProperty", (char **)kwlist, &id, &id_len, &name, &description, &pydef, &min, &max, &soft_min, &soft_max, &step, &PySet_Type, &pyopts, &pysubtype, &size, - &update_cb)) + &update_cb, &get_cb, &set_cb)) { return NULL; } @@ -688,10 +2145,16 @@ static PyObject *BPy_IntVectorProperty(PyObject *self, PyObject *args, PyObject return NULL; } - if (pydef && PyC_AsArray(def, pydef, size, &PyLong_Type, FALSE, "IntVectorProperty(default=sequence)") < 0) + if (pydef && PyC_AsArray(def, pydef, size, &PyLong_Type, false, "IntVectorProperty(default=sequence)") == -1) return NULL; - if (bpy_prop_callback_check(update_cb, 2) == -1) { + if (bpy_prop_callback_check(update_cb, "update", 2) == -1) { + return NULL; + } + if (bpy_prop_callback_check(get_cb, "get", 1) == -1) { + return NULL; + } + if (bpy_prop_callback_check(set_cb, "set", 2) == -1) { return NULL; } @@ -708,7 +2171,8 @@ static PyObject *BPy_IntVectorProperty(PyObject *self, PyObject *args, PyObject if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE); if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION); } - bpy_prop_callback_assign(prop, update_cb); + bpy_prop_callback_assign_update(prop, update_cb); + bpy_prop_callback_assign_int_array(prop, get_cb, set_cb); RNA_def_property_duplicate_pointers(srna, prop); } Py_RETURN_NONE; @@ -726,7 +2190,9 @@ PyDoc_STRVAR(BPy_FloatProperty_doc, "options={'ANIMATABLE'}, " "subtype='NONE', " "unit='NONE', " - "update=None)\n" + "update=None, " + "get=None, " + "set=None)\n" "\n" " Returns a new float property definition.\n" "\n" @@ -748,7 +2214,8 @@ static PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw) if (srna) { static const char *kwlist[] = {"attr", "name", "description", "default", "min", "max", "soft_min", "soft_max", - "step", "precision", "options", "subtype", "unit", "update", NULL}; + "step", "precision", "options", "subtype", + "unit", "update", "get", "set", NULL}; const char *id = NULL, *name = NULL, *description = ""; int id_len; float min = -FLT_MAX, max = FLT_MAX, soft_min = -FLT_MAX, soft_max = FLT_MAX, step = 3, def = 0.0f; @@ -761,15 +2228,17 @@ static PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw) char *pyunit = NULL; int unit = PROP_UNIT_NONE; PyObject *update_cb = NULL; + PyObject *get_cb = NULL; + PyObject *set_cb = NULL; if (!PyArg_ParseTupleAndKeywords(args, kw, - "s#|ssffffffiO!ssO:FloatProperty", + "s#|ssffffffiO!ssOOO:FloatProperty", (char **)kwlist, &id, &id_len, &name, &description, &def, &min, &max, &soft_min, &soft_max, &step, &precision, &PySet_Type, &pyopts, &pysubtype, &pyunit, - &update_cb)) + &update_cb, &get_cb, &set_cb)) { return NULL; } @@ -781,7 +2250,13 @@ static PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw) return NULL; } - if (bpy_prop_callback_check(update_cb, 2) == -1) { + if (bpy_prop_callback_check(update_cb, "update", 2) == -1) { + return NULL; + } + if (bpy_prop_callback_check(get_cb, "get", 1) == -1) { + return NULL; + } + if (bpy_prop_callback_check(set_cb, "set", 2) == -1) { return NULL; } @@ -797,7 +2272,8 @@ static PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw) if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE); if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION); } - bpy_prop_callback_assign(prop, update_cb); + bpy_prop_callback_assign_update(prop, update_cb); + bpy_prop_callback_assign_float(prop, get_cb, set_cb); RNA_def_property_duplicate_pointers(srna, prop); } Py_RETURN_NONE; @@ -814,7 +2290,9 @@ PyDoc_STRVAR(BPy_FloatVectorProperty_doc, "options={'ANIMATABLE'}, " "subtype='NONE', " "size=3, " - "update=None)\n" + "update=None, " + "get=None, " + "set=None)\n" "\n" " Returns a new vector float property definition.\n" "\n" @@ -842,7 +2320,8 @@ static PyObject *BPy_FloatVectorProperty(PyObject *self, PyObject *args, PyObjec if (srna) { static const char *kwlist[] = {"attr", "name", "description", "default", "min", "max", "soft_min", "soft_max", - "step", "precision", "options", "subtype", "unit", "size", "update", NULL}; + "step", "precision", "options", "subtype", + "unit", "size", "update", "get", "set", NULL}; const char *id = NULL, *name = NULL, *description = ""; int id_len; float min = -FLT_MAX, max = FLT_MAX, soft_min = -FLT_MAX, soft_max = FLT_MAX, step = 3; @@ -857,15 +2336,17 @@ static PyObject *BPy_FloatVectorProperty(PyObject *self, PyObject *args, PyObjec char *pyunit = NULL; int unit = PROP_UNIT_NONE; PyObject *update_cb = NULL; + PyObject *get_cb = NULL; + PyObject *set_cb = NULL; if (!PyArg_ParseTupleAndKeywords(args, kw, - "s#|ssOfffffiO!ssiO:FloatVectorProperty", + "s#|ssOfffffiO!ssiOOO:FloatVectorProperty", (char **)kwlist, &id, &id_len, &name, &description, &pydef, &min, &max, &soft_min, &soft_max, &step, &precision, &PySet_Type, &pyopts, &pysubtype, &pyunit, &size, - &update_cb)) + &update_cb, &get_cb, &set_cb)) { return NULL; } @@ -884,10 +2365,16 @@ static PyObject *BPy_FloatVectorProperty(PyObject *self, PyObject *args, PyObjec return NULL; } - if (pydef && PyC_AsArray(def, pydef, size, &PyFloat_Type, FALSE, "FloatVectorProperty(default=sequence)") < 0) + if (pydef && PyC_AsArray(def, pydef, size, &PyFloat_Type, false, "FloatVectorProperty(default=sequence)") == -1) return NULL; - if (bpy_prop_callback_check(update_cb, 2) == -1) { + if (bpy_prop_callback_check(update_cb, "update", 2) == -1) { + return NULL; + } + if (bpy_prop_callback_check(get_cb, "get", 1) == -1) { + return NULL; + } + if (bpy_prop_callback_check(set_cb, "set", 2) == -1) { return NULL; } @@ -904,7 +2391,8 @@ static PyObject *BPy_FloatVectorProperty(PyObject *self, PyObject *args, PyObjec if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE); if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION); } - bpy_prop_callback_assign(prop, update_cb); + bpy_prop_callback_assign_update(prop, update_cb); + bpy_prop_callback_assign_float_array(prop, get_cb, set_cb); RNA_def_property_duplicate_pointers(srna, prop); } Py_RETURN_NONE; @@ -917,7 +2405,9 @@ PyDoc_STRVAR(BPy_StringProperty_doc, "maxlen=0, " "options={'ANIMATABLE'}, " "subtype='NONE', " - "update=None)\n" + "update=None, " + "get=None, " + "set=None)\n" "\n" " Returns a new string property definition.\n" "\n" @@ -937,7 +2427,7 @@ static PyObject *BPy_StringProperty(PyObject *self, PyObject *args, PyObject *kw if (srna) { static const char *kwlist[] = {"attr", "name", "description", "default", - "maxlen", "options", "subtype", "update", NULL}; + "maxlen", "options", "subtype", "update", "get", "set", NULL}; const char *id = NULL, *name = NULL, *description = "", *def = ""; int id_len; int maxlen = 0; @@ -947,20 +2437,28 @@ static PyObject *BPy_StringProperty(PyObject *self, PyObject *args, PyObject *kw char *pysubtype = NULL; int subtype = PROP_NONE; PyObject *update_cb = NULL; + PyObject *get_cb = NULL; + PyObject *set_cb = NULL; if (!PyArg_ParseTupleAndKeywords(args, kw, - "s#|sssiO!sO:StringProperty", + "s#|sssiO!sOOO:StringProperty", (char **)kwlist, &id, &id_len, &name, &description, &def, &maxlen, &PySet_Type, &pyopts, &pysubtype, - &update_cb)) + &update_cb, &get_cb, &set_cb)) { return NULL; } BPY_PROPDEF_SUBTYPE_CHECK(StringProperty, property_flag_items, property_subtype_string_items); - if (bpy_prop_callback_check(update_cb, 2) == -1) { + if (bpy_prop_callback_check(update_cb, "update", 2) == -1) { + return NULL; + } + if (bpy_prop_callback_check(get_cb, "get", 1) == -1) { + return NULL; + } + if (bpy_prop_callback_check(set_cb, "set", 2) == -1) { return NULL; } @@ -975,246 +2473,22 @@ static PyObject *BPy_StringProperty(PyObject *self, PyObject *args, PyObject *kw if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE); if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION); } - bpy_prop_callback_assign(prop, update_cb); + bpy_prop_callback_assign_update(prop, update_cb); + bpy_prop_callback_assign_string(prop, get_cb, set_cb); RNA_def_property_duplicate_pointers(srna, prop); } Py_RETURN_NONE; } -#if 0 -/* copies orig to buf, then sets orig to buf, returns copy length */ -static size_t strswapbufcpy(char *buf, const char **orig) -{ - const char *src = *orig; - char *dst = buf; - size_t i = 0; - *orig = buf; - while ((*dst = *src)) { dst++; src++; i++; } - return i + 1; /* include '\0' */ -} -#endif - -static EnumPropertyItem *enum_items_from_py(PyObject *seq_fast, PyObject *def, int *defvalue, const short is_enum_flag) -{ - EnumPropertyItem *items; - PyObject *item; - const Py_ssize_t seq_len = PySequence_Fast_GET_SIZE(seq_fast); - Py_ssize_t totbuf = 0; - int i; - short def_used = 0; - const char *def_cmp = NULL; - - if (is_enum_flag) { - if (seq_len > RNA_ENUM_BITFLAG_SIZE) { - PyErr_SetString(PyExc_TypeError, - "EnumProperty(...): maximum " - STRINGIFY(RNA_ENUM_BITFLAG_SIZE) - " members for a ENUM_FLAG type property"); - return NULL; - } - if (def && !PySet_Check(def)) { - PyErr_Format(PyExc_TypeError, - "EnumProperty(...): default option must be a 'set' " - "type when ENUM_FLAG is enabled, not a '%.200s'", - Py_TYPE(def)->tp_name); - return NULL; - } - } - else { - if (def) { - def_cmp = _PyUnicode_AsString(def); - if (def_cmp == NULL) { - PyErr_Format(PyExc_TypeError, - "EnumProperty(...): default option must be a 'str' " - "type when ENUM_FLAG is disabled, not a '%.200s'", - Py_TYPE(def)->tp_name); - return NULL; - } - } - } - - /* blank value */ - *defvalue = 0; - - items = MEM_callocN(sizeof(EnumPropertyItem) * (seq_len + 1), "enum_items_from_py1"); - - for (i = 0; i < seq_len; i++) { - EnumPropertyItem tmp = {0, "", 0, "", ""}; - Py_ssize_t item_size; - Py_ssize_t id_str_size; - Py_ssize_t name_str_size; - Py_ssize_t desc_str_size; - - item = PySequence_Fast_GET_ITEM(seq_fast, i); - - if ((PyTuple_CheckExact(item)) && - (item_size = PyTuple_GET_SIZE(item)) && - (item_size == 3 || item_size == 4) && - (tmp.identifier = _PyUnicode_AsStringAndSize(PyTuple_GET_ITEM(item, 0), &id_str_size)) && - (tmp.name = _PyUnicode_AsStringAndSize(PyTuple_GET_ITEM(item, 1), &name_str_size)) && - (tmp.description = _PyUnicode_AsStringAndSize(PyTuple_GET_ITEM(item, 2), &desc_str_size)) && - /* TODO, number isn't ensured to be unique from the script author */ - (item_size < 4 || py_long_as_int(PyTuple_GET_ITEM(item, 3), &tmp.value) != -1)) - { - if (is_enum_flag) { - if (item_size < 4) { - tmp.value = 1 << i; - } - - if (def && PySet_Contains(def, PyTuple_GET_ITEM(item, 0))) { - *defvalue |= tmp.value; - def_used++; - } - } - else { - if (item_size < 4) { - tmp.value = i; - } - - if (def && def_used == 0 && strcmp(def_cmp, tmp.identifier) == 0) { - *defvalue = tmp.value; - def_used++; /* only ever 1 */ - } - } - - items[i] = tmp; - - /* calculate combine string length */ - totbuf += id_str_size + name_str_size + desc_str_size + 3; /* 3 is for '\0's */ - } - else { - MEM_freeN(items); - PyErr_SetString(PyExc_TypeError, - "EnumProperty(...): expected a tuple containing " - "(identifier, name, description) and optionally a " - "unique number"); - return NULL; - } - - } - - if (is_enum_flag) { - /* strict check that all set members were used */ - if (def && def_used != PySet_GET_SIZE(def)) { - MEM_freeN(items); - - PyErr_Format(PyExc_TypeError, - "EnumProperty(..., default={...}): set has %d unused member(s)", - PySet_GET_SIZE(def) - def_used); - return NULL; - } - } - else { - if (def && def_used == 0) { - MEM_freeN(items); - - PyErr_Format(PyExc_TypeError, - "EnumProperty(..., default=\'%s\'): not found in enum members", - def_cmp); - return NULL; - } - } - - /* disabled duplicating strings because the array can still be freed and - * the strings from it referenced, for now we can't support dynamically - * created strings from python. */ -#if 0 - /* this would all work perfectly _but_ the python strings may be freed - * immediately after use, so we need to duplicate them, ugh. - * annoying because it works most of the time without this. */ - { - EnumPropertyItem *items_dup = MEM_mallocN((sizeof(EnumPropertyItem) * (seq_len + 1)) + (sizeof(char) * totbuf), - "enum_items_from_py2"); - EnumPropertyItem *items_ptr = items_dup; - char *buf = ((char *)items_dup) + (sizeof(EnumPropertyItem) * (seq_len + 1)); - memcpy(items_dup, items, sizeof(EnumPropertyItem) * (seq_len + 1)); - for (i = 0; i < seq_len; i++, items_ptr++) { - buf += strswapbufcpy(buf, &items_ptr->identifier); - buf += strswapbufcpy(buf, &items_ptr->name); - buf += strswapbufcpy(buf, &items_ptr->description); - } - MEM_freeN(items); - items = items_dup; - } - /* end string duplication */ -#endif - - return items; -} - -static EnumPropertyItem *bpy_props_enum_itemf(struct bContext *C, PointerRNA *ptr, PropertyRNA *prop, int *free) -{ - PyGILState_STATE gilstate; - - PyObject *py_func = RNA_property_enum_py_data_get(prop); - PyObject *self = NULL; - PyObject *args; - PyObject *items; /* returned from the function call */ - - EnumPropertyItem *eitems = NULL; - int err = 0; - - bpy_context_set(C, &gilstate); - - args = PyTuple_New(2); - self = pyrna_struct_as_instance(ptr); - PyTuple_SET_ITEM(args, 0, self); - - /* now get the context */ - PyTuple_SET_ITEM(args, 1, (PyObject *)bpy_context_module); - Py_INCREF(bpy_context_module); - - items = PyObject_CallObject(py_func, args); - - Py_DECREF(args); - - if (items == NULL) { - err = -1; - } - else { - PyObject *items_fast; - int defvalue_dummy = 0; - - if (!(items_fast = PySequence_Fast(items, "EnumProperty(...): " - "return value from the callback was not a sequence"))) - { - err = -1; - } - else { - eitems = enum_items_from_py(items_fast, NULL, &defvalue_dummy, - (RNA_property_flag(prop) & PROP_ENUM_FLAG) != 0); - - Py_DECREF(items_fast); - - if (!eitems) { - err = -1; - } - } - - Py_DECREF(items); - } - - if (err != -1) { /* worked */ - *free = 1; - } - else { - printf_func_error(py_func); - - eitems = DummyRNA_NULL_items; - } - - - bpy_context_clear(C, &gilstate); - return eitems; -} - PyDoc_STRVAR(BPy_EnumProperty_doc, ".. function:: EnumProperty(items, " "name=\"\", " "description=\"\", " "default=\"\", " "options={'ANIMATABLE'}, " - "update=None)\n" + "update=None, " + "get=None, " + "set=None)\n" "\n" " Returns a new enumerator property definition.\n" "\n" @@ -1246,7 +2520,7 @@ static PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw) if (srna) { static const char *kwlist[] = {"attr", "items", "name", "description", "default", - "options", "update", NULL}; + "options", "update", "get", "set", NULL}; const char *id = NULL, *name = NULL, *description = ""; PyObject *def = NULL; int id_len; @@ -1256,22 +2530,30 @@ static PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw) PropertyRNA *prop; PyObject *pyopts = NULL; int opts = 0; - short is_itemf = FALSE; + bool is_itemf = false; PyObject *update_cb = NULL; + PyObject *get_cb = NULL; + PyObject *set_cb = NULL; if (!PyArg_ParseTupleAndKeywords(args, kw, - "s#O|ssOO!O:EnumProperty", + "s#O|ssOO!OOO:EnumProperty", (char **)kwlist, &id, &id_len, &items, &name, &description, &def, &PySet_Type, &pyopts, - &update_cb)) + &update_cb, &get_cb, &set_cb)) { return NULL; } BPY_PROPDEF_CHECK(EnumProperty, property_flag_enum_items); - if (bpy_prop_callback_check(update_cb, 2) == -1) { + if (bpy_prop_callback_check(update_cb, "update", 2) == -1) { + return NULL; + } + if (bpy_prop_callback_check(get_cb, "get", 1) == -1) { + return NULL; + } + if (bpy_prop_callback_check(set_cb, "set", 2) == -1) { return NULL; } @@ -1292,7 +2574,7 @@ static PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw) return NULL; } - is_itemf = TRUE; + is_itemf = true; eitems = DummyRNA_NULL_items; } else { @@ -1314,25 +2596,17 @@ static PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw) if (opts & PROP_ENUM_FLAG) prop = RNA_def_enum_flag(srna, id, eitems, defvalue, name ? name : id, description); else prop = RNA_def_enum(srna, id, eitems, defvalue, name ? name : id, description); - if (is_itemf) { - RNA_def_enum_funcs(prop, bpy_props_enum_itemf); - RNA_def_enum_py_data(prop, (void *)items); - - /* watch out!, if a user is tricky they can probably crash blender - * if they manage to free the callback, take care! */ - /* Py_INCREF(items); */ - } - if (pyopts) { if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN); if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE); if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION); } - bpy_prop_callback_assign(prop, update_cb); + bpy_prop_callback_assign_update(prop, update_cb); + bpy_prop_callback_assign_enum(prop, get_cb, set_cb, (is_itemf ? items : NULL)); RNA_def_property_duplicate_pointers(srna, prop); - if (is_itemf == FALSE) { + if (is_itemf == false) { /* note: this must be postponed until after #RNA_def_property_duplicate_pointers * otherwise if this is a generator it may free the strings before we copy them */ Py_DECREF(items_fast); @@ -1424,7 +2698,7 @@ static PyObject *BPy_PointerProperty(PyObject *self, PyObject *args, PyObject *k if (!ptype) return NULL; - if (bpy_prop_callback_check(update_cb, 2) == -1) { + if (bpy_prop_callback_check(update_cb, "update", 2) == -1) { return NULL; } @@ -1435,7 +2709,7 @@ static PyObject *BPy_PointerProperty(PyObject *self, PyObject *args, PyObject *k if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE); if (opts & PROP_LIB_EXCEPTION) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION); } - bpy_prop_callback_assign(prop, update_cb); + bpy_prop_callback_assign_update(prop, update_cb); RNA_def_property_duplicate_pointers(srna, prop); } Py_RETURN_NONE; diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index bc245ecda5c..94f262f57f5 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -37,6 +37,12 @@ #include "RNA_types.h" +#include "BLI_dynstr.h" +#include "BLI_string.h" +#include "BLI_listbase.h" +#include "BLI_math_rotation.h" +#include "BLI_utildefines.h" + #include "BPY_extern.h" #include "bpy_rna.h" @@ -50,12 +56,6 @@ # include "MEM_guardedalloc.h" #endif -#include "BLI_dynstr.h" -#include "BLI_string.h" -#include "BLI_listbase.h" -#include "BLI_math_rotation.h" -#include "BLI_utildefines.h" - #ifdef USE_PYRNA_INVALIDATE_WEAKREF # include "BLI_ghash.h" #endif @@ -309,9 +309,9 @@ void BPY_id_release(struct ID *id) } #ifdef USE_PEDANTIC_WRITE -static short rna_disallow_writes = FALSE; +static bool rna_disallow_writes = false; -static int rna_id_write_error(PointerRNA *ptr, PyObject *key) +static bool rna_id_write_error(PointerRNA *ptr, PyObject *key) { ID *id = ptr->id.data; if (id) { @@ -329,30 +329,30 @@ static int rna_id_write_error(PointerRNA *ptr, PyObject *key) "%.200s, %.200s datablock, error setting %.200s.%.200s", id->name + 2, idtype, RNA_struct_identifier(ptr->type), pyname); - return TRUE; + return true; } } - return FALSE; + return false; } #endif /* USE_PEDANTIC_WRITE */ #ifdef USE_PEDANTIC_WRITE -int pyrna_write_check(void) +bool pyrna_write_check(void) { return !rna_disallow_writes; } -void pyrna_write_set(int val) +void pyrna_write_set(bool val) { rna_disallow_writes = !val; } #else /* USE_PEDANTIC_WRITE */ -int pyrna_write_check(void) +bool pyrna_write_check(void) { - return TRUE; + return true; } -void pyrna_write_set(int UNUSED(val)) +void pyrna_write_set(bool UNUSED(val)) { /* nothing */ } @@ -644,7 +644,7 @@ PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop) RNA_property_float_get_array(ptr, prop, ((MatrixObject *)ret)->matrix); } else { - PyObject *mat_cb = Matrix_CreatePyObject_cb(ret, 4, 4, mathutils_rna_matrix_cb_index, FALSE); + PyObject *mat_cb = Matrix_CreatePyObject_cb(ret, 4, 4, mathutils_rna_matrix_cb_index, 0); Py_DECREF(ret); /* the matrix owns now */ ret = mat_cb; /* return the matrix instead */ } @@ -655,7 +655,7 @@ PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop) RNA_property_float_get_array(ptr, prop, ((MatrixObject *)ret)->matrix); } else { - PyObject *mat_cb = Matrix_CreatePyObject_cb(ret, 3, 3, mathutils_rna_matrix_cb_index, FALSE); + PyObject *mat_cb = Matrix_CreatePyObject_cb(ret, 3, 3, mathutils_rna_matrix_cb_index, 0); Py_DECREF(ret); /* the matrix owns now */ ret = mat_cb; /* return the matrix instead */ } @@ -1123,7 +1123,7 @@ static const char *pyrna_enum_as_string(PointerRNA *ptr, PropertyRNA *prop) { EnumPropertyItem *item; const char *result; - int free = FALSE; + int free = false; RNA_property_enum_items(BPy_GetContext(), ptr, prop, &item, NULL, &free); if (item) { @@ -1187,7 +1187,7 @@ int pyrna_set_to_enum_bitfield(EnumPropertyItem *items, PyObject *value, int *r_ return -1; } - if (pyrna_enum_value_from_id(items, param, &ret, error_prefix) < 0) { + if (pyrna_enum_value_from_id(items, param, &ret, error_prefix) == -1) { return -1; } @@ -1202,7 +1202,7 @@ static int pyrna_prop_to_enum_bitfield(PointerRNA *ptr, PropertyRNA *prop, PyObj { EnumPropertyItem *item; int ret; - int free = FALSE; + int free = false; *r_value = 0; @@ -1282,7 +1282,7 @@ static PyObject *pyrna_enum_to_py(PointerRNA *ptr, PropertyRNA *prop, int val) } else { EnumPropertyItem *enum_item; - int free = FALSE; + int free = false; /* don't throw error here, can't trust blender 100% to give the * right values, python code should not generate error for that */ @@ -1682,13 +1682,13 @@ static int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyOb /* type checkins is done by each function */ if (RNA_property_flag(prop) & PROP_ENUM_FLAG) { /* set of enum items, concatenate all values with OR */ - if (pyrna_prop_to_enum_bitfield(ptr, prop, value, &val, error_prefix) < 0) { + if (pyrna_prop_to_enum_bitfield(ptr, prop, value, &val, error_prefix) == -1) { return -1; } } else { /* simple enum string */ - if (pyrna_string_to_enum(value, ptr, prop, &val, error_prefix) < 0) { + if (pyrna_string_to_enum(value, ptr, prop, &val, error_prefix) == -1) { return -1; } } @@ -1777,7 +1777,7 @@ static int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyOb } else { BPy_StructRNA *param = (BPy_StructRNA *)value; - int raise_error = FALSE; + bool raise_error = false; if (data) { if (flag & PROP_RNAPTR) { @@ -1804,7 +1804,7 @@ static int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyOb *((void **)data) = param->ptr.data; } else { - raise_error = TRUE; + raise_error = true; } } else { @@ -2195,7 +2195,7 @@ static int pyrna_prop_collection_subscript_str_lib_pair_ptr(BPy_PropertyRNA *sel else { PyObject *keylib = PyTuple_GET_ITEM(key, 1); Library *lib; - int found = FALSE; + bool found = false; if (keylib == Py_None) { lib = NULL; @@ -2232,7 +2232,7 @@ static int pyrna_prop_collection_subscript_str_lib_pair_ptr(BPy_PropertyRNA *sel { ID *id = itemptr.data; /* always an ID */ if (id->lib == lib && (strncmp(keyname, id->name + 2, sizeof(id->name) - 2) == 0)) { - found = TRUE; + found = true; if (r_ptr) { *r_ptr = itemptr; } @@ -2242,7 +2242,7 @@ static int pyrna_prop_collection_subscript_str_lib_pair_ptr(BPy_PropertyRNA *sel RNA_PROP_END; /* we may want to fail silently as with collection.get() */ - if ((found == FALSE) && err_not_found) { + if ((found == false) && err_not_found) { /* only runs for getitem access so use fixed string */ PyErr_SetString(PyExc_KeyError, "bpy_prop_collection[key, lib]: not found"); @@ -2255,7 +2255,7 @@ static int pyrna_prop_collection_subscript_str_lib_pair_ptr(BPy_PropertyRNA *sel } static PyObject *pyrna_prop_collection_subscript_str_lib_pair(BPy_PropertyRNA *self, PyObject *key, - const char *err_prefix, const short err_not_found) + const char *err_prefix, const bool err_not_found) { PointerRNA ptr; const int contains = pyrna_prop_collection_subscript_str_lib_pair_ptr(self, key, err_prefix, err_not_found, &ptr); @@ -2448,7 +2448,7 @@ static PyObject *pyrna_prop_collection_subscript(BPy_PropertyRNA *self, PyObject else if (PyTuple_Check(key)) { /* special case, for ID datablocks we */ return pyrna_prop_collection_subscript_str_lib_pair(self, key, - "bpy_prop_collection[id, lib]", TRUE); + "bpy_prop_collection[id, lib]", true); } else { PyErr_Format(PyExc_TypeError, @@ -2865,7 +2865,7 @@ static int pyrna_prop_collection_contains(BPy_PropertyRNA *self, PyObject *key) if (PyTuple_Check(key)) { /* special case, for ID datablocks we */ return pyrna_prop_collection_subscript_str_lib_pair_ptr(self, key, - "(id, lib) in bpy_prop_collection", FALSE, NULL); + "(id, lib) in bpy_prop_collection", false, NULL); } else { @@ -4205,7 +4205,7 @@ static PyObject *pyrna_prop_collection_get(BPy_PropertyRNA *self, PyObject *args } else if (PyTuple_Check(key_ob)) { PyObject *ret = pyrna_prop_collection_subscript_str_lib_pair(self, key_ob, - "bpy_prop_collection.get((id, lib))", FALSE); + "bpy_prop_collection.get((id, lib))", false); if (ret) { return ret; } @@ -4267,12 +4267,12 @@ static PyObject *pyrna_prop_collection_find(BPy_PropertyRNA *self, PyObject *key static void foreach_attr_type(BPy_PropertyRNA *self, const char *attr, /* values to assign */ - RawPropertyType *raw_type, int *attr_tot, int *attr_signed) + RawPropertyType *raw_type, int *attr_tot, bool *attr_signed) { PropertyRNA *prop; *raw_type = PROP_RAW_UNSET; *attr_tot = 0; - *attr_signed = FALSE; + *attr_signed = false; /* note: this is fail with zero length lists, so don't let this get caled in that case */ RNA_PROP_BEGIN (&self->ptr, itemptr, self->prop) @@ -4280,7 +4280,7 @@ static void foreach_attr_type(BPy_PropertyRNA *self, const char *attr, prop = RNA_struct_find_property(&itemptr, attr); *raw_type = RNA_property_raw_type(prop); *attr_tot = RNA_property_array_length(&itemptr, prop); - *attr_signed = (RNA_property_subtype(prop) == PROP_UNSIGNED) ? FALSE : TRUE; + *attr_signed = (RNA_property_subtype(prop) == PROP_UNSIGNED) ? false : true; break; } RNA_PROP_END; @@ -4291,7 +4291,7 @@ static int foreach_parse_args(BPy_PropertyRNA *self, PyObject *args, /* values to assign */ const char **attr, PyObject **seq, int *tot, int *size, - RawPropertyType *raw_type, int *attr_tot, int *attr_signed + RawPropertyType *raw_type, int *attr_tot, bool *attr_signed ) { #if 0 @@ -4299,7 +4299,8 @@ static int foreach_parse_args(BPy_PropertyRNA *self, PyObject *args, int target_tot; #endif - *size = *attr_tot = *attr_signed = FALSE; + *size = *attr_tot = 0; + *attr_signed = false; *raw_type = PROP_RAW_UNSET; if (!PyArg_ParseTuple(args, "sO", attr, seq) || (!PySequence_Check(*seq) && PyObject_CheckBuffer(*seq))) { @@ -4344,7 +4345,7 @@ static int foreach_parse_args(BPy_PropertyRNA *self, PyObject *args, return 0; } -static int foreach_compat_buffer(RawPropertyType raw_type, int attr_signed, const char *format) +static bool foreach_compat_buffer(RawPropertyType raw_type, int attr_signed, const char *format) { char f = format ? *format : 'B'; /* B is assumed when not set */ @@ -4372,16 +4373,18 @@ static int foreach_compat_buffer(RawPropertyType raw_type, int attr_signed, cons static PyObject *foreach_getset(BPy_PropertyRNA *self, PyObject *args, int set) { PyObject *item = NULL; - int i = 0, ok = 0, buffer_is_compat; + int i = 0, ok = 0; + bool buffer_is_compat; void *array = NULL; /* get/set both take the same args currently */ const char *attr; PyObject *seq; - int tot, size, attr_tot, attr_signed; + int tot, size, attr_tot; + bool attr_signed; RawPropertyType raw_type; - if (foreach_parse_args(self, args, &attr, &seq, &tot, &size, &raw_type, &attr_tot, &attr_signed) < 0) + if (foreach_parse_args(self, args, &attr, &seq, &tot, &size, &raw_type, &attr_tot, &attr_signed) == -1) return NULL; if (tot == 0) @@ -4390,7 +4393,7 @@ static PyObject *foreach_getset(BPy_PropertyRNA *self, PyObject *args, int set) if (set) { /* get the array from python */ - buffer_is_compat = FALSE; + buffer_is_compat = false; if (PyObject_CheckBuffer(seq)) { Py_buffer buf; PyObject_GetBuffer(seq, &buf, PyBUF_SIMPLE | PyBUF_FORMAT); @@ -4441,7 +4444,7 @@ static PyObject *foreach_getset(BPy_PropertyRNA *self, PyObject *args, int set) } } else { - buffer_is_compat = FALSE; + buffer_is_compat = false; if (PyObject_CheckBuffer(seq)) { Py_buffer buf; PyObject_GetBuffer(seq, &buf, PyBUF_SIMPLE | PyBUF_FORMAT); @@ -4945,7 +4948,8 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject ParameterIterator iter; PropertyRNA *parm; PyObject *ret, *item; - int i, pyargs_len, pykw_len, parms_len, ret_len, flag, err = 0, kw_tot = 0, kw_arg; + int i, pyargs_len, pykw_len, parms_len, ret_len, flag, err = 0, kw_tot = 0; + bool kw_arg; PropertyRNA *pret_single = NULL; void *retdata_single = NULL; @@ -5026,7 +5030,7 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject if (i < pyargs_len) { item = PyTuple_GET_ITEM(args, i); - kw_arg = FALSE; + kw_arg = false; } else if (kw != NULL) { #if 0 @@ -5037,7 +5041,7 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject if (item) kw_tot++; /* make sure invalid keywords are not given */ - kw_arg = TRUE; + kw_arg = true; } i++; /* current argument */ @@ -5074,7 +5078,7 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject char error_prefix[512]; PyErr_Clear(); /* re-raise */ - if (kw_arg == TRUE) + if (kw_arg == true) BLI_snprintf(error_prefix, sizeof(error_prefix), "%.200s.%.200s(): error with keyword argument \"%.200s\" - ", RNA_struct_identifier(self_ptr->type), @@ -5109,12 +5113,12 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject DynStr *good_args = BLI_dynstr_new(); const char *arg_name, *bad_args_str, *good_args_str; - int found = FALSE, first = TRUE; + bool found = false, first = true; while (PyDict_Next(kw, &pos, &key, &value)) { arg_name = _PyUnicode_AsString(key); - found = FALSE; + found = false; if (arg_name == NULL) { /* unlikely the argname is not a string but ignore if it is*/ PyErr_Clear(); @@ -5125,22 +5129,22 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject for (; iter.valid; RNA_parameter_list_next(&iter)) { parm = iter.parm; if (strcmp(arg_name, RNA_property_identifier(parm)) == 0) { - found = TRUE; + found = true; break; } } RNA_parameter_list_end(&iter); - if (found == FALSE) { + if (found == false) { BLI_dynstr_appendf(bad_args, first ? "%s" : ", %s", arg_name); - first = FALSE; + first = false; } } } /* list good args */ - first = TRUE; + first = true; RNA_parameter_list_begin(&parms, &iter); for (; iter.valid; RNA_parameter_list_next(&iter)) { @@ -5149,7 +5153,7 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject continue; BLI_dynstr_appendf(good_args, first ? "%s" : ", %s", RNA_property_identifier(parm)); - first = FALSE; + first = false; } RNA_parameter_list_end(&iter); @@ -5179,7 +5183,7 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject BKE_reports_init(&reports, RPT_STORE); RNA_function_call(C, &reports, self_ptr, self_func, &parms); - err = (BPy_reports_to_error(&reports, PyExc_RuntimeError, TRUE)); + err = (BPy_reports_to_error(&reports, PyExc_RuntimeError, true)); /* return value */ if (err != -1) { @@ -5242,7 +5246,7 @@ static PyObject *pyrna_func_doc_get(BPy_FunctionRNA *self, void *UNUSED(closure) PyObject *ret; char *args; - args = RNA_function_as_string_keywords(NULL, self->func, NULL, TRUE, TRUE); + args = RNA_function_as_string_keywords(NULL, self->func, NULL, true, true); ret = PyUnicode_FromFormat("%.200s.%.200s(%.200s)\n%s", RNA_struct_identifier(self->ptr.type), @@ -5974,7 +5978,7 @@ static PyObject *pyrna_prop_collection_iter(BPy_PropertyRNA *self) static PyObject *pyrna_prop_collection_iter_next(BPy_PropertyCollectionIterRNA *self) { - if (self->iter.valid == FALSE) { + if (self->iter.valid == false) { PyErr_SetString(PyExc_StopIteration, "pyrna_prop_collection_iter stop"); return NULL; } @@ -6052,7 +6056,7 @@ static void pyrna_subtype_set_rna(PyObject *newclass, StructRNA *srna) FunctionRNA *func = (FunctionRNA *)link; const int flag = RNA_function_flag(func); if ((flag & FUNC_NO_SELF) && /* is staticmethod or classmethod */ - (flag & FUNC_REGISTER) == FALSE) /* is not for registration */ + (flag & FUNC_REGISTER) == false) /* is not for registration */ { /* we may want to set the type of this later */ PyObject *func_py = pyrna_func_to_py(&func_ptr, func); @@ -6262,7 +6266,7 @@ PyObject *pyrna_struct_CreatePyObject(PointerRNA *ptr) pyrna->ptr = *ptr; #ifdef PYRNA_FREE_SUPPORT - pyrna->freeptr = FALSE; + pyrna->freeptr = false; #endif #ifdef USE_PYRNA_STRUCT_REFERENCE @@ -6342,15 +6346,15 @@ PyObject *pyrna_id_CreatePyObject(ID *id) } } -int pyrna_id_FromPyObject(PyObject *obj, ID **id) +bool pyrna_id_FromPyObject(PyObject *obj, ID **id) { if (BPy_StructRNA_Check(obj) && (RNA_struct_is_ID(((BPy_StructRNA *)obj)->ptr.type))) { *id = ((BPy_StructRNA *)obj)->ptr.id.data; - return TRUE; + return true; } else { *id = NULL; - return FALSE; + return false; } } @@ -6561,7 +6565,7 @@ PyObject *BPY_rna_types(void) return (PyObject *)self; } -StructRNA *pyrna_struct_as_srna(PyObject *self, int parent, const char *error_prefix) +StructRNA *pyrna_struct_as_srna(PyObject *self, const bool parent, const char *error_prefix) { BPy_StructRNA *py_srna = NULL; StructRNA *srna; @@ -6635,7 +6639,7 @@ StructRNA *srna_from_self(PyObject *self, const char *error_prefix) PyErr_Fetch(&error_type, &error_value, &error_traceback); PyErr_Clear(); - srna = pyrna_struct_as_srna(self, 0, error_prefix); + srna = pyrna_struct_as_srna(self, false, error_prefix); if (!PyErr_Occurred()) { PyErr_Restore(error_type, error_value, error_traceback); @@ -7051,7 +7055,7 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param if (py_class->tp_init) { #ifdef USE_PEDANTIC_WRITE const int prev_write = rna_disallow_writes; - rna_disallow_writes = is_operator ? FALSE : TRUE; /* only operators can write on __init__ */ + rna_disallow_writes = is_operator ? false : true; /* only operators can write on __init__ */ #endif /* true in most cases even when the class its self doesn't define an __init__ function. */ @@ -7070,7 +7074,7 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param #else const int prev_write = rna_disallow_writes; - rna_disallow_writes = TRUE; + rna_disallow_writes = true; /* 'almost' all the time calling the class isn't needed. * We could just do... */ @@ -7146,7 +7150,7 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param } #ifdef USE_PEDANTIC_WRITE - rna_disallow_writes = is_readonly ? TRUE : FALSE; + rna_disallow_writes = is_readonly ? true : false; #endif /* *** Main Caller *** */ @@ -7155,7 +7159,7 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param /* *** Done Calling *** */ #ifdef USE_PEDANTIC_WRITE - rna_disallow_writes = FALSE; + rna_disallow_writes = false; #endif RNA_parameter_list_end(&iter); @@ -7420,7 +7424,7 @@ static PyObject *pyrna_register_class(PyObject *UNUSED(self), PyObject *py_class } /* warning: gets parent classes srna, only for the register function */ - srna = pyrna_struct_as_srna(py_class, 1, "register_class(...):"); + srna = pyrna_struct_as_srna(py_class, true, "register_class(...):"); if (srna == NULL) return NULL; @@ -7456,7 +7460,7 @@ static PyObject *pyrna_register_class(PyObject *UNUSED(self), PyObject *py_class srna_new = reg(CTX_data_main(C), &reports, py_class, identifier, bpy_class_validate, bpy_class_call, bpy_class_free); - if (BPy_reports_to_error(&reports, PyExc_RuntimeError, TRUE) == -1) + if (BPy_reports_to_error(&reports, PyExc_RuntimeError, true) == -1) return NULL; /* python errors validating are not converted into reports so the check above will fail. @@ -7563,7 +7567,7 @@ static PyObject *pyrna_unregister_class(PyObject *UNUSED(self), PyObject *py_cla return NULL; } - srna = pyrna_struct_as_srna(py_class, 0, "unregister_class(...):"); + srna = pyrna_struct_as_srna(py_class, false, "unregister_class(...):"); if (srna == NULL) return NULL; diff --git a/source/blender/python/intern/bpy_rna.h b/source/blender/python/intern/bpy_rna.h index edd2ada0539..424452ef6fe 100644 --- a/source/blender/python/intern/bpy_rna.h +++ b/source/blender/python/intern/bpy_rna.h @@ -115,7 +115,7 @@ typedef struct { #endif /* !USE_PYRNA_STRUCT_REFERENCE */ #ifdef PYRNA_FREE_SUPPORT - int freeptr; /* needed in some cases if ptr.data is created on the fly, free when deallocing */ + bool freeptr; /* needed in some cases if ptr.data is created on the fly, free when deallocing */ #endif /* PYRNA_FREE_SUPPORT */ } BPy_StructRNA; @@ -164,7 +164,7 @@ typedef struct { #define BPy_BaseTypeRNA BPy_PropertyRNA StructRNA *srna_from_self(PyObject *self, const char *error_prefix); -StructRNA *pyrna_struct_as_srna(PyObject *self, int parent, const char *error_prefix); +StructRNA *pyrna_struct_as_srna(PyObject *self, const bool parent, const char *error_prefix); void BPY_rna_init(void); PyObject *BPY_rna_module(void); @@ -178,7 +178,7 @@ PyObject *pyrna_prop_CreatePyObject(PointerRNA *ptr, PropertyRNA *prop); /* extern'd by other modules which don't deal closely with RNA */ PyObject *pyrna_id_CreatePyObject(struct ID *id); -int pyrna_id_FromPyObject(PyObject *obj, struct ID **id); +bool pyrna_id_FromPyObject(PyObject *obj, struct ID **id); /* operators also need this to set args */ int pyrna_pydict_to_props(PointerRNA *ptr, PyObject *kw, int all_args, const char *error_prefix); @@ -205,8 +205,8 @@ PyObject *pyrna_py_from_array_index(BPy_PropertyArrayRNA *self, PointerRNA *ptr, PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop); int pyrna_array_contains_py(PointerRNA *ptr, PropertyRNA *prop, PyObject *value); -int pyrna_write_check(void); -void pyrna_write_set(int val); +bool pyrna_write_check(void); +void pyrna_write_set(bool val); void pyrna_invalidate(BPy_DummyPointerRNA *self); int pyrna_struct_validity_check(BPy_StructRNA *pysrna); diff --git a/source/blender/python/intern/bpy_rna_anim.c b/source/blender/python/intern/bpy_rna_anim.c index 0acfc36bb4e..a19f8e2d8ed 100644 --- a/source/blender/python/intern/bpy_rna_anim.c +++ b/source/blender/python/intern/bpy_rna_anim.c @@ -160,14 +160,14 @@ static int pyrna_struct_keyframe_parse( return -1; } - if (pyrna_struct_anim_args_parse(ptr, error_prefix, path, path_full, index) < 0) + if (pyrna_struct_anim_args_parse(ptr, error_prefix, path, path_full, index) == -1) return -1; if (*cfra == FLT_MAX) *cfra = CTX_data_scene(BPy_GetContext())->r.cfra; /* flag may be null (no option currently for remove keyframes e.g.). */ - if (pyoptions && options && (pyrna_set_to_enum_bitfield(keying_flag_items, pyoptions, options, error_prefix) < 0)) + if (pyoptions && options && (pyrna_set_to_enum_bitfield(keying_flag_items, pyoptions, options, error_prefix) == -1)) return -1; return 0; /* success */ @@ -222,7 +222,7 @@ PyObject *pyrna_struct_keyframe_insert(BPy_StructRNA *self, PyObject *args, PyOb result = insert_keyframe(&reports, (ID *)self->ptr.id.data, NULL, group_name, path_full, index, cfra, options); MEM_freeN((void *)path_full); - if (BPy_reports_to_error(&reports, PyExc_RuntimeError, TRUE) == -1) + if (BPy_reports_to_error(&reports, PyExc_RuntimeError, true) == -1) return NULL; return PyBool_FromLong(result); @@ -271,7 +271,7 @@ PyObject *pyrna_struct_keyframe_delete(BPy_StructRNA *self, PyObject *args, PyOb result = delete_keyframe(&reports, (ID *)self->ptr.id.data, NULL, group_name, path_full, index, cfra, 0); MEM_freeN((void *)path_full); - if (BPy_reports_to_error(&reports, PyExc_RuntimeError, TRUE) == -1) + if (BPy_reports_to_error(&reports, PyExc_RuntimeError, true) == -1) return NULL; return PyBool_FromLong(result); @@ -301,7 +301,7 @@ PyObject *pyrna_struct_driver_add(BPy_StructRNA *self, PyObject *args) if (!PyArg_ParseTuple(args, "s|i:driver_add", &path, &index)) return NULL; - if (pyrna_struct_anim_args_parse(&self->ptr, "bpy_struct.driver_add():", path, &path_full, &index) < 0) { + if (pyrna_struct_anim_args_parse(&self->ptr, "bpy_struct.driver_add():", path, &path_full, &index) == -1) { return NULL; } else { @@ -313,7 +313,7 @@ PyObject *pyrna_struct_driver_add(BPy_StructRNA *self, PyObject *args) result = ANIM_add_driver(&reports, (ID *)self->ptr.id.data, path_full, index, 0, DRIVER_TYPE_PYTHON); - if (BPy_reports_to_error(&reports, PyExc_RuntimeError, TRUE) == -1) + if (BPy_reports_to_error(&reports, PyExc_RuntimeError, true) == -1) return NULL; if (result) { @@ -377,7 +377,7 @@ PyObject *pyrna_struct_driver_remove(BPy_StructRNA *self, PyObject *args) if (!PyArg_ParseTuple(args, "s|i:driver_remove", &path, &index)) return NULL; - if (pyrna_struct_anim_args_parse(&self->ptr, "bpy_struct.driver_remove():", path, &path_full, &index) < 0) { + if (pyrna_struct_anim_args_parse(&self->ptr, "bpy_struct.driver_remove():", path, &path_full, &index) == -1) { return NULL; } else { @@ -390,7 +390,7 @@ PyObject *pyrna_struct_driver_remove(BPy_StructRNA *self, PyObject *args) MEM_freeN((void *)path_full); - if (BPy_reports_to_error(&reports, PyExc_RuntimeError, TRUE) == -1) + if (BPy_reports_to_error(&reports, PyExc_RuntimeError, true) == -1) return NULL; WM_event_add_notifier(BPy_GetContext(), NC_ANIMATION | ND_FCURVES_ORDER, NULL); diff --git a/source/blender/python/intern/bpy_rna_callback.c b/source/blender/python/intern/bpy_rna_callback.c index adb4ae6a2c6..1043f68dbdb 100644 --- a/source/blender/python/intern/bpy_rna_callback.c +++ b/source/blender/python/intern/bpy_rna_callback.c @@ -32,12 +32,12 @@ #include "RNA_types.h" +#include "BLI_utildefines.h" + #include "bpy_rna.h" #include "bpy_rna_callback.h" #include "bpy_util.h" -#include "BLI_utildefines.h" - #include "DNA_space_types.h" #include "DNA_screen_types.h" @@ -101,7 +101,7 @@ PyObject *pyrna_callback_add(BPy_StructRNA *self, PyObject *args) if (RNA_struct_is_a(self->ptr.type, &RNA_Region)) { if (cb_event_str) { - if (pyrna_enum_value_from_id(region_draw_mode_items, cb_event_str, &cb_event, "bpy_struct.callback_add()") < 0) { + if (pyrna_enum_value_from_id(region_draw_mode_items, cb_event_str, &cb_event, "bpy_struct.callback_add()") == -1) { return NULL; } } @@ -194,7 +194,7 @@ PyObject *pyrna_callback_classmethod_add(PyObject *UNUSED(self), PyObject *args) } cls = PyTuple_GET_ITEM(args, 0); - if (!(srna = pyrna_struct_as_srna(cls, FALSE, "handler_add"))) { + if (!(srna = pyrna_struct_as_srna(cls, false, "handler_add"))) { return NULL; } cb_func = PyTuple_GET_ITEM(args, 1); @@ -212,10 +212,10 @@ PyObject *pyrna_callback_classmethod_add(PyObject *UNUSED(self), PyObject *args) return NULL; } - if (pyrna_enum_value_from_id(region_draw_mode_items, cb_event_str, &cb_event, "bpy_struct.callback_add()") < 0) { + if (pyrna_enum_value_from_id(region_draw_mode_items, cb_event_str, &cb_event, "bpy_struct.callback_add()") == -1) { return NULL; } - else if (pyrna_enum_value_from_id(region_type_items, cb_regiontype_str, &cb_regiontype, "bpy_struct.callback_add()") < 0) { + else if (pyrna_enum_value_from_id(region_type_items, cb_regiontype_str, &cb_regiontype, "bpy_struct.callback_add()") == -1) { return NULL; } else { @@ -257,7 +257,7 @@ PyObject *pyrna_callback_classmethod_remove(PyObject *UNUSED(self), PyObject *ar } cls = PyTuple_GET_ITEM(args, 0); - if (!(srna = pyrna_struct_as_srna(cls, FALSE, "callback_remove"))) { + if (!(srna = pyrna_struct_as_srna(cls, false, "callback_remove"))) { return NULL; } py_handle = PyTuple_GET_ITEM(args, 1); @@ -278,7 +278,7 @@ PyObject *pyrna_callback_classmethod_remove(PyObject *UNUSED(self), PyObject *ar customdata = ED_region_draw_cb_customdata(handle); Py_DECREF((PyObject *)customdata); - if (pyrna_enum_value_from_id(region_type_items, cb_regiontype_str, &cb_regiontype, "bpy_struct.callback_remove()") < 0) { + if (pyrna_enum_value_from_id(region_type_items, cb_regiontype_str, &cb_regiontype, "bpy_struct.callback_remove()") == -1) { return NULL; } else { diff --git a/source/blender/python/intern/bpy_util.c b/source/blender/python/intern/bpy_util.c index b7994eeccdc..b0b0f346944 100644 --- a/source/blender/python/intern/bpy_util.c +++ b/source/blender/python/intern/bpy_util.c @@ -29,9 +29,13 @@ #include <Python.h> -#include "bpy_util.h" +#include "BLI_utildefines.h" #include "BLI_dynstr.h" + +#include "bpy_util.h" + #include "MEM_guardedalloc.h" + #include "BKE_report.h" #include "BKE_context.h" @@ -59,13 +63,13 @@ char *BPy_enum_as_string(EnumPropertyItem *item) return cstring; } -short BPy_reports_to_error(ReportList *reports, PyObject *exception, const short clear) +short BPy_reports_to_error(ReportList *reports, PyObject *exception, const bool clear) { char *report_str; report_str = BKE_reports_string(reports, RPT_ERROR); - if (clear) { + if (clear == true) { BKE_reports_clear(reports); } diff --git a/source/blender/python/intern/bpy_util.h b/source/blender/python/intern/bpy_util.h index b5f679b741f..b007e123cfc 100644 --- a/source/blender/python/intern/bpy_util.h +++ b/source/blender/python/intern/bpy_util.h @@ -39,7 +39,7 @@ char *BPy_enum_as_string(struct EnumPropertyItem *item); #define BLANK_PYTHON_TYPE {PyVarObject_HEAD_INIT(NULL, 0) NULL} /* error reporting */ -short BPy_reports_to_error(struct ReportList *reports, PyObject *exception, const short clear); +short BPy_reports_to_error(struct ReportList *reports, PyObject *exception, const bool clear); short BPy_errors_to_report(struct ReportList *reports); /* TODO - find a better solution! */ |