Keying a value to a class

Started by
6 comments, last by ApochPiQ 12 years ago
So I'm writing a relatively simple state manager, it has a single member pointer to a base State class and a ChangeState function. Changestate(in a perfect world) checks if the new state is the same as the current one and disregards it, then it tells the pointed to object to clean itself up and then deletes it, that's all fine and dandy. The question I have is when I get to creating the new state, right now I'm using an enum for the list of states(declared in the header) so to create simplicity one would just have to edit the list to add/remove states.

Problem is when I get to the actual creating a new object for the game state, I would prefer not to use a switch or if/else block because that would mean having to hardcode each class to create, depending on what the function receives as a paramater. I'm wondering if there's a better way to implement this or a way to create a "key" or something I could pass to the function and then it simply uses that as a basis for which class to create with the pointer.

Is there an elegant way to do this?
Advertisement
You're thinking of the problem inside out.

Don't ask the state system to create a new state for you; create a new state object directly when you know you need one and then pass that to ChangeState to make it active.

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]


You're thinking of the problem inside out.

Don't ask the state system to create a new state for you; create a new state object directly when you know you need one and then pass that to ChangeState to make it active.

I actually was considering that method earlier but I think the reason I didn't go with it right away was because I felt like it removed any checks I could do against the object I was passing. For instance, what if I'm passing an object of the same class(for some reason) and want to interrupt that? Alternatively if I change to have an array of state pointers(to keep multiple states alive/paused/etc) I'd need to be able to check if the array contained a duplicate of a certain class. Theoretically I could give states ID's themselves to compare against or use something like instanceof from Java, but that all seemed just another version of ugly compared to what I'm doing currently.
Sorry, I guess I wasn't clear enough.

You don't pass a State constantly, like every frame. You only pass a State when the state needs to change. The concrete derived class of the state becomes irrelevant, because you only invoke the creation of a new state when you actually need to. As for managing multiple states, you might find a stack much more appropriate than a plain array; only one state is active at a time, after all, and you can simply Pause() a state when it is no longer the top of the stack and Resume() it when it comes back up to the top.

Generally speaking, if you're writing code that has to know the class of an object, you've done something horribly wrong.

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]


You don't pass a State constantly, like every frame. You only pass a State when the state needs to change.

I got that part, what I did before was have a vector of pointers and would just create a new state and pass it to changestate, then it'd push a new pointer to the passed state in. I had some problems with that but I guess that isn't really relevant to what I'm deciding right now.

As for managing multiple states, you might find a stack much more appropriate than a plain array;

I was just using "array" as a general term for storage, obviously a vector, map, or anything else could work better than a plain array.

I guess what I was getting at with the whole thing was making it abstract to the point where you can shove a game state object in it then manipulate it without having to worry about what the statemanager was actually doing. I guess you're kinda saying I should just do what I did before and just ignore any sort of "duplicate" checking of states on the stack, and just make people pop the prior state or else deal with duplicates themselves. I was trying to make it "idiot proof."

Although I guess I could still do that utilizing ID's assigned to each state or something.
So you want to prevent the programmer from doing this?

StateManager.PushState(new HighScoresState());
StateManager.PushState(new HighScoresState());
StateManager.PushState(new HighScoresState());


Trying to make your interface hard to abuse is good, but only to a point. Eventually you will reach a tradeoff where you're doing extreme contortions to try and eliminate stupidity, but people can still do stupid things if they really try hard enough. It really comes down to making a decision as to how much effort you want to invest in designing your system, because at the end of the day, someone will be able to do the wrong thing with it.

And it'll be frighteningly easy to do that wrong thing, no matter how much work you put into making it impossible.

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]


So you want to prevent the programmer from doing this?

StateManager.PushState(new HighScoresState());
StateManager.PushState(new HighScoresState());
StateManager.PushState(new HighScoresState());


Trying to make your interface hard to abuse is good, but only to a point. Eventually you will reach a tradeoff where you're doing extreme contortions to try and eliminate stupidity, but people can still do stupid things if they really try hard enough. It really comes down to making a decision as to how much effort you want to invest in designing your system, because at the end of the day, someone will be able to do the wrong thing with it.

And it'll be frighteningly easy to do that wrong thing, no matter how much work you put into making it impossible.

Yeah that makes sense, have to give in at some point I suppose.

Although I kinda hit a new snag, realization hit me that I have to be able to change the state from within another state, but you can't exactly delete a state in the middle of it, suppose I'll have to set it to switch on the next iteration of the game loop or something.
shared_ptr is your best friend :-)

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

This topic is closed to new replies.

Advertisement