Commit d5cb2382 authored by David Gobbi's avatar David Gobbi

Wrap constants more efficiently.

Sometimes header files contain a large number of constants, and
the wrappers were generating a function call for each and every
one in order to convert them into python values.  This new code
stores the constants in static data structures when possible.

Change-Id: Id59c8448be154647ff349b43d958871b0f18af69
parent a5948d9f
......@@ -692,20 +692,10 @@ int main(int argc, char *argv[])
}
/* add any enum types defined in the file */
for (j = 0; j < contents->NumberOfEnums; j++)
{
vtkWrapPython_AddEnumType(
fp, " ", "dict", "o", NULL, contents->Enums[j]);
fprintf(fp, "\n");
}
vtkWrapPython_AddPublicEnumTypes(fp, " ", "dict", "o", contents);
/* add any constants defined in the file */
for (j = 0; j < contents->NumberOfConstants; j++)
{
vtkWrapPython_AddConstant(fp, " ", "dict", "o", NULL,
contents->Constants[j]);
fprintf(fp, "\n");
}
vtkWrapPython_AddPublicConstants(fp, " ", "dict", "o", contents);
/* close the AddFile function */
fprintf(fp,
......
......@@ -423,26 +423,10 @@ static void vtkWrapPython_GenerateObjectNew(
"\n");
/* add any enum types defined in the class to its dict */
for (i = 0; i < data->NumberOfEnums; i++)
{
if (data->Enums[i]->Access == VTK_ACCESS_PUBLIC)
{
vtkWrapPython_AddEnumType(
fp, " ", "d", "o", data->Name, data->Enums[i]);
fprintf(fp, "\n");
}
}
vtkWrapPython_AddPublicEnumTypes(fp, " ", "d", "o", data);
/* add any constants defined in the class to its dict */
for (i = 0; i < data->NumberOfConstants; i++)
{
if (data->Constants[i]->Access == VTK_ACCESS_PUBLIC)
{
vtkWrapPython_AddConstant(
fp, " ", "d", "o", data->Name, data->Constants[i]);
fprintf(fp, "\n");
}
}
vtkWrapPython_AddPublicConstants(fp, " ", "d", "o", data);
fprintf(fp,
" }\n"
......
......@@ -14,6 +14,7 @@
=========================================================================*/
#include "vtkWrapPythonConstant.h"
#include "vtkWrap.h"
/* for VTK_TYPE_USE_LONG_LONG vs VTK_TYPE_USE___INT64 */
#include "vtkConfigure.h"
......@@ -23,22 +24,36 @@
#include <string.h>
#include <ctype.h>
/* -------------------------------------------------------------------- */
/* This method adds constants defined in the file to the module */
/* The scope, attrib, and valstring parameters are optional and can be
set to NULL.
void vtkWrapPython_AddConstant(
The "scope" is a namespace to use for enum constants, it is ignored
if null.
The "attrib" is the attribute to set in the dictionary, if null then
val->Name is used as the attribute name.
The "attribval" is the value to set the attribute to, if null then
val->Value is used.
*/
void vtkWrapPython_AddConstantHelper(
FILE *fp, const char *indent, const char *dictvar, const char *objvar,
const char *scope, ValueInfo *val)
const char *scope, const char *attrib, const char *attribval,
ValueInfo *val)
{
unsigned int valtype;
const char *valstring;
const char *valname;
const char *valstring;
int objcreated = 0;
valtype = (val->Type & VTK_PARSE_UNQUALIFIED_TYPE);
valstring = val->Value;
valname = val->Name;
valstring = attribval;
if (valstring == 0)
{
valstring = val->Value;
}
if (valtype == 0 && (valstring == NULL || valstring[0] == '\0'))
{
......@@ -63,7 +78,9 @@ void vtkWrapPython_AddConstant(
"%s%s = Py%s%s%s_FromEnum(%s%s%s);\n",
indent, objvar,
(scope ? scope : ""), (scope ? "_" : ""), val->Class,
(scope ? scope : ""), (scope ? "::" : ""), valname);
((scope && !attribval) ? scope : ""),
((scope && !attribval) ? "::" : ""),
(!attribval ? valname : attribval));
objcreated = 1;
}
else
......@@ -71,7 +88,9 @@ void vtkWrapPython_AddConstant(
fprintf(fp,
"%s%s = PyInt_FromLong(%s%s%s);\n",
indent, objvar,
(scope ? scope : ""), (scope ? "::" : ""), valname);
((scope && !attribval) ? scope : ""),
((scope && !attribval) ? "::" : ""),
(!attribval ? valname : attribval));
objcreated = 1;
}
}
......@@ -182,10 +201,175 @@ void vtkWrapPython_AddConstant(
fprintf(fp,
"%sif (%s)\n"
"%s {\n"
"%s PyDict_SetItemString(%s, (char *)\"%s\", %s);\n"
"%s PyDict_SetItemString(%s, (char *)%s%s%s, %s);\n"
"%s Py_DECREF(%s);\n"
"%s }\n",
indent, objvar, indent, indent, dictvar, val->Name, objvar,
indent, objvar, indent, indent, dictvar,
(attrib ? "" : "\""), (attrib ? attrib : valname),
(attrib ? "" : "\""), objvar,
indent, objvar, indent);
}
}
/* -------------------------------------------------------------------- */
/* Add all constants defined in the namespace to the module */
void vtkWrapPython_AddPublicConstants(
FILE *fp, const char *indent, const char *dictvar, const char *objvar,
NamespaceInfo *data)
{
const char *nextindent = " ";
ValueInfo *val;
ValueInfo *firstval;
const char *scope;
int scopeType, scopeValue;
unsigned int valtype;
const char *typeName;
const char *tname;
int j = 0;
int count, k, i;
size_t l, m;
/* get the next indent to use */
l = strlen(indent);
m = strlen(nextindent);
if (m > l + 2)
{
nextindent += m - l - 2;
}
/* get the name of the namespace, or NULL if global */
scope = data->Name;
if (scope && scope[0] == '\0')
{
scope = 0;
}
/* go through the constants, collecting them by type */
while (j < data->NumberOfConstants)
{
val = data->Constants[j];
if (val->Access != VTK_ACCESS_PUBLIC)
{
j++;
continue;
}
/* write a single constant if not numerical */
if (j+1 == data->NumberOfConstants ||
val->Type != data->Constants[j+1]->Type ||
!vtkWrap_IsScalar(val) ||
(!val->IsEnum && !vtkWrap_IsNumeric(val)))
{
vtkWrapPython_AddConstant(
fp, indent, dictvar, objvar, scope, val);
j++;
continue;
}
/* get important information about the value */
valtype = val->Type;
typeName = (val->IsEnum ? val->Class : vtkWrap_GetTypeName(val));
scopeType = (scope && val->IsEnum && strcmp(typeName, "int") != 0);
scopeValue = (scope && val->IsEnum);
/* count a series of constants of the same type */
firstval = val;
count = 0;
for (k = j; k < data->NumberOfConstants; k++)
{
val = data->Constants[k];
if (val->Access == VTK_ACCESS_PUBLIC)
{
tname = (val->IsEnum ? val->Class : vtkWrap_GetTypeName(val));
if (val->Type != valtype || strcmp(tname, typeName) != 0)
{
break;
}
count++;
}
}
/* if no constants to generate, then continue */
if (count == 0)
{
j = k;
continue;
}
/* check to make sure there won't be a name conflict between an
enum type and some other class member, it happens specifically
for vtkImplicitBoolean which has a variable and enum type both
with the name OperationType */
if (scopeType)
{
int conflict = 0;
for (i = 0; i < data->NumberOfVariables && !conflict; i++)
{
conflict = (strcmp(data->Variables[i]->Name, typeName) == 0);
}
if (conflict)
{
valtype = VTK_PARSE_INT;
typeName = "int";
scopeType = 0;
}
}
/* generate the code */
fprintf(fp,
"%sfor (int c = 0; c < %d; c++)\n"
"%s {\n",
indent, count, indent);
if (scopeType)
{
fprintf(fp,
"%s typedef %s::%s cxx_enum_type;\n\n",
indent, scope, typeName);
}
fprintf(fp,
"%s static const struct { const char *name; %s value; }\n"
"%s constants[%d] = {\n",
indent, (scopeType ? "cxx_enum_type" : typeName),
indent, count);
while (j < k)
{
val = data->Constants[j++];
if (val->Access == VTK_ACCESS_PUBLIC)
{
fprintf(fp,
"%s { \"%s\", %s%s%s },\n",
indent, val->Name,
(scopeValue ? scope : ""), (scopeValue ? "::" : ""),
(val->IsEnum ? val->Name : val->Value));
}
}
fprintf(fp,
"%s };\n"
"\n",
indent);
vtkWrapPython_AddConstantHelper(
fp, nextindent, dictvar, objvar, scope,
"constants[c].name", "constants[c].value", firstval);
fprintf(fp,
"%s }\n\n",
indent);
}
}
/* -------------------------------------------------------------------- */
/* This method adds one constant defined in the file to the module */
void vtkWrapPython_AddConstant(
FILE *fp, const char *indent, const char *dictvar, const char *objvar,
const char *scope, ValueInfo *val)
{
vtkWrapPython_AddConstantHelper(
fp, indent, dictvar, objvar, scope, NULL, NULL, val);
}
......@@ -25,4 +25,9 @@ void vtkWrapPython_AddConstant(
FILE *fp, const char *indent, const char *dictvar, const char *objvar,
const char *scope, ValueInfo *val);
/* generate code that adds all public constants in a namespace */
void vtkWrapPython_AddPublicConstants(
FILE *fp, const char *indent, const char *dictvar, const char *objvar,
NamespaceInfo *data);
#endif /* VTK_WRAP_PYTHON_CONSTANT_H */
......@@ -175,3 +175,21 @@ void vtkWrapPython_GenerateEnumType(
enumname,
enumname);
}
/* generate code that adds all public enum types to a python dict */
void vtkWrapPython_AddPublicEnumTypes(
FILE *fp, const char *indent, const char *dictvar, const char *objvar,
NamespaceInfo *data)
{
int i;
for (i = 0; i < data->NumberOfEnums; i++)
{
if (data->Enums[i]->Access == VTK_ACCESS_PUBLIC)
{
vtkWrapPython_AddEnumType(
fp, indent, dictvar, objvar, data->Name, data->Enums[i]);
fprintf(fp, "\n");
}
}
}
......@@ -33,4 +33,9 @@ void vtkWrapPython_AddEnumType(
FILE *fp, const char *indent, const char *dictvar, const char *objvar,
const char *scope, EnumInfo *cls);
/* generate code that adds all public enum types to a python dict */
void vtkWrapPython_AddPublicEnumTypes(
FILE *fp, const char *indent, const char *dictvar, const char *objvar,
NamespaceInfo *data);
#endif /* VTK_WRAP_PYTHON_ENUM_H */
......@@ -54,20 +54,10 @@ int vtkWrapPython_WrapNamespace(FILE *fp, NamespaceInfo *data)
"\n");
/* add any enum types defined in the namespace */
for (i = 0; i < data->NumberOfEnums; i++)
{
vtkWrapPython_AddEnumType(
fp, " ", "d", "o", data->Name, data->Enums[i]);
fprintf(fp, "\n");
}
vtkWrapPython_AddPublicEnumTypes(fp, " ", "d", "o", data);
/* add any constants defined in the namespace */
for (i = 0; i < data->NumberOfConstants; i++)
{
vtkWrapPython_AddConstant(
fp, " ", "d", "o", data->Name, data->Constants[i]);
fprintf(fp, "\n");
}
vtkWrapPython_AddPublicConstants(fp, " ", "d", "o", data);
}
fprintf(fp,
......
......@@ -888,26 +888,10 @@ void vtkWrapPython_GenerateSpecialType(
classname);
/* add any enum types defined in the class to its dict */
for (i = 0; i < data->NumberOfEnums; i++)
{
if (data->Enums[i]->Access == VTK_ACCESS_PUBLIC)
{
vtkWrapPython_AddEnumType(
fp, " ", "d", "o", data->Name, data->Enums[i]);
fprintf(fp, "\n");
}
}
vtkWrapPython_AddPublicEnumTypes(fp, " ", "d", "o", data);
/* add any constants defined in the class to its dict */
for (i = 0; i < data->NumberOfConstants; i++)
{
if (data->Constants[i]->Access == VTK_ACCESS_PUBLIC)
{
vtkWrapPython_AddConstant(
fp, " ", "d", "o", data->Name, data->Constants[i]);
fprintf(fp, "\n");
}
}
vtkWrapPython_AddPublicConstants(fp, " ", "d", "o", data);
}
fprintf(fp,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment