Using a Class name as a parameter...?

Member
Posts: 22
Joined: 2009.08
Post: #1
**OOPS** Forgot to say: This is Objective-C!

What I'm trying to do is pass in a class's NAME into a parameter for a method call.

-(Game Object *)instanceCreate:(GameObject *)pGameObject atX:(int)pX Y:(int)pY{
GameObject *temp = [[ [pGameObject class] alloc] init];
temp.x = pX;
temp.y = pY;
return temp;
}

So basically I want it to accept the name of any GameObject object, or its subclasses and create an object of GameObject. So if I have bulletObject as a subclass of GameObject, I could pull of something like:
[self instanceCreate:bulletObject, 100, 100];
..and it will create a Bullet object to do whatever I want. It LOOKS like it's working okay, but during the GameObject's init, I define it "x" and "y" as properties. If I do the code in this manner, I get the error:
"Request for member 'x' in something not a structure or a union".

What does it need to look like to work? Thanks!
Quote this message in a reply
Member
Posts: 27
Joined: 2008.12
Post: #2
Do you mean you want to pass in a class, like instanceCreate:[Bullet class] or do you want to pass in an NSString with instanceCreate:@"Bullet" ?

Code:
//passing in a class
instanceCreate:[Bullet class];

-(Game Object *)instanceCreate:(Class)class atX:(int)pX Y:(int)pY{
id temp = [[class alloc] init];
//etc.
}

or

Code:
//passing in an NSString
instanceCreate:@"Bullet"

-(Game Object *)instanceCreate:(NSString*)pClassString atX:(int)pX Y:(int)pY{

Class class = [[NSBundle MainBundle] classNamed: pClassString];
id temp = [[class alloc] init];
//etc.
}

-- Available Now: Dead Panic, a casual zombie shooter!
-- Development Blog: How to make a game under $1k
-- Twitter: xsmasher
Quote this message in a reply
Member
Posts: 22
Joined: 2009.08
Post: #3
While that second implementation yields no errors...
Code:
//passing in an NSString
instanceCreate:@"Bullet"

-(Game Object *)instanceCreate:(NSString*)pClassString atX:(int)pX Y:(int)pY{

Class class = [[NSBundle MainBundle] classNamed: pClassString];
id temp = [[class alloc] init];
temp.x = 100;
temp.y = 100;
//etc.
}

Still gives me those same errors after setting the x and y values. Why is this?
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #4
because "id" doesn't have properties called "x" and "y", like the error message says.
Quote this message in a reply
Member
Posts: 22
Joined: 2009.08
Post: #5
EVERY instance created will be a subclass of GameObject, which contains the "x" and "y" variables, but I want to allocate space for the class called into the parameter.

So how would I be able to set the X and Y values in this function, following the class allocation, since the object of type "id" doesn't contain these values?
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #6
Honestly it sounds like You're Doing This Wrong.

But if you use GameObject* instead of id, you'll tell the compiler that it's always a GameObject, and then you can use .x= and .y= if GameObject defines those as writable properties.
Quote this message in a reply
Member
Posts: 22
Joined: 2009.08
Post: #7
I am probably doing this wrong, but I like to find out the errors the hard way, I guess. It allows me to remember not to make them...!

Cool, so that works wonderfully. A couple more questions.
If I allocate an instance of, for example, the Bullet class such as this...

Code:
GameObject* temp = [[Bullet alloc] init];

and Bullet is a child class of GameObject, will there be any problems when I want to find all the instances of "Bullet" in my game? Will it treat "temp" as a Bullet, or as a GameObject?

And:
Code:
-(GameObject *)instanceCreate:(NSString*)pClassString atX:(int)pX Y:(int)pY{
    
    Class class = [[NSBundle mainBundle] classNamed: pClassString];
    GameObject* temp = [[class alloc] init];
    temp.x = pX;
    temp.y = pY;
    return temp;
}
I'd like to return a reference to temp, but when I change the return type from void to GameObject*, it's giving me a bunch of warnings:
"Expected ')' before 'GameObject' "

But I'm pretty sure my parenthesis are good... no?
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #8
Temp is statically a GameObject, which means the compiler will yell if you try to do something to it that you can't do to a GameObject. It's dynamically a Bullet, though, so if you (for example) send a message to it which GameObject declares and Bullet overrides, you'll get Bullet's implementation.

Just try it Rasp
Quote this message in a reply
Member
Posts: 27
Joined: 2008.12
Post: #9
SamBaylus Wrote:I'd like to return a reference to temp, but when I change the return type from void to GameObject*, it's giving me a bunch of warnings:
"Expected ')' before 'GameObject' "

But I'm pretty sure my parenthesis are good... no?

Yep, your parens are fine - you probably need to import GameObject.h into this file so that the compiler knows what a GameObject is. Then the error will go away.

Cookie, when you say "You're Doing This Wrong" I assume you mean you shouldn't be passing strings around and creating classes from them.

I wouldn't use something like this for saving and restoring game state, or while the game was running. I can see a case for this when creating levels or events based on a file, though; how else would you do that other than a giant switch statement? The switch statement is safer, but tedious to maintain.

-- Available Now: Dead Panic, a casual zombie shooter!
-- Development Blog: How to make a game under $1k
-- Twitter: xsmasher
Quote this message in a reply
Member
Posts: 22
Joined: 2009.08
Post: #10
smasher Wrote:...
Cookie, when you say "You're Doing This Wrong" I assume you mean you shouldn't be passing strings around and creating classes from them.

I wouldn't use something like this for saving and restoring game state, or while the game was running.
...

I actually AM using this while the game is running. Well. Sort of. In ANY instance, I want to be able to create another instance of another object during runtime. By using a define functions instead of a method call just to keep it nice and neat looking:
instanceCreate(instanceName, x, y);
I can pass in the instanceName as a string, and provide and x and y to start the object out, and it'll also call code for all the init values and whatnot. I'm sure there's a much better way of doing this, but like I said before; it's a learning process.

**ALSO** I did import GameObject, but strangely enough the error went away from I changed my import classes from my .h to my .m. I'm not sure why this is, but now it works perfectly without errors. Hmm.
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  Forcing template parameter type Fenris 4 3,528 Jan 4, 2008 07:03 AM
Last Post: TomorrowPlusX