Bug with Controller

Maverick

19-02-2009 14:47:40

Hi folks,

This is my first post to this forum. First I want to thank you for MyGUI. I have just started working with it. I had some minor 'problems' understanding the concepts, but its getting better ;-)

To my issue: I think I found a bug that cannot be solved without touching MyGUI sources.

I am using a ControllerEdgeHide that I add to a window.


m_pControllerEdgeHide = new ControllerEdgeHide( 0.5f, 5, 5 );
ControllerManager::getInstance().addItem( m_window, m_pControllerEdgeHide );


The point is, that I am in a separate DLL. When unloading my DLL the window is also freed. That means, that during the next ControllerManager::frameEntered call MyGUI detects that widget is no more existing and frees the controller. See the code:


void ControllerManager::frameEntered(float _time)
{
for (ListControllerItem::iterator iter=mListItem.begin(); iter!=mListItem.end(); /*added in body*/) {

if (null == (*iter).first) {
delete (*iter).second;
// удаляем из списка, итератор не увеличиваем и на новый круг
iter = mListItem.erase(iter);
continue;
}

if ((*iter).second->addTime((*iter).first, _time)) {
++iter;
continue;
}

// на следующей итерации виджет вылетит из списка
(*iter).first = null;
}

//if (0 == mListItem.size()) Gui::getInstance().removeFrameListener(newDelegate(this, &ControllerManager::frameEntered));
if (0 == mListItem.size()) Gui::getInstance().eventFrameStart -= newDelegate(this, &ControllerManager::frameEntered);
}


The delete wants to free the controller. This happens from within the MyGUI.DLL. Due to the fact that I allocated the ControllerEdgeHide from my DLL the heap is another. That triggers an exception.

I found no solution for this but to keep the 'ownership' of the Controller and write an erase function that I call to remove the item from the controller manager.


void ControllerManager::eraseItem(WidgetPtr _widget)
{
for (ListControllerItem::iterator iter=mListItem.begin(); iter!=mListItem.end(); ++iter) {
if (_widget == (*iter).first) {
mListItem.erase(iter);
return;
}
}
}


So, when destructing my window I do:


ControllerManager::getInstance().eraseItem( m_window );
SAFE_DELETE( m_pControllerEdgeHide );


I found no MyGUI factory for ControllerEdgeHide, so I have to create it with new in my 'space'.

As mentioned before: I am new to MyGUI. Maybe I basically did not understand the mechanics. Maybe one of you guys might take a look at this issue and let me know about your thoughts ^^

Best regards,

Thomas

Altren

20-02-2009 00:42:02

Oh, you is right and there should be factory but we have no controllers factories. Use your current solution for now, but we will add controller factories later.

Maverick

20-02-2009 07:04:32

Cool, thanks for your help.

Best regards,

Thomas

Maverick

20-02-2009 07:05:37

PS: But it would be nice to have 'custom' controllers as well. So we user can do some nice fancy stuff :-)