Undo/redo mit Baum mit Signalen
-
Hi,
zurzeit sieht das bei mir so aus:
class Tree { public: typedef std::unique_ptr<TreeNode> RangeTreeNodePtr; typedef std::vector<RangeTreeNodePtr> Nodes; // ... private: Nodes nodes; }; // === class TreeNode { public: typedef std::vector<unsigned int> ChildIndices; // ... private: Tree* tree; int indexInTree; int parentIndex; ChildIndices childIndices; };Die Nodes werden speichertechnisch also alle in Tree verwaltet und die Nodes haben redundante Informationen über ihren Speicherort im Baum und darüber, welche Indices das Elternelement und die Kinder haben.
Eingefügt/gelöscht wird über Tree, der ruft dann private Funktionen vom Node auf, um childIndices/parentIndex/indexInTree ggf. upzudaten. Tree setzt dann auch signals zwischen den einzelnen Ästen. Denn wenn ich folgende Struktur habe:
A
--> B (Child von A)
--> C (Child von A)und dann A ein neues Child namens D zuweise, muss bei einer Änderung von B eben auch D geupdated werden -> Signale/Slots gehen über mehrere Nodes hinweg, weswegen mir die Verwaltung im Tree sinnvoll erschien.
Die Indices wirken erstmal unnötig, sind aber eben sinnvoll, wenn ich den Baum serialisieren möchte und wenn ich Mementos für undo/redo erzeuge.
Mein Problem ist, dass ich nicht sicher bin, ob der Ansatz so am "schönsten" ist: Die Implementierung erscheint mir etwas schwierig und umständlich, mir fällt jedoch auch keine bessere Lösung ein.
Beste Grüße
Eisflamme
-
Wo sind da jetzt die Mengen?
-
Pro TreeNode gibt es eine Menge. Eine Menge ist z.B. einfach ein
std::vector<int>als Attribut von TreeNode.
-
Wo sind jetzt die Funktionszeiger?
-
Im
// ...-Bereich. Ich zeige hier nur Ausschnitte und nicht den Produktiv-Code, der würde das Problem unnötig aufblähen.
-
Oder findest du das zur Problemlösung relevant? Eigentlich suche ich hier ja auch für gegebene Anforderungen die Lösung und nicht für meine Lösung Kritik
Ich bin ja durchaus bereit alles umzuschmeißen und sauberer aufzuziehen
-
Eisflamme schrieb:
Oder findest du das zur Problemlösung relevant? Eigentlich suche ich hier ja auch für gegebene Anforderungen die Lösung und nicht für meine Lösung Kritik
Ich bin ja durchaus bereit alles umzuschmeißen und sauberer aufzuziehenDoch, das finde ich schon relevant. Irgendwie ist mir die Problembeschreibung nach wie vor nicht ganz klar, da würde es helfen, das Ganze mal in Aktion zu sehen.
-
Hi,
also ich kann euch die Software selbst nahelegen. Mein Beispiel mit Mengen ist nämlich sehr gut vereinfacht, ohne den Kontext (Poker) bloßzustellen. Nimmt man Poker aber dazu, so bläht sich das direkt zum Gesamtkontext auf, in dem die Software eben steht.
http://www.pokerranger.net/Download
Man kann die Software sowieso 21 Tage mit allen Funktionen nutzen. Wenn jemand mehr Zeit braucht oder zu spät reinschaut, kann ich ihm hier aber gerne einen freien Key geben.
In der Software klickt man jetzt oben bei "Player1 Range" doppelt drauf, dann öffnet sich ein Fenster. Hier kann man die eigentliche "Menge" auswählen, das sind 13x13 Hände (mit Hand z.B. = AKs, also eine Hand mit Ass und König in derselben Farbe für beide Karten). Oben rechts kann man dann eine neue Gruppe erstellen mit Klick auf die 1. Eine Gruppe ist eine Untermenge.
Ich weiß nicht, wie selbsterklärend das jetzt ist. Ansonsten kann ich auch Screenshots bereitstellen. Lasst mich bitte wissen, was ihr braucht.

Gruß
Tim
-
Ok, einmal push ich noch, dann frag ich hier eben nicht mehr nach.
Ich hab's so weit vereinfacht und eine Analogie geschaffen wie möglich. Und wenn ihr das alles wirklich integriert live sehen wollt, habt ihr auch die perfekte Möglichkeit.
Demnach gehe ich mal davon aus, dass es die einfache, elegante Lösung einfach nicht gibt oder die nur mit sehr hohem Aufwand zu finden ist, sodass meine Frage den Rahmen vom Forum einfach sprengt. Eigentlich ist das in meinen Augen nicht viel mehr als ein Standardproblem (undo/redo, Memento, Serialisierung für eine baumartige Struktur mit ein paar Extras), aber dann vertue ich mich da wohl.
Kurzes Feedback dazu, wieso ich hier quasi keine Resonanz kriege, wäre top. Dann stell ich die Frage nächstes mal anders (oder gar nicht)
-
Eisflamme schrieb:
Kurzes Feedback dazu, wieso ich hier quasi keine Resonanz kriege, wäre top. Dann stell ich die Frage nächstes mal anders (oder gar nicht)
Ich versteh halt überhaupt nicht, was dein vorheriger Beitrag zur Klärung der Problemstellung beiträgt. Und irgendwelche Software runterzuladen und auszuführen (ist das deine Software?) ist eine extrem hohe Hürde. Daher ist mir die Problemstellung immer noch nicht so ganz klar.
-
SeppJ schrieb:
Und irgendwelche Software runterzuladen und auszuführen (ist das deine Software?) ist eine extrem hohe Hürde.
Hast du keine VM für solche Zwecke?

Außerdem gibt's noch VirusTotal und Metascan.
-
Irgendwie ist mir die Problembeschreibung nach wie vor nicht ganz klar, da würde es helfen, das Ganze mal in Aktion zu sehen.
Wie meintest du das denn? Ich hab im Ausgangsbeitrag mein Problem abstrahiert mit Mengenmodellen vorgestellt und gesagt, welche Funktionen ich benötige.
Das schien zu abstrakt zu sein, daher habe ich halt mal einen Link zu unserer Software gepostet, wo genau das zurzeit umgesetzt wird -> nur bin ich eben mit meiner Architektur nicht restlos zufrieden, weil
1. das erstens viel Code ist und ich Teile für undo/redo und Serialisierung wiederhole, was ich aber nicht nur reuse ausnutze
2. die Performance nicht optimal ist
3. Wartung hier schwierig und fehleranfällig scheint
4. Weiterentwicklung schwierig und fehleranfällig scheintUm zu sehen, was die Funktionen genau tun, wäre das jedoch gut. Und ja, das ist meine Software.

-
Eisflamme schrieb:
Wie meintest du das denn?
Code natürlich. Insbesondere:
overly simplistic schrieb:
Wo sind jetzt die Funktionszeiger?
-
Hi,
die Funktionszeiger hatte ich in jedem einzelnen Node. Das Design war aber echt zu kompliziert. Im Endeffekt waren die Funktionszeiger das ganze Problem am Design, die haben die Strukturen starr gemacht, den Code kompliziert und lang... nicht gut.
Mein neues Design hat jetzt einen kopierbaren Baum. Für das Problem, dass eine Menge nichts hinzugefügt haben darf, was in der Obermenge nicht enthalten ist, habe ich jetzt einfach eine zweite Klases genutzt, die von Menge ableitet: SetInTree. SetInTree kennt den Node, in dem es steckt, und kann darüber eben auch auf andere Nodes zugreifen, um dort zu ermitteln, wie viele Elemente jetzt z.B. in der Obermenge stecken.
So weit, so gut. Das Einzige, was mich gerade noch stört, ist, dass SetInTree und SetNode koabhängig sind.
Für Serialisierung und Memento ist das aber praktisch: Ich kann den Tree jetzt einfach (recht schnell und mit kurzem Code!) kopieren. XML/binäre Serialisierung ist wie vorher Extraaufwand, aber der lässt sich eben nicht reduzieren, evtl. mit boost::serialize ein bisschen.
Undo/redo, Serialisierung, Baumstrukturen sind Standardthemen. Damit ist auch jede Kombination davon miteinander für mich ein Standardthema. Vielleicht schreibe ich mal einen Artikel dazu, in dem klar wird, wie man das alles verbindet und sei es nur als Erinnerung für mich selbst.