Programming C, C++, Java, PHP, Ruby, Turing, VB
Computer Science Canada 
Programming C, C++, Java, PHP, Ruby, Turing, VB  

Username:   Password: 
 RegisterRegister   
 event driven programming in C++
Index -> Programming, C++ -> C++ Help
View previous topic Printable versionDownload TopicSubscribe to this topicPrivate MessagesRefresh page View next topic
Author Message
Anon




PostPosted: Sat Mar 24, 2007 10:20 pm   Post subject: event driven programming in C++

I was just wondering what the best way was to implement event driven programming in C++ with the SDL. Right now I'm using a while loop that continously checks a boolean flag, and that flag is set when the user X's out the window, signalling the program to terminate. However, in Java, all I had to do was to implement a listener and write the event handler. Is there anything like that in C++/SDL? If not, is there a better way to handle events then what I'm doing now?

heres a snippet from my code that might better show what I mean.
This is what I'm doing right now:
code:

while (qflag) {
  while (SDL_PollEvent(&evt)) {
    if (evt.type == SDL_QUIT) {qflag = false;}
  }


}


This is the sort of thing I'd do in Java(note: I believe the example code is deprecated, but I just want to show how I could streamline detection/handling of events in Java):
code:

public class ExampleApp extends Frame
{
        //other stuff
       
        public boolean handleEvent(Event evt)
        {
                if (evt.id == Event.WINDOW_DESTROY)
                {
                        System.exit(0);
                }
                return false;
        }
       
}
Sponsor
Sponsor
Sponsor
sponsor
abcdefghijklmnopqrstuvwxy




PostPosted: Sat Mar 24, 2007 10:47 pm   Post subject: RE:event driven programming in C++

I too am using c++ with sdl and was wondering if the top example you posted is actually an example of "event driven programming". Cause all it is is a big while loop with a bunch of conditional statements - seems kind of blande to me.

About your java code, if all you want is a function handEvents() than why don't you just write a c++ function called handle events and sub it in your while loop.
Anon




PostPosted: Sat Mar 24, 2007 10:58 pm   Post subject: RE:event driven programming in C++

I agree, the C++ stuff I wrote doesnt really seem like 'proper' event driven stuff to me.

The thing with the java code is, that in the java example above, the handleEvent Method was all that was needed. Whenever the user closed the window, handleEvent was automatically called, ie there was no need to continously check to see if an event had been fired.

Thats what I'd like to do with C++ and the SDL.
ericfourfour




PostPosted: Sun Mar 25, 2007 1:12 am   Post subject: RE:event driven programming in C++

Some of the more experienced c++ users may be able to help you, but I'm going to suggest callback functions.

Although, if you want to make it work like Java (I assume you were working with Swing), you are going to have to do some research into Swing. It doesn't quite "automatically" call the handleEvent method and it does consistently check if an event has occurred. If you want to get the same effect in your c++ program, you are going to have to do a lot of work.
abcdefghijklmnopqrstuvwxy




PostPosted: Sun Mar 25, 2007 6:03 am   Post subject: RE:event driven programming in C++

Anon I was also asking if it was "proper" cause I honestly don't know that's just how I'm doing it. So far I haven't come across a better way.

About handleEvents() I don't get how it would "automatically" get called.

Your code could look something like this though, incase you don't already know...

code:


while (qflag) {
  while (SDL_PollEvent(&evt)) {
     handleEvents(evt);
  }
}   



I guess it makes the main() smaller to make a handleEvent function, but other than that I don't see a benifit.
md




PostPosted: Sun Mar 25, 2007 10:35 am   Post subject: RE:event driven programming in C++

If SDL supports callback functions you can use those, but in the end you'll have a while loop somewhere that just just as you've already got.

Java hides all the looping and polling from you so you don't have to worry about it. In C++ there is no such abstraction, so you need to either write an extensive class system to create it; or just get used to the idea of having a central while loop that controls everything.
Mazer




PostPosted: Sun Mar 25, 2007 12:51 pm   Post subject: RE:event driven programming in C++

It might also be worth knowing that none of that was actually C++. You can use it with C++, but SDL is written in C.
Anon




PostPosted: Mon Mar 26, 2007 10:07 am   Post subject: Re: RE:event driven programming in C++

Mazer @ Sun Mar 25, 2007 12:51 pm wrote:
It might also be worth knowing that none of that was actually C++. You can use it with C++, but SDL is written in C.


really? thats interesting,
I was compiling with g++, all this time, but after reading this I used gcc to compile my program, and it worked just fine, since I had no OOP stuff, and I stuck to c strings. Thanks.

I have another question though. When I compile/run my program, (entire code below), it seems to use a lot of CPU power, according to the windows task manager. have I done something wrong?
I apologise in advance for the lack of good commenting


code:


#include <stdio.h>
#include <stdlib.h>

#include "SDL.h"
#include "SDL_Image.h"
#include "SDL_ttf.h"


//define screen constants
#define SCRN_WDTH 640
#define SCRN_HGHT 480
#define SCRN_RS 32

//declare SDL surfaces globally
SDL_Surface *image = NULL;
SDL_Surface *msg = NULL;
SDL_Surface *screen = NULL;

//declare SDL_Event var
SDL_Event evt;
//declare an array of rectangles that will define where on the sprite sheet we clip the image
SDL_Rect clips[4];
//declare a fontface & color
TTF_Font *font = NULL;
SDL_Color textColor = { 0, 255, 255 };

//initialise SDL
int init() {
        if (SDL_Init(SDL_INIT_EVERYTHING) <0) {return 1;}
        if (TTF_Init()<0) {return 1;}
        return 0;
}

//load the image from file, check for null pointers, and get rid of backgrounds
SDL_Surface *safeLoadImage(char* fname) {
        SDL_Surface* tmp = NULL;
        SDL_Surface* newImg = NULL;

        tmp = IMG_Load(fname);

        if (tmp != NULL) {
                newImg = SDL_DisplayFormat( tmp );
                SDL_FreeSurface(tmp);
        }

        if (newImg != NULL) {
                Uint32 ck = SDL_MapRGB( newImg->format, 0, 0xFF, 0xFF );
                SDL_SetColorKey( newImg, SDL_RLEACCEL | SDL_SRCCOLORKEY, ck );
        }



        return newImg;
}


//same as above for the font
TTF_Font *safeLoadFont(char* fname, int size) {
        TTF_Font* tmp = NULL;


        tmp = TTF_OpenFont(fname, size);






        return tmp;
}

//paint the part of the img surface designated by clip, to the scrn surface at the offsets x and y, if clip is NULL, then paint all of img to scrn
void applyToScreen(int x, int y, SDL_Surface* img, SDL_Surface* scrn, SDL_Rect* clip) {
        SDL_Rect off;
        SDL_Rect tmp;

        if (clip == NULL) {
                clip = &tmp;
                tmp.x = 0;
                tmp.y = 0;
                tmp.w = img->w;
                tmp.h = img->h;
        }

        off.x = x;
        off.y = y;

        SDL_BlitSurface(img, clip, scrn, &off);

}


int main(int argc, char *argv[]) {
//init the quit flag, and the clps array
        int qflag = 0;
        clips[0].x = 0;
        clips[0].y = 0;
        clips[0].w = 50;
        clips[0].h = 50;

        clips[1].x = 50;
        clips[1].y = 0;
        clips[1].w = 50;
        clips[1].h = 50;

        clips[2].x = 0;
        clips[2].y = 50;
        clips[2].w = 50;
        clips[2].h = 50;

        clips[3].x = 50;
        clips[3].y = 50;
        clips[3].w = 50;
        clips[3].h = 50;
//initialise
        if (init() == 1) {return 1;}
        atexit(SDL_Quit);

        screen = SDL_SetVideoMode(640, 480, 32, SDL_SWSURFACE);
        if (screen == NULL) {return 1;}
        SDL_WM_SetCaption("TEST",NULL);
//wipe the screen blank
        SDL_FillRect( screen, &screen->clip_rect, SDL_MapRGB( screen->format, 0xFF, 0xFF, 0xFF ) );
//load necessary files
        image = safeLoadImage("image.bmp");
        font = safeLoadFont("maneater.ttf", 20);

        if (image == NULL || font == NULL) {return 1;}
//paint the stuff to screen
        applyToScreen( 0, 0, image, screen, &clips[ 0 ] );
        applyToScreen( 540, 0, image, screen, &clips[ 1 ] );
        applyToScreen( 0, 380, image, screen, &clips[ 2 ] );
        applyToScreen( 540, 380, image, screen, &clips[ 3 ] );


        if (SDL_Flip(screen) <0) {
                return 1;
        }
        SDL_Delay(3000);
//start the event handling loop
        while (qflag == 0) {
              //keep running untilt he quit flag is set
                while (SDL_PollEvent(&evt)) {
                        //check for events
                        //handle events based on their type
                        if (evt.type == SDL_KEYDOWN) {
                          //if user presses a key
                                switch(evt.key.keysym.sym) {
                                        case SDLK_UP:
                                                msg = TTF_RenderText_Solid( font, "UP was pressed", textColor );
                                                break;
                                        case SDLK_DOWN:
                                                msg = TTF_RenderText_Solid( font, "DOWN was pressed", textColor );
                                                break;
                                        case SDLK_LEFT:
                                                msg = TTF_RenderText_Solid( font, "LEFT was pressed", textColor );
                                                break;
                                        case SDLK_RIGHT:
                                                msg = TTF_RenderText_Solid( font, "RIGHT was pressed", textColor );
                                                break;
                                        default:
                                                msg = TTF_RenderText_Solid( font, "PRESS an arrow key", textColor );
                                                break;

                                }
                                  //repaint the screen
                                SDL_FillRect( screen, &screen->clip_rect, SDL_MapRGB( screen->format, 0xFF, 0xFF, 0xFF ) );
                                        applyToScreen( 0, 0, image, screen, &clips[ 0 ] );
                                        applyToScreen( 540, 0, image, screen, &clips[ 1 ] );
                                        applyToScreen( 0, 380, image, screen, &clips[ 2 ] );
                                        applyToScreen( 540, 380, image, screen, &clips[ 3 ] );
                                applyToScreen(100,100, msg, screen, NULL);
                                if (SDL_Flip(screen) <0) {
                                                return 1;
                                }
                        }
                        else if (evt.type == SDL_QUIT) {
                                qflag = 1;
                        }
                }
        }


//clean up and exit.
        TTF_CloseFont(font);
        TTF_Quit();



        SDL_FreeSurface( image );
        SDL_Quit();
        return 0;
}



First I thought the inefficiency was because I was repainting the screen each time a key was pressed, but even if I press no keys and let the program sit idle(ie pollEvent finds nothing, and so the screen is not repainted), it still takes up a lot of CPU power. Any suggestions?
Sponsor
Sponsor
Sponsor
sponsor
md




PostPosted: Mon Mar 26, 2007 10:59 am   Post subject: RE:event driven programming in C++

you're busy polling, which means that if there are no events you go and ask again right away. This a fine for things like games where you want things to happen as fast as they can, but otherwise it's pretty inefficient. A solution would be to insert a sleep() statement somewhere (or the SDL equivalent). That way you give up some CPU time to other processes and the CPU usage will drop.
OneOffDriveByPoster




PostPosted: Mon Mar 26, 2007 12:11 pm   Post subject: Re: RE:event driven programming in C++

Anon @ Mon Mar 26, 2007 10:07 am wrote:
code:
                while (SDL_PollEvent(&evt)) {
There is a SDL_WaitEvent (I believe). Use that if you only do things in response to keypresses (e.g., no animation in the background, etc.).
Anon




PostPosted: Mon Mar 26, 2007 3:54 pm   Post subject: Re: RE:event driven programming in C++

I looked up SDL_WaitEvent, but it seems that all that does is wait for 10 milliseconds before rechecking the event queue. So, I think I'll just include an SDL_Delay(10); in the outer while loop. Hopefully, that should give the same effect.

thanks everyone.
Display posts from previous:   
   Index -> Programming, C++ -> C++ Help
View previous topic Tell A FriendPrintable versionDownload TopicSubscribe to this topicPrivate MessagesRefresh page View next topic

Page 1 of 1  [ 11 Posts ]
Jump to:   


Style:  
Search: