Author Topic: How to do this?  (Read 34141 times)

Krice

  • (Banned)
  • Rogueliker
  • ***
  • Posts: 2316
  • Karma: +0/-2
    • View Profile
    • Email
How to do this?
« on: March 29, 2008, 02:38:34 PM »
I have a Window class using graphics from Tileset class instance. I'm initializing the graphics when the program starts, but I'm wondering is there a way to initialize graphics once using only Window class (constructor) itself, so you wouldn't have to rely on external initialization and could use Window class independently (and place it in class library). I'm programming in C++.

Anvilfolk

  • Rogueliker
  • ***
  • Posts: 374
  • Karma: +0/-0
    • View Profile
Re: How to do this?
« Reply #1 on: March 29, 2008, 05:08:45 PM »
I'm not really sure I understand what you're saying... what I'm guessing is that you programmed the Tileset class and the Window class separately, but now want them to interact without having to explicitly use and call Tileset's methods, is that it?

Not understanding what you want fully, I can only guess, but I'd make the Tileset class have a binary state of "loaded" or "not loaded". Then, all the Window constructor needs to do is ask for the state of the Tileset and ask it to load everything it needs if it hasn't already been done.

This assumes that the Tileset class knows what it's supposed to load... and the information might be stored in a more general class, like a resource manager, who reads it from an initialization file or somesuch. Or you can just shove it all into the Tileset's instances, which might make it a little less organized, but meh...

Also... do you plan on having a lot of Tilesets at the same time? You might want to make that Tileset a singleton, it makes accessing it much easier. You can typedef the static calls Tileset::get_instance() to something shorter to type and it works like a charm!
"Get it hot! Hit it harder!!!"
 - The tutor warcry

One of They Who Are Too Busy

Krice

  • (Banned)
  • Rogueliker
  • ***
  • Posts: 2316
  • Karma: +0/-2
    • View Profile
    • Email
Re: How to do this?
« Reply #2 on: March 29, 2008, 05:50:54 PM »
but I'd make the Tileset class have a binary state of "loaded" or "not loaded". Then, all the Window constructor needs to do is ask for the state of the Tileset and ask it to load everything it needs if it hasn't already been done.

That doesn't sound good. How Tileset instance can know its state when it's not yet even constructed? If you need to construct it elsewhere then it's breaking the rule of independency.

Anvilfolk

  • Rogueliker
  • ***
  • Posts: 374
  • Karma: +0/-0
    • View Profile
Re: How to do this?
« Reply #3 on: March 29, 2008, 06:25:58 PM »
Right... so you don't want to touch the Tileset class with a ten foot pole ;)

Well, I'm not sure what your Window class is all about. In any case, you'll have to store information about where the tile image files are - it shouldn't really be directly in the Window class, so I'm going to assume you've got some class which stores that information. Like I said, a resource/preference manager might do the trick. If you don't plan on having several profiles, I'd suggest using the singleton pattern - or use the pattern and make it support several profiles.

If you're only going to have one tileset, I don't really see what the problem is. I'm probably not imagining the problem correctly.

Somehow, your resource manager is going to know which one is the tileset-info, right? Either by inner data - or maybe he handed out an identifier when he loaded the tileset and whomever holds it knows what it is - or maybe you can get it through a method call with "tileset" as an argument. Why doesn't the Tileset constructor simply either get passed that descriptor or just get the information out of the resource manager and load it in it's constructor or on a separate load() method?
"Get it hot! Hit it harder!!!"
 - The tutor warcry

One of They Who Are Too Busy

Krice

  • (Banned)
  • Rogueliker
  • ***
  • Posts: 2316
  • Karma: +0/-2
    • View Profile
    • Email
Re: How to do this?
« Reply #4 on: March 30, 2008, 07:27:29 AM »
and load it in it's constructor or on a separate load() method?

Because there are several instances of Window class, of course. If the external window data would be loaded in the constructor then there would be multiple graphics tiles (actually the borders of window in this case) loaded in memory when more than one Window class instance is made. Slow and inefficient.

corremn

  • Rogueliker
  • ***
  • Posts: 700
  • Karma: +0/-0
  • SewerJack Extraordinaire
    • View Profile
    • Demise RogueLike Games
Re: How to do this?
« Reply #5 on: March 30, 2008, 10:48:24 AM »
and load it in it's constructor or on a separate load() method?

Because there are several instances of Window class, of course.

Of course that was so obvious. 

Make it a static class.
corremn's Roguelikes. To admit defeat is to blaspheme against the Emperor.  Warhammer 40000 the Roguelike

Krice

  • (Banned)
  • Rogueliker
  • ***
  • Posts: 2316
  • Karma: +0/-2
    • View Profile
    • Email
Re: How to do this?
« Reply #6 on: March 30, 2008, 05:23:47 PM »
Make it a static class.

What's that?

corremn

  • Rogueliker
  • ***
  • Posts: 700
  • Karma: +0/-0
  • SewerJack Extraordinaire
    • View Profile
    • Demise RogueLike Games
Re: How to do this?
« Reply #7 on: March 30, 2008, 11:07:23 PM »
Make it a static class.

What's that?

Sorry I dont really know what you want.

You want a multiple windows class instances and you want the window class to initialise the tileset class, but you only want one instance (in memory) of the tileset class??

Below is some code that will do the following, however there are a few other ways to do this.
 Disclaimer: My c++ knowledge is not always the best.

#include "tileset.h"
class Window
{
public:
   Window ();

       static Tileset   tileset; //one and only one instance ever
}

in window.cpp

#include "window.h"
Tileset   WorldBuilder::tileset; //here it is intialised/constructed once and only once

Window::Window ()
{
       if(tileset.IsInitialised())       //dont really need this code if you init it in its constructor
              tileset.Initialised();
}


//out side windows code you access the tileset like this

main()
{
          Window w1,w2;
       w1::tileset.doStuff(); //w1::tileset and w1::tileset should be the same thing
       w2::tileset.doMoreStuff();

}
corremn's Roguelikes. To admit defeat is to blaspheme against the Emperor.  Warhammer 40000 the Roguelike

Anvilfolk

  • Rogueliker
  • ***
  • Posts: 374
  • Karma: +0/-0
    • View Profile
Re: How to do this?
« Reply #8 on: March 31, 2008, 01:54:15 AM »
Just to be whiny and annoying, but that's not a static class, it's a static member.

You can't really declare static classes per se, but you can create a class where all members and methods are declared as static, thus fulfilling the "static class" idea. This is one way to implement the Singleton Pattern. The other one you can easilly see through the Java implementation on that page.

If you're ever only going to have a single instance of that Tileset class, again, this is a good way to go. It will be accessible just about anywhere in your program, so you'll have no problem at all doing what you wanted, if the data-loading information is already kept within the Tileset class or the resource manager (which could also be a singleton, heh).

Good luck!

P.S. I just realized how patronizing this post was. Let me also add a disclaimer:
I'm only 22 and a 3rd year Computer Science student. I do not have all the answers to the universe, and the one I proposed here might be completely wrong - but I hope not.
« Last Edit: March 31, 2008, 01:58:26 AM by Anvilfolk »
"Get it hot! Hit it harder!!!"
 - The tutor warcry

One of They Who Are Too Busy

Krice

  • (Banned)
  • Rogueliker
  • ***
  • Posts: 2316
  • Karma: +0/-2
    • View Profile
    • Email
Re: How to do this?
« Reply #9 on: March 31, 2008, 09:57:09 AM »
It will be accessible just about anywhere in your program, so you'll have no problem at all doing what you wanted, if the data-loading information is already kept within the Tileset class or the resource manager (which could also be a singleton, heh).

How is this different from just using a global instance of a class, which I'm now using?

Anvilfolk

  • Rogueliker
  • ***
  • Posts: 374
  • Karma: +0/-0
    • View Profile
Re: How to do this?
« Reply #10 on: March 31, 2008, 04:17:56 PM »
It assures that there will never, ever be more than once instance of that class. If I, or anyone, were to pick up your code, you could never guarantee that we wouldn't create another instance, which might break the application. Granted, the possibility is rather remote, but on big projects with lots of people, one may never know. Besides, it's always good to learn new things!

On another note, I believe there are some weird, obscure bugs you might get while trying if you're ever using the Tileset type in arguments and stuff - related to copy-constructors and default constructors and the like. The fact that all your constructors are private will generate a compile-time error which might save you a lot of headaches.

And finally, and this is a bit personal, but everything should have its place - "but the global namespace ain't it". I mean, where does it stop? You can shove a LOT of variables into the global namespace... that doesn't mean you should, it's that's a principle of OOP.

Ultimately it's up to you, of course, but if Kaduria is going to be as big and complex as you say, maybe this kind of stuff will save you some time in the end - in one way or another.
"Get it hot! Hit it harder!!!"
 - The tutor warcry

One of They Who Are Too Busy

corremn

  • Rogueliker
  • ***
  • Posts: 700
  • Karma: +0/-0
  • SewerJack Extraordinaire
    • View Profile
    • Demise RogueLike Games
Re: How to do this?
« Reply #11 on: April 01, 2008, 12:38:57 AM »
Just to be whiny and annoying, but that's not a static class, it's a static member.

I should of been more specific, it is a static instance of a class declared in a class, hence a static member.  I though that would be easier to decribe than singletons, better that messy-every-things-static classes and classier than globals. I believe he is C++ self taught so I went the simpler solution, while still OO.  But Krice does seem to want perfection doesn't he?

P.s On a side note, there is nothing wrong with globals, I dont care what lecturers tell you.  They work, they are simple and easy to use.  Whats the harm?  Bad use of global variables means bad coding, which means you are a bad coder in the first place, right?  I dont use them myself, except when I am very lazy, but why do people think they are evil. So they dont fit the OOP, whoopy do.
corremn's Roguelikes. To admit defeat is to blaspheme against the Emperor.  Warhammer 40000 the Roguelike

Anvilfolk

  • Rogueliker
  • ***
  • Posts: 374
  • Karma: +0/-0
    • View Profile
Re: How to do this?
« Reply #12 on: April 01, 2008, 06:31:19 PM »
Quote
I should of been more specific, it is a static instance of a class declared in a class, hence a static member.  I though that would be easier to decribe than singletons, better that messy-every-things-static classes and classier than globals. I believe he is C++ self taught so I went the simpler solution, while still OO.  But Krice does seem to want perfection doesn't he?

Point taken :)



I don't think I could ever declare a global variable like that, not anymore! Most of my coursework is Java (not something I totally agree with), so it's not even possible to do. It can tie you up sometimes, but it's such a clean language that after awhile I just got a desire to use C++ the same way that I do Java :)

However, C++ is starting to get pretty outdated, many things could be improved upon. You wouldn't know of another OO language that compiles to actual machine code, but that works and codes smoother (I still shudder at some of the compile errors I used to get)?
"Get it hot! Hit it harder!!!"
 - The tutor warcry

One of They Who Are Too Busy

gerryq

  • Newcomer
  • Posts: 6
  • Karma: +0/-0
    • View Profile
Re: How to do this?
« Reply #13 on: May 13, 2008, 03:14:15 PM »
You shouldn't have too many globals (or semi-globals - an object instantiated in your main application function such as a CWinApp-derived class is global in all but name).  But for a game where you know there will be just one of particular kinds of things (e.g. the game output window), there's really no harm in using a few.

fecal_brunch

  • Newcomer
  • Posts: 5
  • Karma: +0/-0
    • View Profile
    • Email
Re: How to do this?
« Reply #14 on: June 21, 2008, 09:32:19 AM »
Quote
However, C++ is starting to get pretty outdated, many things could be improved upon. You wouldn't know of another OO language that compiles to actual machine code, but that works and codes smoother (I still shudder at some of the compile errors I used to get)?

D looks interesting, I'm not going to try it just yet, but I want to as soon as possible... I think I should become better aquainted with c++ before I go changing my focus.

http://www.dprogramming.com/