Willkommen ~Gast!
Registrieren || Einloggen || Hilfe/FAQ || Staff
Probleme mit der Registrierung im Forum? Melde dich unter registerEin Bild.
Autor Beitrag
000
01.04.2002, 20:49
Prefect



Mmkay, ich bin ja inzwischen sogar so weit, daß ich freiwillig Exceptions verwende. Aber irgendwie stoße ich immer, wenn ich auf C++ umsteige um irgendwelche vertrackten Probleme zu lösen, auf ätzende Probleme, fehlende Features und was weiß ich...

Mein Ziel: Ein Signal-Slot-System ähnlich wie bei Qt zu programmieren, wobei ich allerdings nicht auf einen externen MO-Compiler wie Qt zurückgreifen will.

Bis jetzt sieht das Ganze so aus:

Quellcode:
class LSignalMgr {
        friend LObject;

protected:
        l_connection_t  *conns;
public:
        LSignalMgr() { conns = 0; }
        ~LSignalMgr();

        void AddSlot(LObject *pObj, l_objectfn_t fn);
        void DelSlot(LObject *pObj, l_objectfn_t fn);

private:
        void RemoveConn(l_connection_t *conn);
};

#define SIGNAL(name) \
class class_##name : public LSignalMgr { \
public: \
        typedef void (LObject::*fnslot_##name)(); \
        inline Connect(LObject *pObj, fnslot_##name fn) { AddSlot(pObj, (l_objectfn_t)fn); } \
        inline Disconnect(LObject *pObj, fnslot_##name fn) { DelSlot(pObj, (l_objectfn_t)fn); } \
        inline Emit() { \
                for(l_connection_t *c = conns; c; c = c->signext) \
                        (c->obj->*(fnslot_##name)(c->fn))(); \
        } \
} name;

...

class GButton : GPanel { // indirekt von LObject abgeleitet
....
        SIGNAL(Clicked);
};


...

pButton->Clicked.Connect(this, &MainMenu::Quit); // Fehler

Dieses Makro SIGNAL ist schon der erste Punkt. Es ist ja wohl nicht möglich, eine komplette Parameterliste als einzelnen Parameter an ein Template zu übergeben, sehe ich das richtig?
Denn schließlich sollen die Signals ja unterschiedlich viele Parameter verwenden können. Das geht anscheinend nur mit entsprechend angepaßten Makros.

MainMenu ist ebenfalls indirekt von LObject abgeleitet. Nun gibt mir der Compiler aber auf der pButton->Clicked.Connect()-Zeile einen Fehler, da &MainMenu::Quit vom Typ (void (MainMenu::*)()) und nicht vom Typ (void (LObject::*)()) ist.

Na toll.

Irgendwie muß ich nun also casten. Ich habe zwei potentielle Lösungsansätze gefunden:

1) ein Makro, das Connect() verkapselt. Das würde so aussehen:
#define CONNECT(signal,obj,fn) (signal).Connect((obj), <somecast>(fn))
Das führt allerdings eine Typunsicherheit ein, es sei denn es gibt eine Möglichkeit, nur den MainMenu::-Teil des Funktionspointertyps in ein LObject:: zu casten, und die Parameterliste ungecastet zu lassen. Geht das?

2) Connect() zu einer Templatefunktion machen, d.h. der Connect()-Aufruf sieht so aus:
pButton->Clicked.Connect<MainMenu>(this, &MainMenu::Quit);

cu,
Prefect

--

Widelands - Gemütliche Aufbaustrategie, Free Software
Noch ein Blog - Lerne, wie die Welt wirklich ist, aber vergiss niemals, wie sie sein sollte.

zum Seitenanfang zum Seitenende Profil || Suche
001
02.04.2002, 13:46
Prefect



Wen's interessiert: ich habe die Connect/Disconnect-Funktionen zu Templates gemacht. Jetzt funktioniert's bestens :)

cu,
Prefect

--

Widelands - Gemütliche Aufbaustrategie, Free Software
Noch ein Blog - Lerne, wie die Welt wirklich ist, aber vergiss niemals, wie sie sein sollte.

zum Seitenanfang zum Seitenende Profil || Suche
002
02.04.2002, 17:41
anothergb02



Na siehst du °_°

--

Being in john Malkovich
.....

zum Seitenanfang zum Seitenende Profil || Suche