...
{CODE(ln=>0)}TMNetworkMessageHeader = record
MagicNumber: longword; // for identifying the beginning of a packet. MachineID: longword; // the receiver id, is ALL=9999 for broadcast CommandID: longword; // numbering of outgoing messages check for missing packets Command : TMCommandID; // DATA, FLUSH Size : Longword; // size of data structure Data: array of Byte; // data
end;
210 2 150 73 15 39 0 0 241 226 2 0 35 97 0 0 0 0 0 0 0 0 0 0
{CODE(ln=>0)}
210 2 150 73 -> MagicNumber: 1234567890
15 39 0 0 -> MachineID: 9999 (all)
241 226 2 0 -> CommandID: DebugCounter (increasing number)
35 97 0 0 -> Command: cmncFlush = $6123; 0 0 0 0 -> Size: 0 0 0 0 0 -> Data: 4 bytes of nothing
210 2 150 73 15 39 0 0 255 4 0 0 35 81 0 0 28 0 0 0 11 0 0 0 17 0 0 0 47 51 47 32 89 32 73 110 112 117 116 32 86 97 108 117 101 49 55 0
{CODE(ln=>0)}
210 2 150 73 -> MagicNumber
15 39 0 0 -> MachineID
124 229 3 0 -> CommandID
35 81 0 0 -> Command: cmncData = $5123; 28 0 0 0 -> Size: 28 byte 11 0 0 0 -> cmgncSetBridgeValueThroughHierarchie 17 0 0 0 -> length(path) 47 51 47 32 -> / 3 / 89 32 73 110 -> Y I n
112 117 116 32 -> p u t
86 97 108 117 -> V a l u
101 49 55 0 -> e 1 7 #0
^
With the Flush the Server sends its time and the number of all messages sent. From this number the client can check if it has missed a message.
Outputs:
Outputs:
clients erhalten die kompletten patchklasses, wie sie auch am server existieren.
dazu wird als erste aktion auf einen client-request-dump mit einer server-cleargraph message und der anschliessenden übertragung aller patchklassen geantwortet.
als letzte reaktion auf den client-request-dump wird der client vom server aufgefordet den server-root-knoten in seinem dafür vorgesehenen clientroot anzulegen.
dadurch wird unter beachtung der boygroup-manager der gesamte graph aufgebaut.
änderungen werden als inkrementelle messages übertragen, wie das auch jetzt schon lokal geschieht.
beim laden eines patches genügt es nicht nur geboygroupte teile zu übertragen. ein client muss die gesamte patchstruktur bis hin zum geboygroupten teil auch aufbauen, um einen geboygroupten knoten in allen instanzen des patches auf dem client anlegen zu können. nur wenn die gesamte patchstruktur des servers auf dem client abgebildet wird kann sichergestellt werden, dass alle instanzen des patches auf dem client vorliegen.
wird auf dem server ein patch unter anderem namen gespeichert muss die änderung des patchnamens dem client mitgeteilt werden, da die identifizierung einer action über den namen der patchklasse geregelt wird. hierfür muss eine neu action eingeführt werden.
if you think of a patch as an instance of a patchclass which can be instanciated more than one time in a patchsystem, then you will notice that it is possible to have a patchclass which holds some boygrouped nodes and therefore is partly boygrouped in one scenario, but in another instance is completely boygrouped because itself is just boygrouped in its parent patch.
so two instances of the same patchclass can look differntly on a client.
however to keep the system simple the patchclasses are always transmitted completely, so that that there is no need to seperate between partly boygrouped patches and completely bougrouped patches. so always transmitting the whole patchclasses of the server just reflects that it is all about the global structure and not about the logical nodes within a patch.
since the patchclasses are maintained on the client in the same way as on the server, the only way to react on boygroup-specific actions is within the patch instances.
a boygrouped instance of a patch behaves like a patch on the server.
a not boygrouped instance reacts on all node (including their childs actions) and link actions (so all actions) if the involved nodes already exist.
a node within a non-boygrouped patch instance is created when a corresponding boygroup-manager action is attached.
a node is deleted if it is deleted on the server or when a node action comes with a local-manager action.
-
a patch class is renamed when the patch action comes with an attribute "saveme".
auf dem client werden dadurch alle knoten innerhalb des patches angelegt. auch links werden gezogen und pins eingestellt. es wird also am besten die komplette currentdescription noch einmal auf der betroffenen instanz ausgeführt. knoten die im patch schon geboygrouped waren werden nicht belangt. werden durch die aktion weitere subpatches geboygrouped ist auch dies implizit zu tun. der server wird nicht alle patchklassen neu schicken. ein knoten sollte im allgemeinen nicht nur seinen logischen boygroup state kennen, sondern auch seinen physikalischen, der vom eigenen logischen und vom physikalischen boygroup state des nächst drüber liegenden parents abhängig ist. der physikalische boygroup state muss bei der impliziten reaktion gesetzt werden und zu möglichen weiteren impliziten reaktionen führen.
property Boygrouped : Boolean read FBoygrouped write SetBoygrouped;
unboygroupen von patches:
same as above.
old:
momentan werden knoten mit halben all ihren links gelöscht und dann mit neuem manager wieder angelegt.
kann eigentlich nur vereinzelt auftreten und kann in sofortiger reaktion münden, indem alle parent patches die betroffenen links ausfindig machen, die alten links löschen und neue ziehen. dies hat in allen patchclassen mit entsprechenden actions zu passieren. am besten wäre sicherlich die sammlung aller instanzen des patches in den jeweiligen parentpatchklassen um die aktionen dann gemeinsam zu verschicken. dazu könnte man sich alle parentpatchklassen ansehen und in eine liste stecken, versehen mit allen ids der jeweiligen instanzen der eigenen klasse innerhalb des parents. danach wird für jede parentklasse eine patchaction zusammengestellt die die links löscht bzw nach dem umbenennen der iobox die neuen links zieht...
frage nur wann genau das passieren soll. schon beim analysieren der aktion in der patchklasse?
kann clientseitig dazu führen, dass ein link in einem oder mehreren parentpatches sinn macht, der in deren description gespeichert ist. (und zu dem neu hinzugekommenen pin des patches führt).
denkbar hierfür eine ähnliche aktion auszuführen wie beim exkurs (unabhängig vom boygrouping). sicher wäre dass dies hier implizit sein sollte, da der parent tatsächlich nicht verändert wird. eigentlich sollte es ausreichen auf aktionen komplett zu verzichten sondern direkt die currentdescription anzuschauen und entsprechende links zu bestätigen.
generell sollte nochmal das implizite löschen von fehlgeschlagenen aktionen gaanz genau durchgesehen werden, da ab jetzt viel mehr aktionen fehlschlagen können als bisher. AUSSER es werden alle physikalischen boygroupstates immer brav abgefragt bevor bspw versucht wird auf einem client einen link zu ziehen.
old:
wenn aber beim boygroupen der knoten komplett zerstört wird bricht auch serverseitig die verbindung auf (bzw. wird nicht neu gezogen). trifft auch aufs un-boygroupen zu.
current:
beim boygroupen werden die ungeboygroupten knoten nicht mehr entfernt und neu gebaut. deshalb bricht die verbindung serverseitig nicht mehr auf. deshalb ist es wichtig nun auch dafür zu sorgen auf dem client das gleiche verhalten zu bekommen. deshalb: (still todo)
mehrere szenarios:
oder
relative pfade zu subpatches und modulen sollen nicht auf dem client neu aufgelöst werden, da der client sowieso nicht von dort lädt. unabhängig ob das jeweilige verzeichnis auf dem client existiert soll der client patch den gleichen pfad wie der server verwenden. immer.
dafür wird ab jetzt jede action zu einem subpatch oder module mit einem attribut für den absoluten pfad versehen. ein client nimmt dann diesen pfad. ein server oder standalone löst den pfad wie bisher relativ auf.
alle patches werden gleich behandelt. es gibt für den client keine module.
es sollte reichen dass sich ein rechner (der server) um die verwaltung von brücken kümmert. im einfachsten fall würden die messages die jedes frame geschickt werden einen pfad zum pin und die neuen werte enthalten. hat den nachteil, dass dieser pfad für jeden pin in jedem frame geparst werden muss.
optional wäre eine neue message, die bei jeder änderung der brücken die komplette liste von brücken-pfaden den clients übermittelt. in dem fall würde der client die brücken einmal parsen und dann jedes frame nur noch auf brücken-id + werte warten und die jeweiligen pins schon parat haben.
da jedoch
wird erstmal der erstere einfachere ansatz umgesetzt.
die neue message auf commander-ebene:
SetBridgeValueThroughHierarchie ( "01/12/14/Filtertime"+"14.000" )
jede Aktion kann u.U. zu verschiebung von Brücken führen. Um nicht jede inkrementelle Änderung am Patchsystem unterscheiden zu müssen (e.g. subpatch boygroupen, link löschen ...), gibt es momentan nur eine Methode zum nachträglichen Erkennen eines Brückenfalls (gray to blue node), zum Löschen einer Brücke gibt es kein System. Wird die Notwendigkeit einer Brücke erkannt, wird diese an einen Manager geschickt (GBridgeFactory). Dieser Manager wird vor und nach inkrementellen Änderungen an Patchklassen (also PerformAction) benachrichtigt und kümmert sich um die "Garbagecollection" der Brücken...
jede performaction (auch undo und redo) ist so gekapselt:
UserConnection geht von grauem Knoten (flat-client-node) zu blauem Knoten (flat-server-node). Beschreibung oben. s/r nodes funktionieren mit diesem system momentan nur wenn auch der s node geboygroupet ist.
Kommt ein request dump reagiert der server nicht nur mit "clear graph + send all patches", sondern schickt auch die momentan vorhandenen Brücken via TCP an den betreffenden Client.
In jedem Frame werden die Brücken über UDP gebroadcastet, falls sich deren Wert verändert hat.
Für den ValuePin wir eine optimierte Methode aufgerufen, die die Werte nachträglich vergleicht (Brücke hat eigenen Cache hierfür).
Für alle anderen Pins (inkl. DiffValuePin) wird das ObserverPinChanged abgefragt.
anonymous user login
~4d ago
~7d ago
~14d ago
~22d ago
~29d ago
~1mth ago
~1mth ago
~1mth ago
~1mth ago
~1mth ago