subscribeEvent and arguments

For help with general CEGUI usage:
- Questions about the usage of CEGUI and its features, if not explained in the documentation.
- Problems with the CMAKE configuration or problems occuring during the build process/compilation.
- Errors or unexpected behaviour.

Moderators: CEGUI MVP, CEGUI Team

ravak_
Just popping in
Just popping in
Posts: 2
Joined: Mon Mar 21, 2011 11:53

subscribeEvent and arguments

Postby ravak_ » Mon Mar 21, 2011 12:02

I am working on a turn-based strategy game using a grid interface to control the units (ala Advance Wars, Civilization). All told, I have three hundred tiles available for the user to click on. I have a two-dimensional array to track where the units are, and when I click on one of the tiles with a unit on, I want to be able to start issuing various commands.

Each tile is implemented using the following function:

Code: Select all

void TutorialApplication::createTile(int x, int y, CEGUI::Window *parent) {
   CEGUI::WindowManager &wgmr = CEGUI::WindowManager::getSingleton();
   Ogre::String s = Ogre::String("(" + Ogre::StringConverter::toString(x) + ", " + Ogre::StringConverter::toString(y) + ")");

   CEGUI::Window *w = wgmr.createWindow("DefaultWindow", s);
   w->setPosition(CEGUI::UVector2(CEGUI::UDim((x-1)/20.0f, 0), CEGUI::UDim((y-1)/15.0f, 0)));
   w->setSize(CEGUI::UVector2(CEGUI::UDim(0.05f, 0), CEGUI::UDim(0.0666f, 0)));
   w->setText(s);
   w->subscribeEvent(CEGUI::PushButton::EventClicked, CEGUI::Event::Subscriber(&TutorialApplication::overlayTileClick, this));

   parent->addChildWindow(w); }


The problem is I can't determine what tile I clicked using the subscribeEvent() function. I was hoping that I could do something like this...

Code: Select all

w->subscribeEvent(CEGUI::PushButton::EventClicked, CEGUI::Event::Subscriber(&TutorialApplication::overlayTileClick(x, y), this));

...but then I get a lovely C2661 error: 'CEGUI::SubscriberSlot::SubscriberSlot' : no overloaded function takes 2 arguments

Is it possible to add arguments in this way, so I can determine what tile has been selected? Or is there another / better way to implement what I'm looking for - that is, a way to know what tile was clicked.

Thanks,
-- Rav

IrmatDen
Not too shy to talk
Not too shy to talk
Posts: 26
Joined: Sat Feb 26, 2011 08:04

Re: subscribeEvent and arguments

Postby IrmatDen » Mon Mar 21, 2011 12:54

Hi,

To extract the tile, you might consider storing a vector<TileDef*> in your class, where TileDef is a struct defining the tile's content (currently, the position only). Then set the Window's userdata pointer to the matching TileDef instance; something like this:

Code: Select all

struct TileDef {
   int x, y;
};
typedef std::shared_ptr<TileDef> TileDefPtr;

typedef std::vector<TileDefPtr> GameTilesContainer;
GameTilesContainer gameTiles;

void TutorialApplication::buildGameTiles() {
   gameTiles.swap(GameTilesContainer());
   gameTiles.reserve(endX * endY);

   TileDefPtr tile;
   for (int x = 0; x != endX; x++)
   {
      for (int y = 0; y != endY; y++)
      {
         tile = TileDefPtr(new Tile(x, y));
         gameTiles.push_back(tile);
      }
   }
}

void TutorialApplication::createTile(int x, int y, CEGUI::Window *parent) {
   CEGUI::WindowManager &wgmr = CEGUI::WindowManager::getSingleton();
   Ogre::String s = Ogre::String("(" + Ogre::StringConverter::toString(x) + ", " + Ogre::StringConverter::toString(y) + ")");

   assert(x < endX);
   assert(y < endY);
   TileDefPtr matchingTile = gameTiles.at(x * endX + y);

   CEGUI::Window *w = wgmr.createWindow("DefaultWindow", s);
   w->setPosition(CEGUI::UVector2(CEGUI::UDim((x-1)/20.0f, 0), CEGUI::UDim((y-1)/15.0f, 0)));
   w->setSize(CEGUI::UVector2(CEGUI::UDim(0.05f, 0), CEGUI::UDim(0.0666f, 0)));
   w->setText(s);
   w->setUserData(matchingTile.get());
   w->subscribeEvent(CEGUI::PushButton::EventClicked, CEGUI::Event::Subscriber(&TutorialApplication::overlayTileClick, this));

   parent->addChildWindow(w);
}


Then, make your overlayTileClick takes no arguments, except for the WindowEventArgs&. From the args received, get the event's source Window pointer by casting EventArgs to WindowEventArgs, and extract the TileDef pointer with Window::getUserData.

Two side-related things though:
1. You're suscribing to the wrong argument: your window is a CEGUI::Window, not a CEGUI::PushButton. You want to suscribe to Window::EventMouseClick
2. I really am not convinced that using CEGUI Windows to represent tiles is efficient. You have a lot of useless overhead for a tilemap.

User avatar
Kulik
CEGUI Team
Posts: 1382
Joined: Mon Jul 26, 2010 18:47
Location: Czech Republic
Contact:

Re: subscribeEvent and arguments

Postby Kulik » Mon Mar 21, 2011 13:06

You can use either boost::bind or something similar to bind the 2 arguments or just use WindowEventArgs::window to figure out what windows has been clicked.

ravak_
Just popping in
Just popping in
Posts: 2
Joined: Mon Mar 21, 2011 11:53

Re: subscribeEvent and arguments

Postby ravak_ » Mon Mar 21, 2011 13:18

Potentially realised in the interim that I don't need three hundred tiles, nor do I need to track their location. Using a single window, I can just get the position of mouse, and calculate what tile I'm clicking on from there. I think this potentially answers the second point IrmatDen made.

As for the first point, thank you. I was wondering why I wasn't getting much of a response.

IrmatDen
Not too shy to talk
Not too shy to talk
Posts: 26
Joined: Sat Feb 26, 2011 08:04

Re: subscribeEvent and arguments

Postby IrmatDen » Mon Mar 21, 2011 13:37

ravak_ wrote:Potentially realised in the interim that I don't need three hundred tiles, nor do I need to track their location. Using a single window, I can just get the position of mouse, and calculate what tile I'm clicking on from there. I think this potentially answers the second point IrmatDen made.

Since you're using Ogre, I would use either of those solutions of derive the (x,y) tile coord the user clicked:
* a simple invisible plane at world level 0
* the level mesh
(It all depends on how you're planning your game to appear, like, if you have interactive high mountains or deep "holes" (ocean, canyons etc...), the first solution might not fit the user's expectations.)


Return to “Help”

Who is online

Users browsing this forum: No registered users and 8 guests