OO Design Question

Whether you're a newbie or an experienced programmer, any questions, help, or just talk of any language will be welcomed here.

Moderator: Coders of Rage

User avatar
Maevik
Chaos Rift Junior
Chaos Rift Junior
Posts: 230
Joined: Mon Mar 02, 2009 3:22 pm
Current Project: www.keedepictions.com/Pewpew/
Favorite Gaming Platforms: PC
Programming Language of Choice: C++
Location: Long Beach, CA

OO Design Question

Post by Maevik »

If I have a class, and inside one of my class functions I wish to call a function that is part of my main code. How can I do this if my class is written as part of example.cpp and the function I want to call is part of main.cpp with the #include example.h ?
My love is like a Haddoken, it's downright fierce!
User avatar
kostiak2
Chaos Rift Cool Newbie
Chaos Rift Cool Newbie
Posts: 74
Joined: Tue Mar 24, 2009 4:08 pm

Re: OO Design Question

Post by kostiak2 »

Maevik wrote:If I have a class, and inside one of my class functions I wish to call a function that is part of my main code. How can I do this if my class is written as part of example.cpp and the function I want to call is part of main.cpp with the #include example.h ?
The real question is why would you want to do that?

Maybe it's a smart design choice, but maybe, there is a better way to do it, so what are you trying to achieve exactly?
User avatar
MarauderIIC
Respected Programmer
Respected Programmer
Posts: 3406
Joined: Sat Jul 10, 2004 3:05 pm
Location: Maryland, USA

Re: OO Design Question

Post by MarauderIIC »

You would need the function prototype for the function that's in main.cpp to be present in example.cpp or example.h. Then you can call it normally. However, in an OO design, it is uncommon to have (m)any functions besides main() not be in a class of some sort (in other words, main() is the only function not inside a class). You may want to take another look at your design.
I realized the moment I fell into the fissure that the book would not be destroyed as I had planned.
User avatar
Maevik
Chaos Rift Junior
Chaos Rift Junior
Posts: 230
Joined: Mon Mar 02, 2009 3:22 pm
Current Project: www.keedepictions.com/Pewpew/
Favorite Gaming Platforms: PC
Programming Language of Choice: C++
Location: Long Beach, CA

Re: OO Design Question

Post by Maevik »

ok, lets say for instance I want to make a game using the blitting functions similar to those in lazyfoo's SDL tutorials. Let's also say that I want my objects to handle blitting their own surface to the screen.

Code: Select all

//The blitting function

void applySurface( int x , int y , SDL_Surface* source , SDL_Surface* destination , SDL_Rect* clip = NULL )
{
     SDL_Rect offset;
     offset.x = x;
     offset.y = y;

     SDL_BlitSurface( source , clip , destination , &offset );
}

Code: Select all

//An Example Class, let's say its a squirrel

class squirrel
{
private:
     int xLoc;
     int yLoc;
     SDL_Surface image;
public:
     void processInput( SDL_Event* event );
}

Code: Select all

//An example of what the processInput() function might look like

void squirred::processInput( SDL_Event* event)
{
     if( event.type == SDL_KEYDOWN )
     {
          if( event.key.keysym.sym == SDLK_UP )
          {
               yLoc -= 5;
          }
          else if( event.key.keysym.sym == SDLK_UP )
          {
               yLoc += 5;
          }
          /* blah blah blah, test screen limits and left and right and all that stuff */
     }

     //Here is where I would put the blit function to have my squirrel function draw itself to the screen.
}
So based on what Marauder is saying, I shouldn't even have the applySurface() function in my main code in the first place?

Could I then build a class called like "screen" or something, and give it those functions ( load Images, blit surfaces, initialize video mode... ) then pass the instance of my screen class into the squirrel.processInput() function along with &event ?

Code: Select all

void squirred::processInput( SDL_Event* event , myScreenClass* screen )
{
     .    
     .
     .
     screen.applySurface( xLoc , yLoc , image , screen.screenSurface );     
}
Would this be the /better/ way to do it? Is it good practice to create a class for something if you know you will only make one instance of it?

edit: edited for clarity
My love is like a Haddoken, it's downright fierce!
User avatar
MarauderIIC
Respected Programmer
Respected Programmer
Posts: 3406
Joined: Sat Jul 10, 2004 3:05 pm
Location: Maryland, USA

Re: OO Design Question

Post by MarauderIIC »

I have something like

Code: Select all

class Game {
    Renderer renderer;
    vector<Object*> objects;
    void init();
    void handleInput();
    void update(); //Update positions
    void drawAll();
};

Code: Select all

class Object {
    int x, y;
    SDL_Surface* mySurface; //This is also an element in Renderer::loadedTextures
    public:
    SDL_Surface* getSurface();
};

Code: Select all

class Renderer {
    ...
    SDL_Surface* screen;
    SDL_Surface* background;
    const int SCREEN_WIDTH = 640;
    const int SCREEN_HEIGHT = 480;
    map<string, SDL_Surface*> loadedTextures;
    public:
    void draw(SDL_Surface* surf, int x, int y);
    void finishFrame();
    ~Renderer(); //This frees all the textures.
};

Code: Select all

void Game::drawAll() {
    for (vector<Object*>::iterator i = objects.begin(); i != objects.end(); ++i) {
        renderer.draw(i->getSurface(), i->getX(), i->getY());
    renderer.finishFrame();
}

Code: Select all

void Renderer::draw(SDL_Surface* surf, int x, int y) {
    SDL_Rect offset;
    offset.x = x;
    offset.y = y;

    SDL_BlitSurface(surf, NULL, screen, &offset);
}

Code: Select all

void Renderer::finishFrame() {
    SDL_Flip(screen);
    SDL_FillRect(screen, &screen->clip_rect, SDL_MapRGB(screen->format, 255, 255, 255)); //Reset
}
The game invokes the Renderer on all of its objects. Renderer does all the drawing. Then the game tells the renderer it's done sending objects, and the Renderer finishes. You could also pass the Renderer a list of objects and make it iterate through them, instead of one at a time, then it would know when it should wrap up the frame without the Game telling it to.
I realized the moment I fell into the fissure that the book would not be destroyed as I had planned.
User avatar
kostiak2
Chaos Rift Cool Newbie
Chaos Rift Cool Newbie
Posts: 74
Joined: Tue Mar 24, 2009 4:08 pm

Re: OO Design Question

Post by kostiak2 »

Yeah, lazyfoo's tutorials are great, his code is terrible.. The design you suggested should be done like that, instead use something similar to what MarauderIIC suggested. I use something similar to this. (Not as complicated as that yet, but as I see it, I'll be there soon).
User avatar
Maevik
Chaos Rift Junior
Chaos Rift Junior
Posts: 230
Joined: Mon Mar 02, 2009 3:22 pm
Current Project: www.keedepictions.com/Pewpew/
Favorite Gaming Platforms: PC
Programming Language of Choice: C++
Location: Long Beach, CA

Re: OO Design Question

Post by Maevik »

Thanks for all the constructive feedback guys. This is immesely helpful.
My love is like a Haddoken, it's downright fierce!
User avatar
dandymcgee
ES Beta Backer
ES Beta Backer
Posts: 4709
Joined: Tue Apr 29, 2008 3:24 pm
Current Project: https://github.com/dbechrd/RicoTech
Favorite Gaming Platforms: NES, Sega Genesis, PS2, PC
Programming Language of Choice: C
Location: San Francisco
Contact:

Re: OO Design Question

Post by dandymcgee »

Thanks Marauder, that helped answer part of my question posted elsewhere. 8-)
Falco Girgis wrote:It is imperative that I can broadcast my narcissistic commit strings to the Twitter! Tweet Tweet, bitches! :twisted:
User avatar
programmerinprogress
Chaos Rift Devotee
Chaos Rift Devotee
Posts: 632
Joined: Wed Oct 29, 2008 7:31 am
Current Project: some crazy stuff, i'll tell soon :-)
Favorite Gaming Platforms: PC
Programming Language of Choice: C++!
Location: The UK
Contact:

Re: OO Design Question

Post by programmerinprogress »

And it helped me too!

thanks for the advice ;)
---------------------------------------------------------------------------------------
I think I can program pretty well, it's my compiler that needs convincing!
---------------------------------------------------------------------------------------
And now a joke to lighten to mood :D

I wander what programming language anakin skywalker used to program C3-PO's AI back on tatooine? my guess is Jawa :P
User avatar
Maevik
Chaos Rift Junior
Chaos Rift Junior
Posts: 230
Joined: Mon Mar 02, 2009 3:22 pm
Current Project: www.keedepictions.com/Pewpew/
Favorite Gaming Platforms: PC
Programming Language of Choice: C++
Location: Long Beach, CA

Re: OO Design Question

Post by Maevik »

MarauderIIC wrote:I have something like

Code: Select all

class Game {
    Renderer renderer;
    vector<Object*> objects;
    void init();
    void handleInput();
    void update(); //Update positions
    void drawAll();
};

Code: Select all

class Object {
    int x, y;
    SDL_Surface* mySurface; //This is also an element in Renderer::loadedTextures
    public:
    SDL_Surface* getSurface();
};

Code: Select all

class Renderer {
    ...
    SDL_Surface* screen;
    SDL_Surface* background;
    const int SCREEN_WIDTH = 640;
    const int SCREEN_HEIGHT = 480;
    map<string, SDL_Surface*> loadedTextures;
    public:
    void draw(SDL_Surface* surf, int x, int y);
    void finishFrame();
    ~Renderer(); //This frees all the textures.
};

Code: Select all

void Game::drawAll() {
    for (vector<Object*>::iterator i = objects.begin(); i != objects.end(); ++i) {
        renderer.draw(i->getSurface(), i->getX(), i->getY());
    renderer.finishFrame();
}

Code: Select all

void Renderer::draw(SDL_Surface* surf, int x, int y) {
    SDL_Rect offset;
    offset.x = x;
    offset.y = y;

    SDL_BlitSurface(surf, NULL, screen, &offset);
}

Code: Select all

void Renderer::finishFrame() {
    SDL_Flip(screen);
    SDL_FillRect(screen, &screen->clip_rect, SDL_MapRGB(screen->format, 255, 255, 255)); //Reset
}
The game invokes the Renderer on all of its objects. Renderer does all the drawing. Then the game tells the renderer it's done sending objects, and the Renderer finishes. You could also pass the Renderer a list of objects and make it iterate through them, instead of one at a time, then it would know when it should wrap up the frame without the Game telling it to.
I was trying to see how far I could get trying to build an engine with this design. I came to a compiler error along the way that I absolutely cannot figure out. I thought that since I'm essentially trying to mirror your code, you might be in a position to help me :D

Code: Select all

#pragma once
#include "SDL.h"
#include "SDL_image.h"
#include "SDL_ttf.h"
#include "SDL_mixer.h"
#include <string>
#include <vector>
#include "Renderer.h"

class Game
{
private:
	//Renderer rend;
public:
	Game(void);
	bool init();
	void input( SDL_Event* event , Renderer* rend );
	~Game(void);
};

Code: Select all

error C2061: syntax error : identifier 'Renderer'	
It doesn't like me initializing an instance of the Rederer class ( you can see the two ways I was trying, both same error ) and I can't figure out why.

It doesn't seem to be a problem with the Renderer class, since if I initialize an instance in the main function it works fine.

Is there something special I need to do when making a class a member of another class?
My love is like a Haddoken, it's downright fierce!
User avatar
Maevik
Chaos Rift Junior
Chaos Rift Junior
Posts: 230
Joined: Mon Mar 02, 2009 3:22 pm
Current Project: www.keedepictions.com/Pewpew/
Favorite Gaming Platforms: PC
Programming Language of Choice: C++
Location: Long Beach, CA

Re: OO Design Question

Post by Maevik »

So this just started working when I created a test class to see if it was happening with any other classes that I make members. So although I was still confused about what had happened and why, I continued on with my project. After about 10 minutes, it just stopped compiling again. The exact line I changed between successful compiles was adding this line ( and only this line ) to the Renderer class deconstructor

Code: Select all

SDL_FreeSurface( background );
Even after I removed the line it would not compile again. This doesn't make sense to me at all.
My love is like a Haddoken, it's downright fierce!
User avatar
Ginto8
ES Beta Backer
ES Beta Backer
Posts: 1064
Joined: Tue Jan 06, 2009 4:12 pm
Programming Language of Choice: C/C++, Java

Re: OO Design Question

Post by Ginto8 »

Maevik wrote:So this just started working when I created a test class to see if it was happening with any other classes that I make members. So although I was still confused about what had happened and why, I continued on with my project. After about 10 minutes, it just stopped compiling again. The exact line I changed between successful compiles was adding this line ( and only this line ) to the Renderer class deconstructor

Code: Select all

SDL_FreeSurface( background );
Even after I removed the line it would not compile again. This doesn't make sense to me at all.
did you allocate background? That may be the problem.
Quit procrastinating and make something awesome.
Ducky wrote:Give a man some wood, he'll be warm for the night. Put him on fire and he'll be warm for the rest of his life.
User avatar
wtetzner
Chaos Rift Regular
Chaos Rift Regular
Posts: 159
Joined: Wed Feb 18, 2009 6:43 pm
Current Project: waterbear, GBA game + editor
Favorite Gaming Platforms: Game Boy Advance
Programming Language of Choice: OCaml
Location: TX
Contact:

Re: OO Design Question

Post by wtetzner »

Ginto8 wrote:
Maevik wrote:So this just started working when I created a test class to see if it was happening with any other classes that I make members. So although I was still confused about what had happened and why, I continued on with my project. After about 10 minutes, it just stopped compiling again. The exact line I changed between successful compiles was adding this line ( and only this line ) to the Renderer class deconstructor

Code: Select all

SDL_FreeSurface( background );
Even after I removed the line it would not compile again. This doesn't make sense to me at all.
did you allocate background? That may be the problem.
That wouldn't stop it from compiling. Maevik, what error message are you getting when you compile?
The novice realizes that the difference between code and data is trivial. The expert realizes that all code is data. And the true master realizes that all data is code.
User avatar
Maevik
Chaos Rift Junior
Chaos Rift Junior
Posts: 230
Joined: Mon Mar 02, 2009 3:22 pm
Current Project: www.keedepictions.com/Pewpew/
Favorite Gaming Platforms: PC
Programming Language of Choice: C++
Location: Long Beach, CA

Re: OO Design Question

Post by Maevik »

error C2061: syntax error : identifier 'Renderer'

It's been happening on and off still, to the point where I'm almost convinced it's a Visual Studio 9 bug. I'm really hesitant to chok it up to that though, especially when I'm learning. I just can't find any reason for the behavior I'm seeing, and I'll change something seemingly unrelated, then it wont compile, then when I change it back, it still wont compile.
My love is like a Haddoken, it's downright fierce!
User avatar
Maevik
Chaos Rift Junior
Chaos Rift Junior
Posts: 230
Joined: Mon Mar 02, 2009 3:22 pm
Current Project: www.keedepictions.com/Pewpew/
Favorite Gaming Platforms: PC
Programming Language of Choice: C++
Location: Long Beach, CA

Re: OO Design Question

Post by Maevik »

Ginto8 wrote:
Maevik wrote:So this just started working when I created a test class to see if it was happening with any other classes that I make members. So although I was still confused about what had happened and why, I continued on with my project. After about 10 minutes, it just stopped compiling again. The exact line I changed between successful compiles was adding this line ( and only this line ) to the Renderer class deconstructor

Code: Select all

SDL_FreeSurface( background );
Even after I removed the line it would not compile again. This doesn't make sense to me at all.
did you allocate background? That may be the problem.
I'm not sure what you're asking. I didn't put background on the heap if that's what you mean, but I did load the file and optimize it with SDL_DisplayFormat(), it works and displays the background ~half the time.
My love is like a Haddoken, it's downright fierce!
Post Reply