Switching DoMagic



  • Having more then a few functions as an interface is a real hell. Atleast, I guess that's what the 'master' of the system we maintain here must have been thinking.

    And thus, we have these types of functions:

    extern int    THING_put_prop(void *id, int select, int32 value);
    extern int32  THING_get_prop(void *id, int select, int pos);

    With defines like this:

    #define THING_P_TYPE            0
    #define THING_P_FLAGS           1
    #define THING_P_UIC             2
    #define THING_P_LOG             3
    #define THING_P_NREL            4
    #define THING_PT_MAXSIZE        5
    #define THING_PV_MIN            6
    #define THING_PV_MAX            7
    #define THING_PV_RES            8

    Ofcourse, those defines go into the select parameter.

    Now, ofcourse, the function implementation looks like this:

    int
    THING_put_prop(void *id, int select, int32 value)
    {
      THING       *p;
      int         ival = (int)value;

      p = id;
      TAG_TEST_RETURN_ARG(p, THING_TAG, FALSE);

      switch (select)
      {
      case THING_P_LOG:
          p->logmask = ival;
          return (TRUE);

      case THING_P_UIC:
          p->uicmask = ival;
          return (TRUE);

      case THING_P_NREL:
          if ((Uint)ival > (Uint)p->max_nrel)
              return (FALSE);
          p->nrel = ival;
          return (TRUE);

      case THING_PV_MIN:
          THING_COMP_TYPE_RETURN(p, THING_TYPE_V, FALSE);
          PV_DATA(p)->min_value = value;
          return (TRUE);

      case THING_PV_MAX:
          THING_COMP_TYPE_RETURN(p, THING_TYPE_V, FALSE);
          PV_DATA(p)->max_value = value;
          return (TRUE);

      default:
          break;
      }

      return (FALSE);
    }

    But ofcourse, calling the function every time with the right define is not that handy. And thus we have these macros:

    #define THING_change_logmask(id, mask)  THING_put_prop(id, THING_P_LOG, mask)
    #define THING_change_uicmask(id, mask)  THING_put_prop(id, THING_P_UIC, mask)
    #define THING_change_nrel(id, nrel)     THING_put_prop(id, THING_P_NREL, (int32)(nrel))
    #define THING_change_min(id, min)      THING_put_prop(id, THING_PV_MIN, min)
    #define THING_change_max(id, max)      THING_put_prop(id, THING_PV_MAX, max)

    #define THING_type(id)                  ((int)THING_get_prop(id, THING_P_TYPE, 0))
    #define THING_nrel(id)                  ((int)THING_get_prop(id, THING_P_NREL, 0))
    #define THING_max_nrel(id)              ((int)THING_get_prop(id, THING_P_MAX_NREL, 0))
    #define THING_uic(id)                   ((int)THING_get_prop(id, THING_P_UIC, 0))
    #define THING_log(id)                   ((int)THING_get_prop(id, THING_P_LOG, 0))
    #define THING_flags(id)                 ((int)THING_get_prop(id, THING_P_FLAGS, 0))
    #define THING_modify(id)                ((int)THING_get_prop(id, THING_P_MODIFY, 0))

     
    Thing is a find/replace, actualy name in the code is different, and I cut down the switch.

    The code is pretty full of gems like this. Not to mention some stuff has dutch variables/defines, and the logbook module is actualy called "tagebuch", which is a bit confusing when you have a log module and a logline module.



  • @Daid said:

    Having more then a few functions as an interface is a real hell. Atleast, I guess that's what the 'master' of the system we maintain here must have been thinking.

    OpenGL anyone?

    glGet :

    void glGetBooleanv(GLenum pname, GLboolean *params);
    void glGetDoublev(GLenum pname, GLdouble *params);
    .... Float, Integer, ... follow

    pname - Specifies the parameter value to be returned. The symbolic constants in the list below are accepted.
    GL_ACCUM_ALPHA_BITS, GL_ACCUM_BLUE_BITS, GL_ACCUM_CLEAR_VALUE, GL_ACCUM_GREEN_BITS, GL_ACCUM_RED_BITS, GL_ACTIVE_TEXTURE, GL_ALIASED_POINT_SIZE_RANGE, .... 30 pages later ... GL_VIEWPORT, GL_ZOOM_X, GL_ZOOM_Y

    ---->8----

    $ grep '#define' /usr/include/GL/gl.h | wc -l
    812
    $ grep 'APIENTRY' /usr/include/GL/gl.h | wc -l  (counting functions really...)
    593

    less functions is goooood :)



  • @viraptor said:

    @Daid said:

    Having more then a few functions as an interface is a real hell. Atleast, I guess that's what the 'master' of the system we maintain here must have been thinking.

    OpenGL anyone?

    That happens because the GL libraries are thin wrappers on the drivers and hardware, so they designed the interface to permit the use of new features without needing an update to the GL library: if you have the relevant constants defined, then the library is just going to pass them on to the hardware and let it figure out what to do with them. This reduces the number of people who have to be involved when creating a new feature.

    This justification only works in a middleware library that spends most of its time passing values through to a lower layer. 



  • Wild guess, but isn't "tagebush" German for a thorn bush?



  • @henke37 said:

    Wild guess, but isn't "tagebush" German for a thorn bush?
    That explains something! (buch not bush :P)

     

    As for comparing to openGL. I can understand the openGL case. Where you can ask if functions exists and are enabled. And it's a dynamicly linked library, thus functionality might change on systems. In our case however, we have an embedded system with this staticly linked in. 



  • @henke37 said:

    Wild guess, but isn't "tagebush" German for a thorn bush?

     

    Tagebuch = Diary

     

    So for a log module it COULD be a good name but... .. No.  



  • @asuffield said:

    @viraptor said:

    @Daid said:

    Having more then a few functions as an interface is a real hell. Atleast, I guess that's what the 'master' of the system we maintain here must have been thinking.

    OpenGL anyone?

    That happens because the GL libraries are thin wrappers on the drivers and hardware, so they designed the interface to permit the use of new features without needing an update to the GL library: if you have the relevant constants defined, then the library is just going to pass them on to the hardware and let it figure out what to do with them. This reduces the number of people who have to be involved when creating a new feature.

    This justification only works in a middleware library that spends most of its time passing values through to a lower layer. 


    It also has uses for forward compatability.

    It allows older apps access to newer properties of a system. The app itself probably is clueless about how to use them, but the human is probably clued in enough to figure it out. (We hope)


Log in to reply