Kommunikation an Ein/Ausgängen in graphbasiertem Programm



  • Hallo ihr!
    Mein Anliegen ist nicht strikt auf C++ bezogen, aber da ich das Programm in C++ schreibe und ihr wahrscheinlich auch schonmal auf ein solches Problem gestoßen seid, dachte ich, hier wäre dennoch ein guter Startpunkt auf meiner Suche nach einer guten Lösung.
    Ich schreibe also gerade ein Programm, in dem man Klickibunti eine (Rechen- und Darstellungs-) Konfiguration aus Knoten und Kanten zusammenbastelt, mit der man dann anschließend die gegebene Aufgabe löst.
    Dabei liegt die Berechnungs-Lösung innerhalb der Knoten, weil das System erweiterbar sein soll (Das Programm selber weiß nicht, was die Knoten da eigentlich machen). Der Graph wird nur durch evtl. noch zu verändernde Schnittstellen in gleichförmiger Weise dem Benutzer präsentiert.
    Die Knoten haben eine (abhängig vom Knoten) flexible Anzahl von Ein- und Ausgängen.
    Nun möchte ich verschiedene Kommunikationsweisen auf den Ein- und Ausgängen ermöglichen. Während für "Stream"-Artige Berechnungen natürlich ein "Push"-Mechanismus naheliegt, bei dem die Knoten ihre Werte auf die Ausgänge legen und dann Folgeknoten ihrerseits die Berechnung starten.
    Andersherum sieht es aus, wenn ich die graphische Präsentation der Berechnungsergebnisse bewerkstelligen möchte. Dann liegen die Daten in einem Verlauf vor und ich möchte sie Reihen- und Spaltenweise in einer Grafik zusammenfassen. Da die Datenmengen größer werden, sich aber (bis auf neue Werte) kaum verändern, bietet sich hier ja ein "Pull"-Mechanismus an, in dem ein Spalten-Knoten z.B. vor Beginn der Darstellung die graphischen Objekte der einzelnen Vorgängerknoten in Erfahrung bringt und dann entsprechend in ihrem eigenen graphischen Objekten anordnen und zur Darstellung bringen.

    Es bleibt also festzuhalten, dass unterschiedliche Kommunikationsart über Ein- und Ausgänge möglich sein müssen (Gibt da noch mehr).
    Also habe ich mir gedacht, dass es sinnvoll ist, in der Basisklasse aller Knoten nur einen Pool von Ein- und Ausgängen zu verwalten und dann kann man die passenden Schnittstellen an den Eingangen bei diesen selber erfragen.
    Eine Kommunikation ist also Datenübertragung zwischen einem Paar von Ein- und Ausgang, die eine Mindestmenge von übereinstimmenden Schnittstellen unterstützt (und vom Benutzer verbunden wurden).

    Nun ist das Problem, dass der einzelne Knoten seine Ausgänge ja "von innen" sieht, der Folgeknoten aber "von außen", selbiges natürlich auch bei den Eingängen. Das heißt für mich auf den ersten Blick, dass für ein Protokoll, das aus Schnittstellen auf Ein- und Ausgängen besteht, 4 Schnittstellen nötig sind. Das ist ja ein ganz schöner Wust und das legt mir den Gedanken nahe, dass ich hier irgendetwas noch nicht ganz klar sehe.

    Habt ihr mein "Problem" verstanden und evtl. erleuchtende Gedanken dazu? Wenn nicht, ich erkläre gerne genauer.

    Danke für eure Zeit schoneinmal,

    Viele Grüße,
    Deci



  • Dieser Thread wurde von Moderator/in pumuckl aus dem Forum C++ in das Forum Rund um die Programmierung verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • Decimad schrieb:

    Nun ist das Problem, dass der einzelne Knoten seine Ausgänge ja "von innen" sieht, der Folgeknoten aber "von außen", selbiges natürlich auch bei den Eingängen. Das heißt für mich auf den ersten Blick, dass für ein Protokoll, das aus Schnittstellen auf Ein- und Ausgängen besteht, 4 Schnittstellen nötig sind. Das ist ja ein ganz schöner Wust und das legt mir den Gedanken nahe, dass ich hier irgendetwas noch nicht ganz klar sehe.

    So wie ich das jetzt verstanden habe ist dein Problem, dass du Knoten direkt miteinander verbinden willst, so dass sie zueinander passende, entgegengesetzte Schnittstellen haben müssen, wobei willfürlich festgelegt werden muss, wer jetzt was von "innen" und was von "außen" sieht. Sinnvoller wäre es, wenn die einzelnen Knoten nicht schon die verbunden Knoten sehen, sondern nur die Kanten dorthin.

    Ich würde die Kanten als Warteschlangen implementieren, und die Knoten als Threads. Die Knoten brauchen dann keine Schnittstelle zum Empfang von Daten zur Verfügung stellen, sondern bekommen nur einmalig die Warteschlangen für die Ein-und Ausgänge, und benutzten dann deren Push- und Pop-Methoden.

    Vielleicht hab ich dein Problem aber auch völlig falsch verstanden 😉



  • Hallo da!
    Danke Dir für die Zeit, die Textwand durchzuackern^^

    An Threads habe ich im Moment noch gar nicht weiter gedacht, das wäre natürlich später auch möglich, wobei es im speziellen Testfall ersteinmal "unnatürlich" wäre, zu threaden und derzeit nicht eine meiner Prioritäten.
    Mein Plan war bislang, dass die einzelnen Knoteninstanzen nur mit ihrer Seite von ihren Ein- und Ausgängen kommunizieren (welche dann an die etwaig verbundene Gegenseite weiterleiten). Sie sehen sozusagen von innen heraus nur ihre eigenen "Pins", um es etwas salopp zu formulieren.
    Nun würde ich (man?) von innen heraus gerne an einem Ausgang eine Push-Methode anbieten. D.h. der Knoten sagt z.B. this->PinA->Push( 0.5 );. PinA weiß nun, welche Eingänge mit ihm verbunden sind und leitet den Aufruf in irgendeiner Weise (im einfachsten Fall repliziert er in einer Schleife einfach die Aufrufe für alle Verbindungen...) an die Gegenseite weiter.

    D.h. also: Der Eingang (Das Datenziel) muss in diesem Fall eine Push-Methode von außen anbieten und der Ausgang eine Push-Methode von innen (hab ich das mit innen und außen klar ausgedrückt?).

    Sagen wir jetzt mal, das Protokoll lässt beidseitigen Datenverkehr zu. Dann müsste ich für das Protokoll 4 Schnittstellen anbieten, nämlich jeweils die Schnittstellen auf beiden Seiten für die Sicht von innen (also vom Knoten) und von außen (also vom verbundenen Pin eines anderen Knoten oder der Programmumgebung um Parameter für die Darstellung einzuholen).

    Hrmmm, ich denke mal weiter darüber nach...

    Viele Grüße,
    Deci



  • Mach mal 'ne Skizze oder 'nen Screenshot. Das ist mir alles au obskur. Was du mit innen und aussen meinst, sind schon Implementationsdetails deiner Idee. Leider kann ich nicht in deinen Kopf schauen, um deine konkrete Vorstellung zu sehen. Deine Beschreibung hilft mir nicht.

    Wozu brauchst du Kannten? Normalerweise hat man eine Liste an denen alle mit den Ausgang verbundenen Knoten enthalten sind. Belegt man diesen nun mit einem Wert, werden alle Knoten an diesem Port benachrichtigt, dass sich was geaendert hat (notify). Diese reagieren auf das notify-Event (Methode .. whatever). Wie das im konkreten ausschaut, haengt natuerlich von den jeweiligen Knoten selbst ab. Er kann dann einfach nachsehen, was sich veraendert hat.

    Das this->PinA->Push( 0.5 ); laesst mich vermuten, dass das Problem overdesigned ist.



  • Hallo da!
    Also hier mal ein erstes Bild dazu... Inkscape ist aber manchmal zu schrecklich zu bedienen^^
    Hoffe, es wird klar.

    http://img90.imageshack.us/img90/6844/designsm.png

    Grüße,
    Deci



  • Wir reden aneinander vorbei ... Ich wollte kein Design der Klasse graphisch haben, sondern wie die Sicht des Anwenders auf deine Applikation ist.

    (Rechen- und Darstellungs-) Konfiguration aus Knoten und Kanten ... "Stream"-Artige Berechnungen

    Was soll das konkret sein. Beispiele?



  • Datenquellen (A/D-Wandler etc.), Berechnungsknoten, Darstellungsknoten (Datenkurve, Koordinatensystem, Hierarchische Anordnung). Sowas!

    Viele Grüße,
    Deci

    PS: Wobei nach der Konfigurationsphase die Graph-Ansicht nur noch zur Fehlersuche und soetwas dient und der Benutzer dann hauptsächlich auf die Ansichten, die die Darstellungsknoten im System anbieten zurückgreift.


Anmelden zum Antworten