subscribeEvent through a wrapper

For help with anything that CEGUI doesn't offer straight out-of-the-box, e.g.:
- Implementation of new features, such as new Core classes, widgets, WindowRenderers, etc. ...
- Modification of any existing features for specific purposes
- Integration of CEGUI in new engines or frameworks and writing of new plugins (Renderer, Parser, ...) or modules

Moderators: CEGUI MVP, CEGUI Team

User avatar
Chris089
Just popping in
Just popping in
Posts: 3
Joined: Fri Jul 22, 2005 15:34

subscribeEvent through a wrapper

Postby Chris089 » Fri Jul 22, 2005 15:48

Hi,

I'm implementing a GUI system in me and the rest of the team are working on, and instead of doing everything from scratch, I chose to use CEGUI. A problem though is that the rest of the team didn't like the interface, so I decided to write a wrapper to suit their needs. Everything went smoothly until I was going to write wrap the event setters. I tried this (parts of the code):

Code: Select all

typedef bool (EventHandler) (const CEGUI::EventArgs);

...

class Editbox {
public:
    void SetTextAcceptedHandler (EventHandler* fpHandler, void* pThis);
};

...

void Editbox::SetTextAcceptedHandler (EventHandler* fpEventHandler, void* pThis) {
    //m_pWindow is a Window*
    m_pWindow->subscribeEvent (CEGUI::Editbox::EventTextAccepted, CEGUI::Event::Subscriber (fpHandler, pThis );
}



But I get this compiler error:

Code: Select all

d:\MTA\MTA10\core\gui\CGUIEdit.cpp(26) : error C2661: 'CEGUI::SubscriberTemplate<Ret,Args>::__ctor' : no overloaded function takes 2 arguments
        with
        [
            Ret=bool,
            Args=const CEGUI::EventArgs &
        ]
        and
        [
            Ret=bool,
            Args=const CEGUI::EventArgs &
        ]


Any suggestion on how to make that work? I could write an event receiver as a baseclass for all eventhandlers, but I don't want to do that. I want to keep it 100% Object-Oriented so using CEGUI's support for method pointers is perfect for me only I could get it through this wrapper.

Any ideas?

User avatar
lindquist
CEGUI Team (Retired)
Posts: 770
Joined: Mon Jan 24, 2005 21:20
Location: Copenhagen, Denmark

Re: subscribeEvent through a wrapper

Postby lindquist » Fri Jul 22, 2005 18:19

I think you would make it easier on yourself by doing something like this instead:

Code: Select all

typedef CEGUI::Event::Subscriber EventSubscriber;

...

class Editbox {
public:
    void SetTextAcceptedHandler(EventSubscriber subscriber);
};

...

void Editbox::SetTextAcceptedHandler (EventSubscriber subscriber) {
    //m_pWindow is a Window*
    m_pWindow->subscribeEvent(CEGUI::Editbox::EventTextAccepted, subscriber);
}


this would give you the full flexibility of Event::Subscriber with little code.
I must admit that I'm not completely up to date with the Event subscription system of CEGUI yet, but I think you'll run into problems with C++'s strict syntax for function pointers.
AFAIK the typedef for EventHandler

Code: Select all

typedef bool (EventHandler) (const CEGUI::EventArgs);
pretty much eliminates the possibility of having a regular class member function passed without errors, except when static. And the this pointer is not needed for such functions.

This is just thoughts that came up while thinking about your problem, I have not tested anything.

another thing i noticed is that the EventArgs is not a reference in your typedef.. It should look like this:

Code: Select all

typedef bool (EventHandler) (const CEGUI::EventArgs&);



Setting things up like this would allow you to write code like this:

Code: Select all

bool StaticHandler(const EventArgs& e)
{
    // do something
    return true;
}

class HandlingClass
{
public:
    bool MemberHandler(const EventArgs& e)
    {
        // do something
        return true;
    }
};

Editbox *eb = .... // your editbox
// subscribe like this
eb->SetTextAcceptedHandler(EventSubscriber(StaticHandler));
// or a class-member like this
HandlingClass *hc = new HandlingClass();
eb->SetTextAcceptedHandler(EventSubscriber(HandlingClass::MemberHandler),&hc);


HTH

User avatar
Chris089
Just popping in
Just popping in
Posts: 3
Joined: Fri Jul 22, 2005 15:34

Re: subscribeEvent through a wrapper

Postby Chris089 » Fri Jul 22, 2005 19:11

Thanks man :D! I really appreciate when people are so helpful and explain in such details :).

That's a very good idea I didn't thought of. I'll try this when I'm back at home.

Thanks again :)

MrBigglesworth
Just popping in
Just popping in
Posts: 2
Joined: Tue May 16, 2006 20:44

Postby MrBigglesworth » Tue May 16, 2006 21:39

Hi everybody,
I'd like to resurrect this quite old Thread because I'm actually trying to do same thing: subscribing member functions to events.

I followed the above code pieces and tried to implement these steps into my project:

Code: Select all

namespace GraphControl{
class InspectableUnit{
       public:
       bool InspectableUnit::processWAIT(const CEGUI::EventArgs& e){
               //do something and return true
       }

 std::map<std::string, CEGUI::Event::Subscriber> InspectableUnit::getContextMenuEntries(void){
       std::map<std::string, CEGUI::Event::Subscriber> entries;
   entries.insert(std::pair<std::string, CEGUI::Event::Subscriber>("WAIT", CEGUI::Event::Subscriber(InspectableUnit::processWAIT)));
   return entries;
}
//... and then I use this map to subscribe it somewhere else in my project
}
}

This is was is done by the last line in lindquist's code.

When I compile this, the compiler gives an error:

error C3867: "GraphControl::InspectableUnit::processWAIT": Dem Funktionsaufruf fehlt die Argumentliste. Verwenden Sie "&GraphControl::InspectableUnit::processWAIT", um einen Zeiger auf den Member zu erstellen.

(Sorry, for the german explanations. I guess if the message really matters, you can look it up by the error code)

So, I changed the line, as suggested to:

Code: Select all

entries.insert(std::pair<std::string, CEGUI::Event::Subscriber>("WAIT", CEGUI::Event::Subscriber(&GraphControl::InspectableUnit::processWAIT)));


And now it gets interesting. The compiler now complains:
1>c:\program files (x86)\ogre sdk\include\cegui\ceguievent.h(93) : error C2064: Ausdruck ergibt keine Funktion, die 1 Argumente übernimmt
1> c:\program files (x86)\ogre sdk\include\cegui\ceguievent.h(92): Bei der Kompilierung der Klassen-template der bool CEGUI::_functorBinder<Functor,Ret,Args>::operator ()(Args) const-Memberfunktion
1> with
1> [
1> Functor=bool (__thiscall GraphControl::InspectableUnit::* )(const CEGUI::EventArgs &),
1> Ret=bool,
1> Args=const CEGUI::EventArgs &
1> ]
1> c:\program files (x86)\ogre sdk\include\cegui\ceguievent.h(155): Siehe Verweis auf die Instanziierung der gerade kompilierten Klassen-template "CEGUI::_functorBinder<Functor,Ret,Args>".
1> with
1> [
1> Functor=bool (__thiscall GraphControl::InspectableUnit::* )(const CEGUI::EventArgs &),
1> Ret=bool,
1> Args=const CEGUI::EventArgs &
1> ]
1> inspectableunit.cpp(149): Siehe Verweis auf die Instanziierung der gerade kompilierten Funktions-template "CEGUI::SubscriberTemplate<Ret,Args>::SubscriberTemplate<bool(__thiscall GraphControl::InspectableUnit::* )(const CEGUI::EventArgs &)>(const Functor &)".
1> with
1> [
1> Ret=bool,
1> Args=const CEGUI::EventArgs &,
1> Functor=bool (__thiscall GraphControl::InspectableUnit::* )(const CEGUI::EventArgs &)
1> ]


I searched the net about this and it seems to me, that this is an error because of the changes they made in VS 2005 to the member-to-pointer code. But maybe I'm wrong and to dumb to use the Subscriber Template right - in that case, could you please help me out? 8)

User avatar
lindquist
CEGUI Team (Retired)
Posts: 770
Joined: Mon Jan 24, 2005 21:20
Location: Copenhagen, Denmark

Postby lindquist » Tue May 16, 2006 21:48

There is a error in the code I posted back then.
The event subscriber must have the this pointer passed along with the function pointer.

This means that to do your thing, you'll need to have the instance of InspectableUnit at hand.

Code: Select all

using namespace CEGUI;

InspectableUnit iu;
Event::Subscriber es(&InspectableUnit::processWait, &iu);
subscriberMap.insert(std::make_pair("WAIT", es));


HTH

MrBigglesworth
Just popping in
Just popping in
Posts: 2
Joined: Tue May 16, 2006 20:44

Postby MrBigglesworth » Tue May 16, 2006 23:38

Ah, I see. Thanks for the quick response. Works perfectly :D


Return to “Modifications / Integrations / Customisations”

Who is online

Users browsing this forum: No registered users and 8 guests