Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » OOP Design and Resource Management

This thread is locked; no one can reply to it. rss feed Print
 1   2   3 
OOP Design and Resource Management
_Kronk_
Member #12,347
November 2010

Hey people. I just recently got C++ The Language, and it's really helping me see how amazingly bad my code is and is giving me some great ideas on how to make my game engine API more manageable and stable.

So, I have to have a resource manager in my design; it just makes sense. The way I ahve been doing this is to have a single class, ResourceManager, that loads all the datafiles, etc, and also contains all the drawing functions so that anything that needs to be drawn also has indirect access to the data; in this case a user might have an Animation class that contains a list of unsigned ints that are frame indices from the datafile, these are sent to the ResourceManager's draw functions as arguments, etc.

TL;DR

Should I use a Singleton(which means Resource::f() syntax) or do what Stroustrup seems to like in C++TL, which would be something like this:

#SelectExpand
1 2// ResourceInterface.h 3 4namespace Resources { 5 6void FlipBuffer(); 7void Draw(int x, int y, unsigned frame, unsigned a); 8... 9 10} 11 12// ResourceImplementation.cpp 13 14namespace Resources { 15 16 BITMAP * buffer; 17 DATAFILE * data; 18 19} 20 21void Resources::Draw(int x, int y, unsigned frame, unsigned a) { 22 23 set_trans_blender(0, 0, 0, a); 24 draw_trans_sprite(buffer, (BITMAP*)data[frame].dat, x, y); 25 26} 27 28// etc...

So, users of the Resource code can just

using Resources;
Draw(myX, myY, anim->CurrentFrame(), anim->A());

instead of (a) exposing the Resource interface directly and (b) having to use verbose syntax.

Personally, I prefer using the namespace. Which is better?

--------------------------------------------------
"If only our dreams were fires to ignite, then we could let the whole world burn" -Emery

My blog: http://joshuadover.tumblr.com

bamccaig
Member #7,536
July 2006
avatar

Neither. The "best" is to use a non-static (non-Singleton) instance of your resource manager object. Also, your resource manager probably shouldn't know how to draw anything. That's mixing up concerns. Your resource manager should manage resources well. Nothing more.

_Kronk_ said:

namespace Resources {
   // ...
}

void Draw(//...

Draw is supposed to be inside of the namespace. ;) But again, it shouldn't be. ;D I like to have a "renderer" object that knows how to draw to the back-buffer/display/screen.

_Kronk_
Member #12,347
November 2010

bamccaig said:

Neither. The "best" is to use a non-static (non-Singleton) instance of your resource manager object. Also, your resource manager probably shouldn't know how to draw anything. That's mixing up concerns. Your resource manager should manage resources well. Nothing more.

The reason I have it doing the drawing is that it keeps the allegro backend from users; any code relating to DATAFILEs or BITMAPs is completely contained in the Resource Manager. I suppose I could rename it "GraphicsManager" or something similar to show the relationship better. I'm actually planning on writing an RAII wrapper class for BITMAPs and DATAFILEs, so that a ResourceManager might end up being obselete anyway.

If I were to use a single instance of ResourceManager somewhere and then pass around references/pointers to it, that changes the user's relationship to it; you go from

#SelectExpand
1 2// Drawing_Thingy.h 3 4class Thing { 5 6 protected: 7 8 int x, int y, unsigned frame, unsigned a; 9 10 public: 11 12 void Draw(); 13} 14 15// Drawing_Thingy.cpp 16 17#include "Drawing_Thingy.h" 18#include "Resources.h" 19using Resources; 20 21void Thing::Draw() { 22 23 DrawImage(x, y, frame, a); 24 25}

which has an understood the ResourceManager relationship to

#SelectExpand
1 2// Drawing_Thingy2.h 3 4class Thing { 5 6 protected: 7 8 int x, int y, unsigned frame, unsigned a; 9 10 public: 11 12 void Draw(ResourceManager& r); 13} 14 15// Drawing_Thingy2.cpp 16 17void Thing::Draw(ResourceManager& r) { 18 19 r.DrawImage(x, y, frame, a); 20 21}

which has an understood a ResourceManager relationship, when in reality there is only one ResourceManager.

Another question is where would the ResourceManager live? If it were made a member of the Game class, you would have to use syntax like

things[i]->Draw(Game->Resources);

which isn't nearly as clean or easy to read as the namespace option.

  • edit

Well, I'll have to go for a regular instance-centric design anyway. Just realized that I can't have an RAII wrapper construct/destruct in a semi-global scope like a namespace when I'm using allegro :(

--------------------------------------------------
"If only our dreams were fires to ignite, then we could let the whole world burn" -Emery

My blog: http://joshuadover.tumblr.com

bamccaig
Member #7,536
July 2006
avatar

_Kronk_ said:

The reason I have it doing the drawing is that it keeps the allegro backend from users; any code relating to DATAFILEs or BITMAPs is completely contained in the Resource Manager.

...

...there is only one ResourceManager.

Another question is where would the ResourceManager live? If it were made a member of the Game class, you would have to use syntax like

things[i]->Draw(Game->Resources);

which isn't nearly as clean or easy to read as the namespace option.

You asked for good practices and I'm giving them to you. >:( Don't shoot the messenger. Global state is always a bad thing because it's too easy to break things. With the namespace solution, all anyone has to do to foil your plans is al_destroy_bitmap(ResourceManager::bitmaps[0]). Have fun with that. ::) With the Singleton solution, it's impossible to test without affecting the entire application, which can cause other strange things to break. With a local object you are in complete control of what can talk to it and it is in complete control of what its willing to tell them.

I wouldn't pass the resource manager into a thing and have it draw itself with the resource manager though. From the sound of it all of your things are going to have very similar Draw methods. I would try to implement a common interface (abstract base class) for all things drawable and have a renderer object draw those. Your things will implement this drawable interface. The one renderer object can know about the one resource manager and then it's just a matter of saying...

for(<each drawable thing>)
{
    renderer.render(<thing>);
}

The renderer can worry about figuring out which resource to draw for which thing and how based on the interface(s) (you can have multiple drawable interfaces, if you need them, and therefore many overloads of Renderer::render, but you probably won't need this unless you do something beyond drawing a sprite per thing).

_Kronk_
Member #12,347
November 2010

bamccaig said:

You asked for good practices and I'm giving them to you. Don't shoot the messenger.

Sorry, didn't mean to come across that way. I was just kind of frustrated trying to find the best solution. It seems like I've been working on this forever ::)

So where would the Renderer be? It wouldn't be global, so maybe a member of the game class?

--------------------------------------------------
"If only our dreams were fires to ignite, then we could let the whole world burn" -Emery

My blog: http://joshuadover.tumblr.com

Mark Oates
Member #1,146
March 2001
avatar

Don't put the cart before the horse. The most important thing to think about is how you want to use the interface. First ask yourself "What would make it the most reasonable and usable?"

For example, I hide all my image managing behind the following functions:

ALLEGRO_BITMAP *get_image(const char *filename);
bool preload_image(const char *filename);
bool reload_image(const char *filename);
void set_image_path(const char *filename);

The above functions include several convience behaviors, including that get_image will never return a null pointer and crash my program. If you haven't preloaded an image yet, no big deal, it will be loaded on first call to get_image and is ready from that point on. Whenever I draw, I draw with the image filename, which acts as the identifier:

al_draw_bitmap(get_image("monkey.png"), 50, 20, NULL);

This way I don't have to remember indexes or variable names. Everything is consistent.

There are a multitude of ways that these functions could be "solved" under the hood, but in the end, it doesn't matter. The important thing is that you should think about how you want to use it first. Then solve for that.

Passing around pointers and instances, and juggling namespaces and whatnots is only going to make things worse.

--
Visit CLUBCATT.com for cat shirts, cat mugs, puzzles, art and more <-- coupon code ALLEGRO4LIFE at checkout and get $3 off any order of 3 or more items!

AllegroFlareAllegroFlare DocsAllegroFlare GitHub

axilmar
Member #1,204
April 2001

_Kronk_ said:

Personally, I prefer using the namespace. Which is better?

Neither.

Remember that object-oriented design is about objects. You shouldn't have any manager classes, it's a mistake. You should have objects that represent the actual entities of your program.

So, from the text you posted, I can infer the following objects:

  • Datafile. Obvious.


  • Bitmap. Bitmaps can be loaded separately, or returned from datafiles.


  • other resources like bitmap that can be loaded separately, but also be in a data file, like sounds, fonts, colors, etc.


  • Animation class. When created, it should be setup with the appropriate resources loaded by the above classes.


  • GameObject or Sprite or something like that; this object knows how to use an animation object in order to have a visual presence in the game world.

jmasterx
Member #11,410
October 2009

You always want to think, things might change, I might need more than 1 of something. In fact ideally (but not likely) your game should be able to be instanced multiple times and run separate instances of itself on multiple threads happily. I realize the underlying graphics or audio apis might not allow this but you want to think with this idea in mind; anything is bound to change, and singletons are bad.

Namespaces are a bit like packages in Java, or folders in a file system.

Because C++ relies heavily on libraries you want to know where classes come from.

Internally it can be used to organize though:

gui::widget::TextBox* textBox = new  gui::widget::TextBox();
base::Entity* hunter = new character::enemy::Hunter();

That's overkill but you get the idea. They are used to organize your classes, not to be your classes.

bamccaig
Member #7,536
July 2006
avatar

_Kronk_ said:

Sorry, didn't mean to come across that way. I was just kind of frustrated trying to find the best solution. It seems like I've been working on this forever ::)

I hope you didn't take me too seriously. :) It might seem awkward or tedious at first until you actually start doing this. You will [hopefully] see how much easier it is to write and organize though. :)

_Kronk_ said:

So where would the Renderer be? It wouldn't be global, so maybe a member of the game class?

That is an option. It could just be a local variable in whatever function/method the main game loop is in. Where it is depends on your design. It really doesn't need to be known to much of the program though. Mostly only the part that renders the game, which is hopefully only done in one part of the program. It can probably be a local variable somewhere, but it might make sense to make it a member of an object instead.

axilmar said:

Remember that object-oriented design is about objects.

Yes.

axilmar said:

You shouldn't have any manager classes, it's a mistake.

Not really. Managing/manipulating/organizing objects is a necessary thing and in a truly object-oriented world it would be objects that do these things also.

axilmar said:

You should have objects that represent the actual entities of your program.

Yes.

axilmar said:

When created, it should be setup with the appropriate resources loaded by the above classes.

It's debatable whether a bitmap object should know how to load itself from a file. It's especially awkward in C++ where throwing exceptions from a constructor is not so simple. I've found that it's often useful to have a separate class do this. The bitmap object itself becomes just a dumb data object and then you have higher-level objects that manipulate them.

AMCerasoli
Member #11,955
May 2010
avatar

axilmar said:

Remember that object-oriented design is about objects. You shouldn't have any manager classes, it's a mistake.

I don't know about classes manager (I don't use them when doing OOP), but resource managers it's also a very good idea in OOP.

A lot of objects may use the same resources like sounds or images, if you create 50 instances of the same object obviously you're not going to load an image per each object.

I use to send a pointer to the resource manager to each of my objects, and if the objects needs an image or sound etc... talks with the resource manager, and the resource managers do all that it needs to do to find that file: search in the .exe directory, sear on internet etc...

axilmar
Member #1,204
April 2001

bamccaig said:

Not really. Managing/manipulating/organizing objects is a necessary thing and in a truly object-oriented world it would be objects that do these things also.

Truly object-oriented worlds do not have manager objects. Look around you; do you see any manager object? you don't.

Quote:

It's debatable whether a bitmap object should know how to load itself from a file.

Not debatable at all, for me. The bitmap knows its internal organization of information, and so the bitmap should be able to load itself from a file.

Quote:

It's especially awkward in C++ where throwing exceptions from a constructor is not so simple.

There is no problem in throwing exceptions from constructors. If an exception is thrown from a constructor, the destructor of all up to that point constructed objects will be invoked, as if the object was deleted.

Quote:

I've found that it's often useful to have a separate class do this. The bitmap object itself becomes just a dumb data object and then you have higher-level objects that manipulate them.

And throw simplicity out of the window, for no benefit?

A lot of objects may use the same resources like sounds or images, if you create 50 instances of the same object obviously you're not going to load an image per each object.I use to send a pointer to the resource manager to each of my objects, and if the objects needs an image or sound etc... talks with the resource manager, and the resource managers do all that it needs to do to find that file: search in the .exe directory, sear on internet etc...

You can always create the resource once and then share it amongst all parts of your code. You don't need a resource manager for that.

AMCerasoli
Member #11,955
May 2010
avatar

axilmar said:

You can always create the resource once and then share it amongst all parts of your code. You don't need a resource manager for that.

If you want and unorganized code, and repetitive code all the time, you can do what you say.

isn't the same:

std::list<C_bullet*> bullets;
bullets.push_back(new Fast(&Res_manager));
bullets.push_back(new Blow(&Res_manager));
bullets.push_back(new Vola(&Res_manager));

Than:

#SelectExpand
1ALLEGRO_BITMAP *bullet_img = al_loa... 2ALLEGRO_BITMAP *exp_img = al_loa... 3ALLEGRO_BITMAP *air1_bmp = al_loa... 4ALLEGRO_SAMPLE *snd_blow1 = al_load... 5ALLEGRO_SAMPLE *snd_blow2= al_load... 6ALLEGRO_SAMPLE *snd_fall1= al_load... 7ALLEGRO_SAMPLE *snd_fall3= al_load... 8 9std::list<C_bullet*> bullets; 10bullets.push_back(new Fast(bullet_img, sound_touch, sound_roll, snd_fall3)); 11bullets.push_back(new Blow(bullet_img, exp_img, air1_bmp, snd_blow1, snd_blow2)); 12bullets.push_back(new Vola(air1_bmp, air2_bmp, snd_fall1, snd_fall3)); 13 14al_destroy_bit... 15al_destroy_bit... 16al_destroy_bit... 17al_destroy_sam... 18al_destroy_sam... 19etc...

And those are just ~3 arguments per objects... if they where more would be worse.

Audric
Member #907
January 2001

axilmar said:

Truly object-oriented worlds do not have manager objects. Look around you; do you see any manager object? you don't.

It's a proof that we don't live in an object-oriented world;)

axilmar
Member #1,204
April 2001

If you want and unorganized code, and repetitive code all the time, you can do what you say.

Your example isn't fair. When you are using the resource manager, you are forgetting to tell the resource manager which resources will be needed. Your code should have been like this:

Res_manager.load_bitmap("bullet");
Res_manager.load_bitmap("exp");
Res_manager.load_bitmap("air1");
Res_manager.load_sample("blow1");
Res_manager.load_sample("blow2");
Res_manager.load_sample("fall1");
Res_manager.load_sample("fall2");
Res_manager.load_sample("fall3");

std::list<C_bullet*> bullets;
bullets.push_back(new Fast(&Res_manager, "bullet", "touch", "roll", "fall3"));
bullets.push_back(new Blow(&Res_manager, "bullet", "exp", "air1", "blow1", "blow2"));
bullets.push_back(new Vola(&Res_manager, "air1", "air2", "fall1", "fall3"));

There is little difference between your approach and mine.

Audric said:

It's a proof that we don't live in an object-oriented world;)

But objects is what exists around us.

AMCerasoli
Member #11,955
May 2010
avatar

... Are you crazy? why would I tell the object which resource to load from outside?. The object already know that...

#SelectExpand
1 2class bullet : public C_bullet{ 3 private: 4 ALLEGRO_BITMAP* bm1; 5 ALLEGRO_SAMPLE* sn1; 6 public: 7 bullet(RES_MANAGER *res_manager): 8 bm1 (res_manager->bm_loader("bullet.png")), 9 sn1 (res_manager->sn_loader("sound1.ogg")) 10 {} 11 12 ~bullet(){ 13 res_manager->unneeded_res("bullet.png"); 14 res_manager->unneeded_res("sound1.ogg"); 15 } 16};

And that way all I have to do is just:

bullets.push_back(new bullet(&Res_manager));

axilmar
Member #1,204
April 2001

... Are you crazy? why would I tell the object which resource to load from outside?. The object already know that...

How would you reuse the code then? your bullet example is not reusable code.

Audric
Member #907
January 2001

Sharing code between bullet and another class is irrelevant.

The point of a resource manager is to get a kind of cache, where the first demander of a resource causes the load, and any other demander will be given a reference to the same resource, avoiding a second disk access and uncompress.

(The second demander may be a second instance of "Bullet", or a very different class like the HUD if it uses the same sprites to display ammo)

AMCerasoli
Member #11,955
May 2010
avatar

In the real world objects aren't reusable, at least not this kind of objects. This is the end of the chain, a bullet.

A bullet has its purposes, if you want a big bullet then you would do:

big_bullet : public C_bullet{..

All the rest would be the same, so the reusable code here is C_bullet which has physics functions and variables that are going to be needed by all the kind of bullets... Well at least that's how I see it.

If you want to change just the images used by your big_bullet I would create another object... After all it's another object.

big_black_bullet : public C_bullet{.. // this makes more damage so I change that here
big_red_bullet : public C_bullet{..   // this makes less damage

How to change the physics?, simple:

#SelectExpand
1 2class big_black_bullet : public C_bullet{ 3 private: 4 ALLEGRO_BITMAP* bm1; 5 ALLEGRO_SAMPLE* sn1; 6 public: 7 bullet(RES_MANAGER *res_manager): 8 bm1 (res_manager->bm_loader("bullet.png")), 9 sn1 (res_manager->sn_loader("sound1.ogg")) 10 { 11 12 set_damage(30); // change the damage. 13 14 } 15 16 ~bullet(){ 17 res_manager->unneeded_res("bullet.png"); 18 res_manager->unneeded_res("sound1.ogg"); 19 } 20};

bamccaig
Member #7,536
July 2006
avatar

axilmar said:

Truly object-oriented worlds do not have manager objects. Look around you; do you see any manager object? you don't.

Our world isn't a purely object-oriented world. An object is something "tangible and relatively stable." There are a ton of things in our world that don't fit that description. This post isn't an object in the real world.

There still are "managers" though. The laws of the universe, for example, manage much (everything?) of what happens. We can't actually move in space. We can only operate muscles inside of us that interact with our limbs that interact with our surroundings; our surroundings then push us around. :P

axilmar said:

Not debatable at all, for me. The bitmap knows its internal organization of information, and so the bitmap should be able to load itself from a file.

A bitmap and an image file (even a bitmap file) are two different things. They're very closely related (especially the bitmap file), but they are still distinct.

axilmar said:

There is no problem in throwing exceptions from constructors. If an exception is thrown from a constructor, the destructor of all up to that point constructed objects will be invoked, as if the object was deleted.

Yes, but you are still responsible for cleaning up any non-RAII state that the constructor has done so far. I didn't say that it wasn't possible. I just said it was awkward.

axilmar said:

And throw simplicity out of the window, for no benefit?

There is benefit. It makes more sense. In the real world, an image doesn't do anything. It's a static object. It can be manipulated, but it needs something external to manipulate it. The same is true of most other objects. There are things that the objects themselves can do, but there are also things that can be done with the objects.

The latter is usually the one that we're dealing with. A hammer doesn't pound in nails. A person, for example, pounds in a nail with a hammer. The hammer has attributes that make it good for pounding in nails, but the hammer itself doesn't do anything.

axilmar said:

You can always create the resource once and then share it amongst all parts of your code. You don't need a resource manager for that.

That's what a resource manager does for you. ;) It can potentially do it much easier. But if you're going to be sharing these objects then it's all the better that they be just dumb (preferably immutable) objects.

A bullet should not have functions on it to describe its physics, IMHO. A bullet should just describe the attributes of the bullet itself (and since it does nothing, doesn't really need any functionality). It's a dumb object. It might have a mass, maybe it has a shape, but how it interacts with the world is up to the particular world that its in. :P

AMCerasoli
Member #11,955
May 2010
avatar

bamccaig said:

A bullet should not have functions on it to describe its physics, IMHO. A bullet should just describe the attributes of the bullet itself (and since it does nothing, doesn't really need any functionality). It's a dumb object. It might have a mass, maybe it has a shape, but how it interacts with the world is up to the particular world that its in.

Yes bamccaig, and we're going to spend the rest of our life creating a perfect and completely similar world in which we live on. At the end with 80 years old axilmar is going to have a library of 50.000.000 files, which actually don't do anything, you would need to join 30 classes to make a ball move in the screen... ahahahahaha. I think you went too far body.

class ball : public texture, public material, public molecules, public atoms{..

;D

bamccaig
Member #7,536
July 2006
avatar

You don't have to model every last detail. You only need to model what exists in your world. That doesn't change how they should be manipulated. Usually objects interact with other objects. Sometimes they interact in weird ways with the entire world. If you try to store that in each object then the entire world is going to have to know about the entire world. If you use higher-level managers or service objects then you can centralize this functionality much easier, IMHO.

Ultimately, the language doesn't put any restrictions on you. A method is just a dumb function that gets an implicit argument passed to it. It's up to the programmer to figure out what is appropriate where. Bullet::shoot(Player &) could just as easily be Player::shootWith(Bullet &). So which is it? Both? It could instead be, World::shoot(Player &, Bullet &). The Player doesn't need to know about the Bullet and visa-versa.

_Kronk_
Member #12,347
November 2010

I think I'm finally starting to see the light on all this :) Thanks guys. Up until this point, I've been kind of half-heartedly OOP, but it's obvious now how effective it can be to put more thought into my designs.

A rough outline of my new design:

#SelectExpand
1 2int main() { 3 4 init_allegro(); 5 6 try { 7 8 Game game; 9 game.Run(); 10 11 } 12 13 catch(MyException& e) { 14 15 cout << "Exception: " << e.name << endl << "Cause: " << e.cause << endl; 16 17 } 18 19} 20 21void Game::Run() { 22 23 try { 24 25 ResourceManager resources(cfg file name); 26 ObjectManager objects(cfg file name); 27 Map map(cfg file name); 28 Renderer renderer(); 29 30 if(NeedUpdate()) { 31 32 objects.Update(); 33 34 map.Draw(renderer); 35 objects.Draw(renderer); 36 renderer.FlipBuffer(); 37 38 } 39 40 } 41 42 catch(MyException& e) { 43 44 cout << blah; 45 46 } 47 48}

I'm also going to be working from a RAII standpoint in code as well. I'm kind of stoked. This is going to be much less of a beast to work with than my previous design ;D

--------------------------------------------------
"If only our dreams were fires to ignite, then we could let the whole world burn" -Emery

My blog: http://joshuadover.tumblr.com

axilmar
Member #1,204
April 2001

Audric said:

Sharing code between bullet and another class is irrelevant

Reuse is irrelevant? since when?

Quote:

The point of a resource manager is to get a kind of cache, where the first demander of a resource causes the load, and any other demander will be given a reference to the same resource, avoiding a second disk access and uncompress.

A variable is good enough for this purpose. No need for a cache.

In the real world objects aren't reusable, at least not this kind of objects. This is the end of the chain, a bullet.

In the real world, we should reuse as much code as possible.

Quote:

If you want to change just the images used by your big_bullet I would create another object... After all it's another object.

So if all a class does is change the images, why not have one class and load the images to the object externally using a function? it makes more sense.

bamccaig said:

There still are "managers" though. The laws of the universe, for example, manage much (everything?) of what happens. We can't actually move in space. We can only operate muscles inside of us that interact with our limbs that interact with our surroundings; our surroundings then push us around.

That's not management, that's interactions based on rules.

Quote:

A bitmap and an image file (even a bitmap file) are two different things. They're very closely related (especially the bitmap file), but they are still distinct.

I didn't say otherwise. Still, a bitmap should use the image file internally to load itself from disk. That's proper OO.

Quote:

Yes, but you are still responsible for cleaning up any non-RAII state that the constructor has done so far. I didn't say that it wasn't possible. I just said it was awkward.

That's what smart pointers are for. There is nothing awkward to it.

Quote:

The latter is usually the one that we're dealing with. A hammer doesn't pound in nails. A person, for example, pounds in a nail with a hammer. The hammer has attributes that make it good for pounding in nails, but the hammer itself doesn't do anything.

Then you would need a person object that knows everything. Not good OOP.

Quote:

That's what a resource manager does for you.

And therefore a resource manager is redundant.

Quote:

It can potentially do it much easier.

I've yet to see an example of how a resource manager makes it easier. Anyone care to post one?

Quote:

A bullet should not have functions on it to describe its physics, IMHO. A bullet should just describe the attributes of the bullet itself (and since it does nothing, doesn't really need any functionality). It's a dumb object. It might have a mass, maybe it has a shape, but how it interacts with the world is up to the particular world that its in.

No, that's part of the Bullet subclass, not an external object. The common attributes of bullets belong to the Bullet class, and the particular physics of the world belong to the Bullet subclass.

Yes bamccaig, and we're going to spend the rest of our life creating a perfect and completely similar world in which we live on. At the end with 80 years old axilmar is going to have a library of 50.000.000 files, which actually don't do anything, you would need to join 30 classes to make a ball move in the screen... ahahahahaha. I think you went too far body.

On the contrary, I'd have one Bullet class.

Oscar Giner
Member #2,207
April 2002
avatar

axilmar said:

I've yet to see an example of how a resource manager makes it easier. Anyone care to post one?

Not needing to keep track of duplicate bitmaps accross all yout program manually. Also, the example posted earlier assumes that the resources needed are known at compile time (they're hardcoded). It's also nice that, when entering a new level, the resource manager automatically frees any resource that will not be used by the new map, but keeping the ones that will be used (a lot of games fail at this though, and always unload everything and reload again the needed resources at each map change). How do you do this without a resource manager?

jmasterx
Member #11,410
October 2009

A resource manager can do reference counting on expensive resources like bitmaps.

This way each class that might need a Bitmap just requests it from the RM and the class calls releaseBitmap() once it is destroyed and so resources are never duplicated and only freed when they are no longer needed.

 1   2   3 


Go to: