Re: help with linked lists



From: Peter Jay Salzman <p dirac org>
>
> hi there,
>
> using sdl i draw a number of circles (electric charges) and would like
> to know when the user clicks on a charge.  a basic charge is a struct:
>
>    typedef struct {
>       SDL_Surface *img;
>       int magnitude;
>       SDL_Rect rect;
>    } ChargeStruct;
>
> and i have a double linked list of them:
>
>    GList *ChargeList = NULL;
> 	ChargeStruct puck;
> 	...
> 	ChargeList = g_list_append (ChargeList, &puck);
>
> i'd like to take the mouse coordinates on a button click and check to
> see if the click happened on a charge.  if it finds a clicked charge, it
> returns a pointer to the ChargeStruct belonging to the clicked charge:
>
>
>   ChargeStruct *ChargeClicked(GList *ChgList, SDL_Event event)
>   {
>      GList *ptr;
>      int x, y;
>   
>      while (ptr != NULL) {
>         ptr = g_list_next(ChgList);
>         x = ptr->data->rect.x;
>         y = ptr->data->rect.y;
>         if (event.button.x > x - 10 && event.button.x < x + 10) {
>            printf("click\n");
>         }
>      }
>      return(ptr->data);
>   }
>
> i don't have any experience with GList's, so i'm grasping at straws.
>
> ptr->data should be a pointer to a ChargeStruct.  so ptr->data->rect
> should be the rect element of a ChargeStruct which is pointed to by
> data.
>
> but this function gives the compile errors:
>
> functions.c: In function `ChargeClicked':
> functions.c:21: warning: dereferencing `void *' pointer
> functions.c:21: request for member `rect' in something not a structure or union
> functions.c:22: warning: dereferencing `void *' pointer
> functions.c:22: request for member `rect' in something not a structure or union
>
> i feel like i'm losing my grip on what a pointer is.  the code makes
> sense to me, but obviously i'm mistaken about something.
>
> can someone help me out?  how do i access rect.x and rect.y of the
> ChargeStruct pointed to by ptr->data?
>
> thanks!
> pete

This appears to be more of a C typecasting issue than anything else.
What you need is ((ChargeStruct *) ptr->data)->rect, so that
C knows what kind of pointer ptr->data is. GList stores things
as void*, so that you can portably store any kind of pointer there.
You could also do:

ChargeStruct *data;
ptr = g_list_next(ChgList); // Maybe should be g_list_next(ptr) instead?
data = (ChargeStruct*) ptr->data;

and just use "data" in the rest of the code, so things look cleaner.

Ron Steinke



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]