diff options
author | Campbell Barton <ideasman42@gmail.com> | 2011-07-14 03:24:21 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2011-07-14 03:24:21 +0400 |
commit | aef6f15b49bd30f142d9635151c993e155c36401 (patch) | |
tree | 200eef4009e9081d52a517ce67bd2675e670097f /source/blender/python/generic/bgl.c | |
parent | 609933208dba8ac78dff85294d83d495a8ae45d4 (diff) |
minor changes to bgl.Buffer py class
- use getset rather then getattr
- remove verbose Buffer docstring, better use sphinx docs for this
- replace bge.Buffer with the Buffer class and add a __new__ function to the class so it can be called.
- improve error messages
Diffstat (limited to 'source/blender/python/generic/bgl.c')
-rw-r--r-- | source/blender/python/generic/bgl.c | 271 |
1 files changed, 155 insertions, 116 deletions
diff --git a/source/blender/python/generic/bgl.c b/source/blender/python/generic/bgl.c index b5a693c397c..7d939a46021 100644 --- a/source/blender/python/generic/bgl.c +++ b/source/blender/python/generic/bgl.c @@ -44,25 +44,7 @@ #include "BLI_utildefines.h" - -PyDoc_STRVAR(Method_Buffer_doc, - "(type, dimensions, [template]) - Create a new Buffer object\n\n\ -(type) - The format to store data in\n\ -(dimensions) - An int or sequence specifying the dimensions of the buffer\n\ -[template] - A sequence of matching dimensions to the buffer to be created\n\ - which will be used to initialize the Buffer.\n\n\ -If a template is not passed in all fields will be initialized to 0.\n\n\ -The type should be one of GL_BYTE, GL_SHORT, GL_INT, GL_FLOAT, or GL_DOUBLE.\n\ -If the dimensions are specified as an int a linear buffer will be\n\ -created. If a sequence is passed for the dimensions the buffer\n\ -will have len(sequence) dimensions, where the size for each dimension\n\ -is determined by the value in the sequence at that index.\n\n\ -For example, passing [100, 100] will create a 2 dimensional\n\ -square buffer. Passing [16, 16, 32] will create a 3 dimensional\n\ -buffer which is twice as deep as it is wide or high." -); - -static PyObject *Method_Buffer(PyObject *self, PyObject *args); +static PyObject *Buffer_new(PyTypeObject *type, PyObject *args, PyObject *kwds); /* Buffer sequence methods */ @@ -71,42 +53,98 @@ static PyObject *Buffer_item(PyObject *self, int i); static PyObject *Buffer_slice(PyObject *self, int begin, int end); static int Buffer_ass_item(PyObject *self, int i, PyObject *v); static int Buffer_ass_slice(PyObject *self, int begin, int end, - PyObject *seq); + PyObject *seq); static PySequenceMethods Buffer_SeqMethods = { - ( lenfunc ) Buffer_len, /*sq_length */ - ( binaryfunc ) NULL, /*sq_concat */ - ( ssizeargfunc ) NULL, /*sq_repeat */ - ( ssizeargfunc ) Buffer_item, /*sq_item */ - ( ssizessizeargfunc ) Buffer_slice, /*sq_slice, deprecated TODO, replace */ - ( ssizeobjargproc ) Buffer_ass_item, /*sq_ass_item */ - ( ssizessizeobjargproc ) Buffer_ass_slice, /*sq_ass_slice, deprecated TODO, replace */ + (lenfunc) Buffer_len, /*sq_length */ + (binaryfunc) NULL, /*sq_concat */ + (ssizeargfunc) NULL, /*sq_repeat */ + (ssizeargfunc) Buffer_item, /*sq_item */ + (ssizessizeargfunc) Buffer_slice, /*sq_slice, deprecated TODO, replace */ + (ssizeobjargproc) Buffer_ass_item, /*sq_ass_item */ + (ssizessizeobjargproc) Buffer_ass_slice, /*sq_ass_slice, deprecated TODO, replace */ (objobjproc) NULL, /* sq_contains */ (binaryfunc) NULL, /* sq_inplace_concat */ (ssizeargfunc) NULL, /* sq_inplace_repeat */ }; static void Buffer_dealloc(PyObject *self); -static PyObject *Buffer_tolist(PyObject *self); -static PyObject *Buffer_dimensions(PyObject *self); -static PyObject *Buffer_getattr(PyObject *self, char *name); +static PyObject *Buffer_tolist(PyObject *self, void *arg); +static PyObject *Buffer_dimensions(PyObject *self, void *arg); static PyObject *Buffer_repr(PyObject *self); +static PyGetSetDef Buffer_getseters[]; PyTypeObject BGL_bufferType = { PyVarObject_HEAD_INIT(NULL, 0) - "buffer", /*tp_name */ - sizeof( Buffer ), /*tp_basicsize */ - 0, /*tp_itemsize */ - ( destructor ) Buffer_dealloc, /*tp_dealloc */ - ( printfunc ) 0, /*tp_print */ - ( getattrfunc ) Buffer_getattr, /*tp_getattr */ - ( setattrfunc ) 0, /*tp_setattr */ + "bgl.Buffer", /*tp_name */ + sizeof(Buffer), /*tp_basicsize */ + 0, /*tp_itemsize */ + (destructor)Buffer_dealloc, /*tp_dealloc */ + (printfunc)NULL, /*tp_print */ + NULL, /*tp_getattr */ + NULL, /*tp_setattr */ NULL, /*tp_compare */ - ( reprfunc ) Buffer_repr, /*tp_repr */ + (reprfunc) Buffer_repr, /*tp_repr */ NULL, /*tp_as_number */ &Buffer_SeqMethods, /*tp_as_sequence */ + NULL, /* PyMappingMethods *tp_as_mapping; */ + + /* More standard operations (here for binary compatibility) */ + + NULL, /* hashfunc tp_hash; */ + NULL, /* ternaryfunc tp_call; */ + NULL, /* reprfunc tp_str; */ + NULL, /* getattrofunc tp_getattro; */ + NULL, /* setattrofunc tp_setattro; */ + + /* Functions to access object as input/output buffer */ + NULL, /* PyBufferProcs *tp_as_buffer; */ + + /*** Flags to define presence of optional/expanded features ***/ + Py_TPFLAGS_DEFAULT, /* long tp_flags; */ + + NULL, /* char *tp_doc; Documentation string */ + /*** Assigned meaning in release 2.0 ***/ + /* call function for all accessible objects */ + NULL, /* traverseproc tp_traverse; */ + + /* delete references to contained objects */ + NULL, /* inquiry tp_clear; */ + + /*** Assigned meaning in release 2.1 ***/ + /*** rich comparisons ***/ + NULL, /* richcmpfunc tp_richcompare; */ + + /*** weak reference enabler ***/ + 0, /* long tp_weaklistoffset; */ + + /*** Added in release 2.2 ***/ + /* Iterators */ + NULL, /* getiterfunc tp_iter; */ + NULL, /* iternextfunc tp_iternext; */ + /*** Attribute descriptor and subclassing stuff ***/ + NULL, /* struct PyMethodDef *tp_methods; */ + NULL, /* struct PyMemberDef *tp_members; */ + Buffer_getseters, /* struct PyGetSetDef *tp_getset; */ + NULL, /*tp_base*/ + NULL, /*tp_dict*/ + NULL, /*tp_descr_get*/ + NULL, /*tp_descr_set*/ + 0, /*tp_dictoffset*/ + NULL, /*tp_init*/ + NULL, /*tp_alloc*/ + Buffer_new, /*tp_new*/ + NULL, /*tp_free*/ + NULL, /*tp_is_gc*/ + NULL, /*tp_bases*/ + NULL, /*tp_mro*/ + NULL, /*tp_cache*/ + NULL, /*tp_subclasses*/ + NULL, /*tp_weaklist*/ + NULL /*tp_del*/ }; + /* #ifndef __APPLE__ */ #define BGL_Wrap(nargs, funcname, ret, arg_list) \ @@ -174,26 +212,13 @@ Buffer *BGL_MakeBuffer(int type, int ndimensions, int *dimensions, void *initbuf } else { memset(buffer->buf.asvoid, 0, length*size); - /* - for (i= 0; i<length; i++) { - if (type==GL_BYTE) - buffer->buf.asbyte[i]= 0; - else if (type==GL_SHORT) - buffer->buf.asshort[i]= 0; - else if (type==GL_INT) - buffer->buf.asint[i]= 0; - else if (type==GL_FLOAT) - buffer->buf.asfloat[i]= 0.0f; - else if (type==GL_DOUBLE) - buffer->buf.asdouble[i]= 0.0; - } - */ } return buffer; } + #define MAX_DIMENSIONS 256 -static PyObject *Method_Buffer (PyObject *UNUSED(self), PyObject *args) +static PyObject *Buffer_new(PyTypeObject *UNUSED(type), PyObject *args, PyObject *kwds) { PyObject *length_ob= NULL, *init= NULL; Buffer *buffer; @@ -201,31 +226,40 @@ static PyObject *Method_Buffer (PyObject *UNUSED(self), PyObject *args) int i, type; int ndimensions = 0; - - if (!PyArg_ParseTuple(args, "iO|O", &type, &length_ob, &init)) { - PyErr_SetString(PyExc_AttributeError, "expected an int and one or two PyObjects"); + + if(kwds && PyDict_Size(kwds)) { + PyErr_SetString(PyExc_TypeError, "bgl.Buffer(): takes no keyword args"); + return NULL; + } + + if (!PyArg_ParseTuple(args, "iO|O: bgl.Buffer", &type, &length_ob, &init)) { return NULL; } if (!ELEM5(type, GL_BYTE, GL_SHORT, GL_INT, GL_FLOAT, GL_DOUBLE)) { - PyErr_SetString(PyExc_AttributeError, "invalid first argument type, should be one of GL_BYTE, GL_SHORT, GL_INT, GL_FLOAT or GL_DOUBLE"); + PyErr_SetString(PyExc_AttributeError, + "invalid first argument type, should be one of " + "GL_BYTE, GL_SHORT, GL_INT, GL_FLOAT or GL_DOUBLE"); return NULL; } if (PyLong_Check(length_ob)) { ndimensions= 1; if(((dimensions[0]= PyLong_AsLong(length_ob)) < 1)) { - PyErr_SetString(PyExc_AttributeError, "dimensions must be between 1 and "STRINGIFY(MAX_DIMENSIONS)); + PyErr_SetString(PyExc_AttributeError, + "dimensions must be between 1 and "STRINGIFY(MAX_DIMENSIONS)); return NULL; } } else if (PySequence_Check(length_ob)) { ndimensions= PySequence_Size(length_ob); if (ndimensions > MAX_DIMENSIONS) { - PyErr_SetString(PyExc_AttributeError, "too many dimensions, max is "STRINGIFY(MAX_DIMENSIONS)); + PyErr_SetString(PyExc_AttributeError, + "too many dimensions, max is "STRINGIFY(MAX_DIMENSIONS)); return NULL; } else if (ndimensions < 1) { - PyErr_SetString(PyExc_AttributeError, "sequence must have at least one dimension"); + PyErr_SetString(PyExc_AttributeError, + "sequence must have at least one dimension"); return NULL; } for (i=0; i<ndimensions; i++) { @@ -236,13 +270,16 @@ static PyObject *Method_Buffer (PyObject *UNUSED(self), PyObject *args) Py_DECREF(ob); if(dimensions[i] < 1) { - PyErr_SetString(PyExc_AttributeError, "dimensions must be between 1 and "STRINGIFY(MAX_DIMENSIONS)); + PyErr_SetString(PyExc_AttributeError, + "dimensions must be between 1 and "STRINGIFY(MAX_DIMENSIONS)); return NULL; } } } else { - PyErr_Format(PyExc_TypeError, "invalid second argument argument expected a sequence or an int, not a %.200s", Py_TYPE(length_ob)->tp_name); + PyErr_Format(PyExc_TypeError, + "invalid second argument argument expected a sequence " + "or an int, not a %.200s", Py_TYPE(length_ob)->tp_name); return NULL; } @@ -336,42 +373,38 @@ static int Buffer_ass_item(PyObject *self, int i, PyObject *v) Buffer *buf= (Buffer *) self; if (i >= buf->dimensions[0]) { - PyErr_SetString(PyExc_IndexError, "array assignment index out of range"); + PyErr_SetString(PyExc_IndexError, + "array assignment index out of range"); return -1; } - + if (buf->ndimensions!=1) { PyObject *row= Buffer_item(self, i); - int ret; - - if (!row) return -1; - ret= Buffer_ass_slice(row, 0, buf->dimensions[1], v); - Py_DECREF(row); - return ret; - } - if (buf->type==GL_BYTE) { - if (!PyArg_Parse(v, "b:Coordinates must be ints", &buf->buf.asbyte[i])) - return -1; - } - else if (buf->type==GL_SHORT) { - if (!PyArg_Parse(v, "h:Coordinates must be ints", &buf->buf.asshort[i])) - return -1; - - } - else if (buf->type==GL_INT) { - if (!PyArg_Parse(v, "i:Coordinates must be ints", &buf->buf.asint[i])) - return -1; - } - else if (buf->type==GL_FLOAT) { - if (!PyArg_Parse(v, "f:Coordinates must be floats", &buf->buf.asfloat[i])) + if (row) { + int ret= Buffer_ass_slice(row, 0, buf->dimensions[1], v); + Py_DECREF(row); + return ret; + } + else { return -1; + } } - else if (buf->type==GL_DOUBLE) { - if (!PyArg_Parse(v, "d:Coordinates must be floats", &buf->buf.asdouble[i])) - return -1; + + switch(buf->type) { + case GL_BYTE: + return PyArg_Parse(v, "b:Expected ints", &buf->buf.asbyte[i]) ? 0:-1; + case GL_SHORT: + return PyArg_Parse(v, "h:Expected ints", &buf->buf.asshort[i]) ? 0:-1; + case GL_INT: + return PyArg_Parse(v, "i:Expected ints", &buf->buf.asint[i]) ? 0:-1; + case GL_FLOAT: + return PyArg_Parse(v, "f:Expected floats", &buf->buf.asfloat[i]) ? 0:-1; + case GL_DOUBLE: + return PyArg_Parse(v, "d:Expected floats", &buf->buf.asdouble[i]) ? 0:-1; + default: + return 0; /* should never happen */ } - return 0; } static int Buffer_ass_slice(PyObject *self, int begin, int end, PyObject *seq) @@ -385,23 +418,30 @@ static int Buffer_ass_slice(PyObject *self, int begin, int end, PyObject *seq) if (begin>end) begin= end; if (!PySequence_Check(seq)) { - PyErr_SetString(PyExc_TypeError, - "illegal argument type for built-in operation"); + PyErr_Format(PyExc_TypeError, + "buffer[:] = value, invalid assignment. " + "Expected a sequence, not an %.200s type", + Py_TYPE(seq)->tp_name); return -1; } - if (PySequence_Size(seq)!=(end-begin)) { - int seq_len = PySequence_Size(seq); - char err_str[128]; - sprintf(err_str, "size mismatch in assignment. Expected size: %d (size provided: %d)", seq_len, (end-begin)); - PyErr_SetString(PyExc_TypeError, err_str); + /* re-use count var */ + if ((count= PySequence_Size(seq)) != (end - begin)) { + PyErr_Format(PyExc_TypeError, + "buffer[:] = value, size mismatch in assignment. " + "Expected: %d (given: %d)", count, end - begin); return -1; } - for (count= begin; count<end; count++) { - item= PySequence_GetItem(seq, count-begin); - err= Buffer_ass_item(self, count, item); - Py_DECREF(item); + for (count= begin; count < end; count++) { + item= PySequence_GetItem(seq, count - begin); + if(item) { + err= Buffer_ass_item(self, count, item); + Py_DECREF(item); + } + else { + err= -1; + } if (err) break; } return err; @@ -411,15 +451,15 @@ static void Buffer_dealloc(PyObject *self) { Buffer *buf = (Buffer *)self; - if (buf->parent) Py_DECREF (buf->parent); + if (buf->parent) Py_DECREF(buf->parent); else MEM_freeN (buf->buf.asvoid); MEM_freeN (buf->dimensions); - PyObject_DEL (self); + PyObject_DEL(self); } -static PyObject *Buffer_tolist(PyObject *self) +static PyObject *Buffer_tolist(PyObject *self, void *UNUSED(arg)) { int i, len= ((Buffer *)self)->dimensions[0]; PyObject *list= PyList_New(len); @@ -431,7 +471,7 @@ static PyObject *Buffer_tolist(PyObject *self) return list; } -static PyObject *Buffer_dimensions(PyObject *self) +static PyObject *Buffer_dimensions(PyObject *self, void *UNUSED(arg)) { Buffer *buffer= (Buffer *) self; PyObject *list= PyList_New(buffer->ndimensions); @@ -444,18 +484,15 @@ static PyObject *Buffer_dimensions(PyObject *self) return list; } -static PyObject *Buffer_getattr(PyObject *self, char *name) -{ - if (strcmp(name, "list")==0) return Buffer_tolist(self); - else if (strcmp(name, "dimensions")==0) return Buffer_dimensions(self); - - PyErr_SetString(PyExc_AttributeError, name); - return NULL; -} +static PyGetSetDef Buffer_getseters[] = { + {(char *)"list", (getter)Buffer_tolist, NULL, NULL, NULL}, + {(char *)"dimensions", (getter)Buffer_dimensions, NULL, NULL, NULL}, + {NULL, NULL, NULL, NULL, NULL} +}; static PyObject *Buffer_repr(PyObject *self) { - PyObject *list= Buffer_tolist(self); + PyObject *list= Buffer_tolist(self, NULL); PyObject *repr= PyObject_Repr(list); Py_DECREF(list); @@ -805,7 +842,6 @@ BGLU_Wrap(9, UnProject, GLint, (GLdouble, GLdouble, GLdouble, GLdoubleP, GLdo * {"glAccum", Method_Accumfunc, METH_VARARGS} */ static struct PyMethodDef BGL_methods[] = { - {"Buffer", Method_Buffer, METH_VARARGS, Method_Buffer_doc}, /* #ifndef __APPLE__ */ MethodDef(Accum), @@ -1153,9 +1189,12 @@ PyObject *BPyInit_bgl(void) submodule= PyModule_Create(&BGL_module_def); dict= PyModule_GetDict(submodule); - if( PyType_Ready( &BGL_bufferType) < 0) + if(PyType_Ready(&BGL_bufferType) < 0) return NULL; /* should never happen */ + + PyModule_AddObject(submodule, "Buffer", (PyObject *)&BGL_bufferType); + #define EXPP_ADDCONST(x) PyDict_SetItemString(dict, #x, item=PyLong_FromLong((int)x)); Py_DECREF(item) /* So, for example: |