From: Hazen B. <hba...@ma...> - 2009-10-09 00:10:19
|
Arjen Markus wrote: > On 2009-08-05 23:04, Hezekiah M. Carty wrote: >> On Wed, Aug 5, 2009 at 4:22 PM, Hazen Babcock<hba...@ma...> wrote: > >>> I like this idea/approach. Is there a reason not to reduce it even further? >>> >>> plget(const char *, void *) >>> plset(const char *, void *) >>> >>> It seems that either way the user would have to call the function as >>> intended to avoid memory corruption. >>> >>> Any objections to my implementing this & attempting to make it fairly >>> comprehensively cover most of what can gotten and set in PLplot core? >>> Likely the bulk of the work would be done post 5.10. >> While I like the API simplification this could provide, I have two >> primary concerns: >> >> First, could the first argument - the field to get/set - be an >> enumerated type of some sort? This should help catch typos at compile >> time rather than run time. (PL_LINE_WIDTH rather than "line width"). >> Additional fields would then require adding elements to the >> enumeration which, as I understand, should not break existing code. >> >> Second, the void* approach may not translate well to other languages. >> I'm not sure if there is a way to do this in C that would translate >> well to the other PLplot-supported languages though. >> > > I agree that a void * argument would be very bad for most languages, > if not all, and it leaves the interpretation of the value up to the > programmer. What about filling a structure instead? > > Something like: > > type struct _plAttribute { > PLINT attributeType; /* enumerated: integer, float, boolean, ... */ > PLINT intValue; /* value reserved for attributes that can be > represented as integers - at least in C */ > PLFLT floatValue; /* ditto: floating point attributes */ > char *stringValue; /* ditto: character string attributes */ > } plAttribute; > > void plget( char *attribute, plAttribute *attValue ); > void plset( char *attribute, plAttribute *attValue ); > > The various language bindings could then easily distinguish the > proper type of the attribute (overloading the functions) or > fill a similar structure and pass that. > > In C you could use the idiom: > > plget( "myattribute", &attValue ); > if ( attValue.attributeType == PL_ATT_INT ) { > attValue.intValue = newValue; > plset( "myattribute, &attValue ); > } I've made a first passing at implementing this in v10518. Below is a simple C program that demonstrates how to use what I have done so far. Suggestions? If everyone is more or less happy with this then I will flesh it out more in the future. Changes: (1) Added two functions to the api, plget & plset. (2) Added some enums & a new struct to plplot.h (3) Added a new file src/plgset.c -Hazen /* * Demo of the PLplot plget & plset functions. * * Hazen 10/09 */ #include <math.h> #include <string.h> #include <ctype.h> #include "plplot/plplot.h" static PLFLT px[] = {0.1, 0.9, 0.9, 0.1, 0.1}; static PLFLT py[] = {0.1, 0.1, 0.9, 0.9, 0.1}; int main(int argc, const char *argv[]) { int i,j; PLAttribute *pen_attr; PLAttribute *col_attr; pen_attr = (PLAttribute *)malloc(sizeof(PLAttribute)); col_attr = (PLAttribute *)malloc(sizeof(PLAttribute)); plsdev("xcairo"); plinit(); pladv(0); plvpor(0.0, 1.0, 0.0, 1.0); plwind(0.0, 1.0, 0.0, 1.0); /* draw smaller & smaller rectangle w/ increasing width & changing color */ for(i=0;i<10;i++){ plget(PL_PENWIDTH, pen_attr); plget(PL_CURCOLOR, col_attr); printf("%d)\n",i); printf(" Pen width: %d\n", pen_attr->intValue); printf(" Pen color: %3d, %3d, %3d\n\n", col_attr->colorValue.r, col_attr->colorValue.g, col_attr->colorValue.b); plline(5, px, py); pen_attr->intValue++; col_attr->colorValue.r -= 25; col_attr->colorValue.b += 25; plset(PL_PENWIDTH, *pen_attr); plset(PL_CURCOLOR, *col_attr); for(j=0;j<5;j++){ if (px[j] < 0.5){ px[j] += 0.02; } else { px[j] -= 0.02; } if (py[j] < 0.5){ py[j] += 0.02; } else { py[j] -= 0.02; } } } plend(); free(pen_attr); free(col_attr); } |