m_callback size

Started by starkhorn, 30 June 2015, 02:11:12

starkhorn

Hi Texus,

Sorry for another question......I have a few radio buttons and each radio button has it's own callback ID. Within my gui.pollCallback(callback) function, I check if the radio callback id is the one. Then I return true from the function...so basically I'm jumping out of the gui.pollCallback loop early here.

However I've realized that when i next call that pollCallback function, the radio button callback ID is still triggered. EVentually I realized that the gui.m_callback size is usually has 3-400 callback IDs...all of them the ID of the radio button. I'm not sure how/why this is the case?

Anyway, I wrote the below to clear out the m_callback queue when I no longer want to check for new events.

Code (cpp) Select

void drawEngine::clearCallBackQueue()
{
while (gui.pollCallback(callback))
{

}
}


I was wondering if there was any way to add a gui.m_callback.clear() instead as it would be a little faster? I cannot do that as m_callback is a private parameter.

texus

Sorry for my answer comes over a bit harsh, I had written a slightly longer version but I accidentally refreshed the page and I lost it.

I won't be adding a clear function, I don't see any use case for it. You shouldn't be clearing the list since you throw away callbacks like that without even checking what they are. But if you really need to clear it then you should just keep the while loop that you have now.

The callback is removed before the pollCallback returns, so if there are callbacks left in the queue when you jump out of the loop then there must have been multiple to begin with. Are you sure you didn't accidentally give the other radio buttons the same id? Are you binding multiple triggers on the radio button? Perhaps you let it send a callback on both clicked and mouse pressed but only handle one while the other still remains in the queue?

starkhorn

No problem at all about being harsh and point taken that there isn't a valid use-case for it. I guess I was doing a hack for something else that I was doing incorrect.

I think you might have hit the nail on the head when you said

Code (cpp) Select

Are you sure you didn't accidentally give the other radio buttons the same id? Are you binding multiple triggers on the radio button?


I'm definitely not giving the other radio buttons the same id. I'm binding as below so you see each radio button within the radiobuttonlist vector is getting bound to the counter from the for loop.

Code (cpp) Select


void Test::initRadioButtonCallbacks()
{
for (int i = 0; i < RadioButtonList.size(); i++)
{
RadioButtonList[i]->setCallbackId(i);
RadioButtonList[i]->bindCallback(tgui::Button::LeftMouseClicked);
}
}



However, I'm calling the initRadioButtonCallbacks function each time I draw the menu, so I'm wondering if the multiple callback is what I am doing incorrectly. I did a few tests with some simple code - (see below if you wanted to copy/paste a full simple example).

When I have the initRadioButtonCallbacks outside the while gamewindow isOpen loop, then m_callback size is always zero when I press on a radiobutton. However say I put this with the while window isOpen loop (to simulate me calling it each time I draw a submenu), then the m_callback is very large.

So my question I guess becomes, does the bindCallback not overwrite the previous callbackID?

Code (cpp) Select


#include <TGUI/TGUI.hpp>
#include <string>
#define THEME_CONFIG_FILE "E:/programming/TGUI-0.6/widgets/Black.conf"

using namespace std;

class Test
{
public:

Test();

sf::RenderWindow gameWindow;
sf::VideoMode desktop;
sf::Event event;
tgui::Callback callback;
tgui::Gui gui;
vector<tgui::RadioButton::Ptr> RadioButtonList;

void initRadioButtonCallbacks();
void setupRadioButton(int passed_numWidgets, int maxNumWidgets,  sf::Color passed_colour, vector<string> stringList);
};

Test::Test()
{
desktop = sf::VideoMode::getDesktopMode();
gameWindow.create(sf::VideoMode(desktop.width * 0.5, desktop.height * 0.50, desktop.bitsPerPixel), "Test");
gameWindow.setPosition(sf::Vector2i(0, 0));
gui.setWindow(gameWindow);
}

void Test::setupRadioButton(int passed_numWidgets, int maxNumWidgets, sf::Color passed_colour, vector<string> stringList)
{
int listPreSize = RadioButtonList.size();
int listNewSize = passed_numWidgets + RadioButtonList.size();
int strListIndex = 0;
sf::Vector2i initPos(50,0);
sf::Vector2i initSize(25,25);

while (RadioButtonList.size() < listNewSize && RadioButtonList.size() < maxNumWidgets)
{
RadioButtonList.push_back(tgui::RadioButton::Ptr(gui));
}

int yposIncrementer = 0;

for (int i = listPreSize; i < RadioButtonList.size(); i++)
{
RadioButtonList[i]->load(THEME_CONFIG_FILE);
RadioButtonList[i]->setPosition(initPos.x, (initPos.y + yposIncrementer));
RadioButtonList[i]->setSize(initSize.x, initSize.y);
RadioButtonList[i]->setTextColor(passed_colour);
if (stringList.size() > 0)
{
RadioButtonList[i]->setText(stringList[strListIndex]);
}
yposIncrementer += initSize.y;
strListIndex++;
}
}

void Test::initRadioButtonCallbacks()
{
for (int i = 0; i < RadioButtonList.size(); i++)
{
RadioButtonList[i]->setCallbackId(i);
RadioButtonList[i]->bindCallback(tgui::Button::LeftMouseClicked);
}
}

int main()
{
Test testClass;
vector<string> widgetStrList;

//Do the radio buttons
widgetStrList.push_back("\tLow");
widgetStrList.push_back("\tNormal");
widgetStrList.push_back("\tHigh");

testClass.setupRadioButton(3, 3, sf::Color::Red, widgetStrList);
testClass.initRadioButtonCallbacks();

while (testClass.gameWindow.isOpen())
{

while (testClass.gameWindow.pollEvent(testClass.event))
        {
if (testClass.event.type == sf::Event::Closed)
{
testClass.gameWindow.close();
}

testClass.gui.handleEvent(testClass.event);
}



        while (testClass.gui.pollCallback(testClass.callback))
        {
if (testClass.callback.id == 0)
            {
int test = 0;
}
else if (testClass.callback.id == 1)
{
int test = 1;
}
else if (testClass.callback.id == 2)
{
int test = 2;
}
        }

testClass.gameWindow.clear(sf::Color::White);
        testClass.gui.draw();
        testClass.gameWindow.display();
}

return 0;
}








starkhorn

Ok so I changed my initcallback function to below.....and had it run in the while gamewindow is open loop.  Now the m_callback size is zero whenever I click on a radiobutton.

So yeah clearly I should unbind first before rebind callbacks within the game loop. Right?

Code (cpp) Select


void Test::initRadioButtonCallbacks()
{
for (int i = 0; i < RadioButtonList.size(); i++)
{
RadioButtonList[i]->unbindAllCallback();
RadioButtonList[i]->setCallbackId(i);
RadioButtonList[i]->bindCallback(tgui::Button::LeftMouseClicked);
}
}


texus

Yeah, the bindCallback function adds callback functions, addCallbackFunction would perhaps have been a better name. Adding instead of replacing the existing one allows multiple callback functions to be bound for the same callback.

Instead of unbindAllCallback you can also do unbindCallback(tgui::Button::LeftMouseClicked), this doesn't clear callback functions that were bound to other triggers. But in your code it probably doesn't matter since you only use LeftMouseClicked.

For RadioButtons, you could use the Checked event instead of LeftMouseClicked, unless you need a callback again when clicking on a radio button that was already checked.

starkhorn

Hi Texus,

Ok thanks again for your help and sorry it took me a while to figure this out....I'm trying to learn c++, sfml and tgui as I go. :) I really do appreciate you continued assistance and patience with my constant questions.