Thread: stuck on namespace problem

  1. #1
    Registered User officedog's Avatar
    Join Date
    Oct 2008
    Posts
    77

    stuck on namespace problem

    I'm developing a screen manager for a GUI. It stores the coordinates of all objects on the screen. The screen manager is dynamically allocated and initialised:

    Code:
    ScreenManager * sm = screenManagerNew();
    I have a function which is designed to take the x,y coordinates of the mouse click (which are provided by the callback routine) and then search through the screen manager database to work out which object was clicked. It takes 3 arguments:

    Code:
    int screenManagerWhichObject(struct screenManager  *sm, int x, int y);
    The problem I have is that I cannot pass the address of the screen manager into the callback function, and I can't call the "whichObject" function from within the callback function either, because I still need the struct pointer to pass into this function and I can't find a way for the function to recognise it.

    I've tried all sorts so far, with no success: e.g.

    a) declaring and initialising the screen manager struct at the top of main (compiler complains - initialiser element is not constant)
    b) declaring the struct pointer at the top of the header file:

    struct screenManager *sm;

    c) Adding an additonal extern keyword for good measure
    d) Declaring and initialising the struct within the draw() function for my program which includes all the callback functions

    Generally the result I get is that even though I declare and initialise the screen manager struct, the callback function either does not recognise it or it recognises it as a NULL pointer.

    Can anyone can shine some light on what I'm doing wrong here?

  2. #2
    Registered User
    Join Date
    Apr 2008
    Posts
    396
    Code:
    struct screenManager* sm;
    // ...
    int screenManagerWhichObject(int x, int y) {
      // use sm here
    }
    // ...
    int main() {
      sm=screenManagerNew();
      // ...
    }
    I'm not sure to understand where the problem is, you're trying to make 'sm' a global, right? just make sure it is initialized before screenManagerWhichObject() is called.
    Last edited by root4; 11-20-2008 at 04:14 PM.

  3. #3
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    Quote Originally Posted by root4 View Post
    I'm not sure to understand where the problem is, you're trying to make 'sm' a global, right? just make sure it is initialized before screenManagerWhichObject() is called.
    It can be ensured by using access function
    Code:
    
    struct screenManager* getScreenManager(void)
    {
       static struct screenManager* sm = NULL;
       if(!sm)
       {
          /* initialize it here */
       }
       return sm;
    }
    in any place you need the sm - just call the getScreenManager function
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  4. #4
    Registered User officedog's Avatar
    Join Date
    Oct 2008
    Posts
    77
    Thanks for these answers root4 and vart. I think varts idea might be the way to go, but just incase there is another way, I have a little more explanation.

    I think what I had hoped for was a screen manager which comes into existence at the start of the program and then, as each time the screen redraws, updates its database of screen objects... and which can also be accessed within the callback to work out which object was clicked on. It's not possible to write additional arguments to the callback function). For example, when you can write a callback as:

    void mousePassive(int x, int y) {
    //etc
    }

    but not

    void mousePassive(int x, int y, struct screenManager *sm) {
    //etc
    }

    So I wondered if it was possible to declare the struct in some way that I can access it within the function itself. However, that's where I ran into problems and couldn't find a way to get it recognised within the function.

    Perhaps then, I should go with the idea that I get the coordinates of the mouse click by assigning them to some external variable, and each time the user clicks, I generate a new screen manager, which registers all objects, pass the mouse coordinates and checks for hits and then draws, and then set it free

    Don't know if it would make any difference if I initialised it statically as this could also be an alternative...

    Thanks for the replies. I'll have a think about this

  5. #5
    Woof, woof! zacs7's Avatar
    Join Date
    Mar 2007
    Location
    Australia
    Posts
    3,459
    I would recommend vart's method. Although you could do it the messy way

    screenman.h
    Code:
    #ifndef INCLUDED_SCREENMAN_H
    #define INCLUDED_SCREENMAN_H
    
    struct screenMan_s
    {
       int test;
    };
    
    extern struct screenMan_s * smp;
    
    #endif /* INCLUDED_SCREENMAN_H */
    screenman.c
    Code:
    #include "screenman.h"
    
    static struct screenMan_s sm = {0};
    struct screenMan_s * smp = &sm;
    
    void screenman_init(void)
    {
       /* blah */
       smp->test = 0;   /* not required, but this is a demo :D */
    }
    mouse.c
    Code:
    #include "screenman.h"
    
    void mousePassive(int x, int y)
    {
       smp->test = 5;           /* just make sure you don't dereference NULL :) */
       /* etc */
    }

  6. #6
    Registered User officedog's Avatar
    Join Date
    Oct 2008
    Posts
    77
    hello zacs7. You'll see I decided to stick with GLUT for now while I figure out the screen manager. Thanks for the alternative idea, i'm just getting the hang of the #ifndef stuff, so this is good timing.

    Just as a last thought - after that last post I had a go with doing a mega global static version (the "hit-it-with-a-hammer" approach):

    main.c
    Code:
    #include "drawing.h"
    #include "screenManager.h"
    
    ScreenManager sm2;
    
    int main (int argc, char * argv[]) {
        screenManagerInit(&(sm2));
        init(argc, argv);
        draw();
        return 0;
    }
    and tried this in the display callback function, in drawing.c:

    Code:
    void display() {
        glClear(GL_COLOR_BUFFER_BIT);
        grid();
        sm2.draw(&(sm2), "rect");
    
        glFlush();
    }
    and this in the mouse callback, also in drawing.c:

    Code:
    void mouse(int button, int state, int x, int y) {
        if (button == GLUT_LEFT && state == GLUT_DOWN) {
            int n = sm2.numberOfObjects;
            printf("\n\nstruct sm2 no. of objects = %d", n);
            sm2.print(&(sm2)); // prints database
        }
    }

    They all worked fine, so it looks like I have a choice. Thanks for the help

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. namespace tm?
    By cunnus88 in forum C++ Programming
    Replies: 3
    Last Post: 01-28-2009, 03:02 PM
  2. Defining a namespace.
    By leeor_net in forum C++ Programming
    Replies: 6
    Last Post: 01-24-2009, 07:17 AM
  3. Problem with friend class declaration in a namespace
    By Angus in forum C++ Programming
    Replies: 2
    Last Post: 12-09-2008, 01:29 PM
  4. Bin packing problem....
    By 81N4RY_DR460N in forum C++ Programming
    Replies: 0
    Last Post: 08-01-2005, 05:20 AM
  5. problem understanding namespace
    By cages in forum C++ Programming
    Replies: 5
    Last Post: 06-27-2005, 05:56 AM