Jump to content
  • Advertisement
Sign in to follow this  

C++ - a class, a void* and a new object

This topic is 4773 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I have a function in a class like so (this is a trivial example but my real project has a purpose for the void pointers)
bool Monster::DataResponse( int messageType, void *messageValue )
{
  // return units x and y position in the messageValue pointer
  point *unitPosition = new point; // ToDo: delete
  point->x = xPos;
  point->y = yPos;
  messageValue = (void*)point;
  return true;
}
Now when the program calls this DataResponse function from another class and casts the messageValue back into a point the x and y values are not what is expected Why?

Share this post


Link to post
Share on other sites
Advertisement
There are better ways to do this, but the direct answer to your question is that you aren't storing anything into messageValue. You would need something like this, instead:


bool Monster::DataResponse( int messageType, void **messageValue ) // note the '**' (pass in the address of messageValue)
{
// return units x and y position in the messageValue pointer
point *unitPosition = new point; // ToDo: delete
point->x = xPos;
point->y = yPos;
*messageValue = (void*)point; // note the '*' (store point at the address pointed to by messageValue)
return true;
}

Share this post


Link to post
Share on other sites
Pass a reference: void *&messageValue. Otherwise you're just changing a copy; the original pointer that the calling code used is still the old value.

Also, what is this purpose for the void pointers? I don't believe you.

Share this post


Link to post
Share on other sites
Quote:
Original post by smart_idiot
Also, what is this purpose for the void pointers? I don't believe you.


In case he wanted to do something like this [grin] Hides in corner

Share this post


Link to post
Share on other sites
Thanks all i got it.

Quote:
Original post by smart_idiot
Also, what is this purpose for the void pointers? I don't believe you.


I need to pass data back to the parent class but that data is different for every monster.

ie. all game objects derive from a base class (funnily enough called GameObjectBase)

This has common functions like Draw (all game objects are renderable in this game) and Animate (steps forwards a frame). All the derived game objects are stored in a vector so i can just call (psuedocode)
for all elements of the vector
{
Animate
Draw
}



Now there comes the problem of input, some objects respond to keyboard input some only to mouse some to both and most objects return data that is valid only to them (the hero for example returns a display inventory message along with a pointer to his inventory when clicked).
I want to make the game so that when i get a mouse click i can go


messageType = MOUSE_CLICK;
messageValue = point;
for all elements of the vector
{
if ( object.DataResponse( &messageType , messageValue ) // true if object was the one clicked
{
if ( messageValue != NULL )
processResponse( &messageType , messageValue ); // a function that does the returned request
break;
}
}


That way all objects can still inherit the one base class (easier for rendering) despite the differences in the way they respond to the different types of input.



If you can think of a better way of doing this without voids then tell me :)

Edit: my topmost example should have had int *messageType as a parameter so that i can pass a different messageType back again.

[Edited by - Pacifist on April 26, 2005 10:08:02 PM]

Share this post


Link to post
Share on other sites
ewww...

I use functors for this. [though ironically enough, the functor class I've used for all my gui-stuff in the past stores the parameters in the void* heterogeneous semi-templated linked list class....]

Essentially...

[though please please someone correct me if the STL adapaters allow for better functor goodness...]

[and sorry for the length; I need the practice]



struct action{
void operator()()=0;
virtual ~action(){}
};

template <typename T>
struct global_action:public action{
T t;
void operator()(){
t();
}
global_action(T &some_action):t(some_action){}
};

template <typename F>
action *make_global_action(F f){
return(global_action<F>(f));
}


struct keybinding{
keycode key; // define keycodes somewhere...
action *bound_action;

void activate(){
if (bound_action){
(*bound_action)();
}
}
bool match(keycode k){
if (k==key){
return(true);
}else{
return(false);
}
}
keybinding(keycode k, action *inaction):key(k),bound_action(inaction){}
~keybinding(){delete bound_action;}
};

// And similar for mousetargets!

struct GameObjectBase{
vector<keybinding> kbinput; // or, use a fixed array or map
// if you expect this to be
// usually full.
mouse_target onleftclick;
mouse_target onrightclick;

virtual void animate();
virtual void render();
// stuff!
};





Then, you just need to figure out which object takes the input, and activate the bound functor. For the hero example, the hero should post the message "open hero_inventory here" [to a queue where it's later picked up] from the bound function, not return it.

In the way I've done it in the past that is...

Eh. That's a terrible example. Something like that...

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
I'm reading up on functors now although it seems way more complex than the way i do it.

My way i have all game objects in a vector which is inside the main game class.
Then i send the mouse events to all those objects to find what object was clicked.

Then if the object returned a message such as SHOW_INVENTORY in messageType i create a new InventoryDisplay object in that vector with messageValue(a void*) pointing to the inventory items.
However if the object returned a message such as SHOW_STATS in messageType i create a new StatsDisplay object with messageValue pointing to the stats.

See the above stuff is my problem, the objects themselves are the ones that decide what to request/return if they have been clicked. The hero doesn't always return show inventory on a mouse click and a monster doesn't always return show stats on a mouse click. If the monster is dead for example i'd prefer the monster to display an inventory screen rather than a stats screen when he is clicked, with my way he can easily do this.

So i can't really bind an open inventory function to the hero object, the hero object itself needs to determine what to request from the main class in the returned values.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!