Move the Point2D_helpers code into a template function so it can be used for other types too.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxPython/Phoenix/trunk@69535 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Robin Dunn
2011-10-26 04:48:04 +00:00
parent f2864fdc05
commit e26a3ebaee
3 changed files with 76 additions and 59 deletions

View File

@@ -32,8 +32,6 @@ ITEMS = [
'wxGraphicsRenderer',
]
OTHERDEPS = [ 'src/Point2D_helpers.cpp']
#---------------------------------------------------------------------------
def run():
@@ -95,7 +93,7 @@ def run():
m.find('descent').out = True
m.find('externalLeading').out = True
m2 = c.addCppMethod('PyObject*', 'GetTextExtent', '(const wxString& text)',
c.addCppMethod('PyObject*', 'GetTextExtent', '(const wxString& text)',
pyArgsString="(text) -> (width, height)",
doc="Gets the dimensions of the string using the currently selected font.",
body="""\
@@ -103,13 +101,12 @@ def run():
self->GetTextExtent(*text, &width, &height, NULL, NULL);
return sipBuildResult(0, "(dd)", width, height);
""")
c.items.remove(m2)
c.insertItemAfter(m, m2)
c.addPyCode("GraphicsContext.DrawRotatedText = wx.deprecated(GraphicsContext.DrawText)")
c.includeCppCode('src/Point2D_helpers.cpp')
c.addCppCode(tools.ObjArrayHelperTemplate('wxPoint2D', 'sipType_wxPoint2DDouble',
"Expected a sequence of length-2 sequences or wx.Point2D objects."))
# we'll reimplement this overload as StrokeLineSegments
c.find('StrokeLines').findOverload('beginPoints').ignore()

View File

@@ -760,4 +760,77 @@ del _{ArrayClass_pyName}___repr__
'''.format(**locals()))
def ObjArrayHelperTemplate(objType, sipType, errmsg):
"""
Generates a helper function that can convert from a Python sequence of
objects (or items that can be converted to the target type) into a C
array of values. Copies are made of the items so the object types should
support implicit or explicit copies and the copy should be cheap.
This kind of helper is useful for situations where the C/C++ API takes a
simple pointer and a count, and there is no higher level container object
(like a wxList or wxArray) being used. If there is an overloaded method
that uses one of those types then the array overload should just be
ignored. But for those cases where the array is the only option then this
helper can be used to make the array.
"""
cppCode = """\
// Convert a Python sequence of {objType} objects, or items that can be converted
// to {objType} into a C array of {objType} instances.
static
{objType}* {objType}_array_helper(PyObject* source, size_t *count)
{{
{objType}* array;
Py_ssize_t idx, len;
// ensure that it is a sequence
if (! PySequence_Check(source))
goto error0;
// ensure it is not a string or unicode object (they are sequences too)
else if (PyString_Check(source) || PyUnicode_Check(source))
goto error0;
// ensure each item can be converted to {objType}
else {{
len = PySequence_Length(source);
for (idx=0; idx<len; idx++) {{
PyObject* item = PySequence_ITEM(source, idx);
if (!sipCanConvertToType(item, {sipType}, SIP_NOT_NONE)) {{
Py_DECREF(item);
goto error0;
}}
Py_DECREF(item);
}}
}}
// The length of the sequence is returned in count.
*count = len;
array = new {objType}[*count];
if (!array) {{
PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
return NULL;
}}
for (idx=0; idx<len; idx++) {{
PyObject* obj = PySequence_ITEM(source, idx);
int state = 0;
int err = 0;
{objType}* item = reinterpret_cast<{objType}*>(
sipConvertToType(obj, {sipType}, NULL, 0, &state, &err));
array[idx] = *item;
sipReleaseType((void*)item, {sipType}, state); // delete temporary instances
Py_DECREF(obj);
}}
return array;
error0:
PyErr_SetString(PyExc_TypeError, "{errmsg}");
return NULL;
}}
""".format(**locals())
return cppCode
#---------------------------------------------------------------------------

View File

@@ -1,53 +0,0 @@
#define sipType_wxPoint2D sipType_wxPoint2DDouble
// Convert a Python sequence of 2-tuples of numbers or wx.Point2D objects into a
// C array of wxPoint2D instances
static
wxPoint2D* wxPoint2D_array_helper(PyObject* source, size_t *count)
{
wxPoint2D* array;
Py_ssize_t idx, len;
// ensure that it is a sequence
if (! PySequence_Check(source))
goto error0;
// ensure it is not a string or unicode object (they are sequences too)
else if (PyString_Check(source) || PyUnicode_Check(source))
goto error0;
// ensure each item can be converted to wxPoint2D
else {
len = PySequence_Length(source);
for (idx=0; idx<len; idx++) {
PyObject* item = PySequence_ITEM(source, idx);
if (!sipCanConvertToType(item, sipType_wxPoint2D, SIP_NOT_NONE)) {
Py_DECREF(item);
goto error0;
}
Py_DECREF(item);
}
}
// The length of the sequence is returned in count.
*count = len;
array = new wxPoint2D[*count];
if (!array) {
PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
return NULL;
}
for (idx=0; idx<len; idx++) {
PyObject* obj = PySequence_ITEM(source, idx);
int state = 0;
int err = 0;
wxPoint2D* item = reinterpret_cast<wxPoint2D*>(
sipConvertToType(obj, sipType_wxPoint2D, NULL, 0, &state, &err));
array[idx] = *item;
sipReleaseType((void*)item, sipType_wxPoint2D, state); // delete temporary instances
Py_DECREF(obj);
}
return array;
error0:
PyErr_SetString(PyExc_TypeError, "Expected a sequence of length-2 sequences or wxPoint2D objects.");
return NULL;
}