G
Mir ist schon klar, dass es sowas gibt, nur sehe ich nicht wie man damit messages hierarchisch (d.h. eben OOP - mäßig) ordnen kann, ohne mehr Aufwand als einfach eine message von einer anderen abzuleiten.
Des weiteren kann man mit einer ähnlichen Vorgehensweise effektiveren Code schreiben als mit boost::bind und boost::signal.
Dazu folgendes Szenario aus der Spieleentwicklung: Man hat das Spiel in mehrere Subsystems aufgespalten, die jeweils eine Aufgabe haben, etwa "RenderSystem", "PhysicsSystem" oder "BulletSystem".
Nun ist es so, dass man immer genau ein solches System hat, das dannn bestimmte Teile der Daten in jedem Tick modifiziert. Natürlich muss man zwischen diesen Systemen kommunizieren, so könnte etwa das PhysicsSystem eine message loslassen, falls ein GameObject mit einem anderen kollidiert ist. Der BulletHandler würde dann prüfen, ob das GameObject eine Bullet ist und dann entsprechend handeln.
Mit boost::signal oder boost::bind müsste sich der BulletHandler nun bei dem PhysicsSystem registrieren, um eine Nachricht zu bekommen. Ich nehme stark an, dass boost::signal sich einfach für jeden boost::connect sich einen Pointer auf das Argument speichert. wird nun ein boost::signal ausgelöst, wird es über alle Pointer iterieren und für jeden eine Art Function Pointer ausführen, d.h. der overhead beim messsage passing nimmt linear mit der Anzahl der Empfänger zu.
Verwendet man meine Herangehensweise, die ich vorgestellt habe, könnte man ein zentrales MessageSystems haben, das am Ende als Handler einen Pointer auf jeden SubSystem - Type bekommt. Wird nun dem Listener des MessageSystems eine message gegeben, wird einmal ein vtable look up stattfinden, dann ist die message beim Handler. Der Handler wird mit SFINAE wie vorgestellt zur compile Zeit feststellen, ob ein SubSystem eine message verwertet. Tut es das wird eine normale Funktion aufgerufen, kein function pointer oder eine virtuelle Function.
Die Komplexität mit boost::signals ist O(n), wobei n die Anzahl der Systems ist, die sich an den Slot connected haben. Ein System wie ich es verwende hat dagegn O(1) (schreibt man das so, wenn es konstant ist?), ist also unabhängig von der Anzahl der sub systems, die ein bestimmtes Event auswerten.
Außerdem kann man mit boost::signals ja wohl sehr schlecht eine generische message queue schreiben kann.
Und zum Schluss kommt noch dazu, dass man eine mit boost::signal eine weitere unnötige Abhängigkeit bekommt: Das BulletSystem muss über das PhysicsSystem Bescheid wissen, um sich dort zu registrieren. Man braucht also ein #include "Physics.hpp" für das BulletSystem. Das braucht man mit meinem message system nicht (sondern nur ein #include "PhysicsMessages.hpp").
Das kam jetzt vielleicht etwas überheblich rüber, dafür entschuldige ich mich. Mir ist schon klar, dass man mit boost::signals und Konsorten auch sehr gut sowas bauen kann. Ich wollte hier nur mal meinen Ansatz vorstellen, weil ich die Techniken, die dafür verwendet werden, sehr interessant fand.