(man kann sich auch den aktuellen master oder devel branch als tar/zip runterladen) Kommentarthread: @Gametoolset Verwendete Bibliotheken:
libxml2 für XML, sowie den in Zusammenarbeit mit Wilson entstandenen Wrapper (gtxml.pas).
Die Lazarus- und FreePascal runtimes.
Systemvorraussetzungen:
libxml2.pas (am besten aus dem DGL-SDK )
FreePascal 2.4.4 oder höher (bisher sollte noch alles mit FPC 2.4.2 laufen, einzelne Units werden auch mit FPC 2.4.0 oder sogar FPC 2.2.0 laufen, ggf. ausprobieren)
Die Lazarus-LCL (für gtlcl und leider auch für gtcore, da ich die FileUtil.pas brauche)
Synapse (nur für gtnet)
Subpakete:
gtstruct — Ein paar Datenstrukturen, die hilfreich sein können. Später kommen da noch weitere hinzu, die ich noch aus meinem alten stwCore importieren muss. Kann auch komplett unabhängig verwendet werden.
gtcore — Kernpaket mit XML-Serialisierung, Config- und Pfadklassen
gtfile — URIs, VFS und Streamfilter
gtnet — Netzwerksupport für die URL-Streams (braucht Synapse)
gtnode — Asynchrone Datenverarbeitung in einem komfortablen Node-Netzwerk
gtlcl — Alles, was eine Abhängigkeit auf die LCL hat, wie der PropertyEditor und die Editor-Basisklasse
Hallo allerseits,
Nachdem dieses Paket echt mächtig geworden ist, dachte ich mir, dass ich das mal öffentlich mache. Kurz was zur Geschichte: Dieses Paket war ursprünglich fest im X³-Toolset integriert, aber irgendwann habe ich die Mächtigkeit erkannt und es etwas abstrahiert. Dieses Paket eignet sich aber bei weitem nicht nur für Spieleditoren. Besonders die XML-Serialisierung ist mir in meinen Projekten immer wieder hilfreich, ebenso das VFS und die URL-Klassen (demnächst soll das komplette GT auf URLs umgestellt werden). Mit dem VFS und ein wenig Anpassung (TFileStream mit TGTURLStream ersetzen, sowie anpassen der Pfade) kann man seine Anwendung ziemlich schnell Freedesktop.org-kompatibel machen. Für neue Anwendungen ist es natürlich noch einfacher. Das Toolset läuft prinzipiell auf Linux und Windows, wobei ich die neuesten Features noch nicht auf Windows getestet habe. Da ich das nun aber schon eine ganze Weile verwende, ist es sehr stabil, man erlebt eher selten böse Überraschungen .
Nun ein kleiner Überblick über die Features:
XML-Serialisierung Dank RTTI ist das Serialisieren von Daten nach XML sehr schön einfach.
Code:
type
TSomeDataClass =class(TGTBaseObject)
published
property Name:Stringread FName write FName;
// …
end;
Code:
var
Instance: TSomeDataClass;
begin
// …
Instance.SaveToFile('some file name.xml');
end;
gibt z.B.
Code:
<?xmlversion="1.0"?>
<SomeDataClassclass="TSomeDataClass">
<Name>Some data</Name>
</SomeDataClass>
Das ganze funktioniert automatisch rekursiv für TGTBaseObject Instanzen. Man kann auch die Methode SaveToXML überschreiben, um z.B. Klassen, die nicht von TGTBaseObject ableiten, separat zu behandeln. Zusammen mit der TGTConfig-Basisklasse ist das Erstellen von Configdateien ein leichtes. Die XML-Serialisierung ist so ziemlich das von mir am meisten genutzte und mächtigste Feature vom GT.
Virtual File System und URL-Streams Das Paket enthält auch ein VFS, welches man ja bei Spielen für das Mounten von Archiven gut gebrauchen kann. Dazu kommt mit gturi.pas eine Unit, die Basisklassen für das öffnen von beliebigen URLs bietet. Es sind auch schon einige Protokolle wie fd (öffnen von stdin/stdout/stderr), file (das Öffnen von normalen Dateien), vfs (das Öffnen von Dateien aus dem VFS), tcp und tcp+ssl (verbinden zu TCP-Servern, ggf mit ssl, über Synapse) und unix (verbinden zu Unix-Sockets). Es gibt auch eine VFS-Klasse, die automatisch alle zum Programm gehörigen Freedesktop.org-Verzeichnisse im VFS unter vfs:///data/ und vfs:///config/ mountet, vorrausgesetzt, man hat mit einer Ableitung der TGTPaths-Klasse Anwendungsnamen und Co angibt. Das Öffnen einer beliebigen URL als Stream (sofern ein entsprechendes Protokoll implementiert ist) geht dann so:
Observerbasiertes Datenmodell TGTBaseObject bietet drei sog. EventLists, die eigentlich nichts weiter als Observer sind (Bevor jetzt irgendwer gegen das veraltete Observer-Modell rantet: Es ist mir egal). Eine für Änderungen, eine für Freigabe und eine für Änderungen an Properties. Bis auf die für Freigabe müssen diese explizit durch protected-Methoden aktiviert werden (will sagen, man muss z.B. DoChange in einem Setter aufrufen, um ein Event über die Change-Liste zu verschicken). Diese Events verwende ich z.B. im X³-Toolset, um automatische Verwaltung von Objekten und aktualisierung der GUI zu erlauben. Man kann praktisch bei jedem Objekt vom Editor einfach .Free aufrufen und es entfernt sich aus allen Listen, wo es referenziert wird. Die Verwendung dieser Observer ist natürlich optional, aber es ist hilfreich .
Sessions Ein Session-Objekt im GT-Jargon ist sowas wie ein Workspace, wo alle für das Arbeiten im Programm relevanten Informationen gespeichert werden. Das ist eher für Editoren als für Spiele oder sonstige Anwendungen gedacht. Diese Klasse bietet einige Methoden, die das reagieren auf Änderungen in den Daten erleichtern (über die angesprochenen Event-Listen). Dabei sind auch Filter möglich, sodass z.B. ein Handler nur für Änderungen an Objekten, die von TX3Asteroid ableiten, aufgerufen wird.
Streamfilter Das GT bietet schöne Basisklassen, um eigene Dateiformate zu realisieren, die automatisch auf Integrität geprüft werden. Dazu leitet man so eine TGTFileStream Klasse ab und implementiert in den dortigen Methoden das, was auch immer notwendig ist. Zum Beispiel entpacken über zstream oder das überprüfen eines Headers.
Editorklassen Wie gesagt, das GT entstand im Kontext des X³-Editors, deshalb hat es einige mächtige Editorwerkzeuge. Darunter eine Basisklasse für beliebige Editoren, mit Methoden um beispielsweise Menüs oder ähnliches in die umgebende GUI einzufügen. Außerdem eine abgelittene Version des bekannten PropertyEditors, die schönere Anzeigenamen für Properties über eine separate Registry erlaubt. Auch Enum-Wertenamen können so überschrieben um in der GUI schön auszusehen. So kann man den PropertyEditor auch verwenden, wenn man eine Anwendung schreibt, die nicht nur für Entwickler sein soll.
Helferlein Im gtstruct-Paket finden sich auch noch Klassen, die man gelegentlich brauchen kann, wie z.B. einen Threadsicheren FIFO oder eine schnelle Map von Integer zu irgendwas beliebigen.
Node-Network Wenn man komplexe Datenverarbeitung hat und an die grenzen heutiger CPU-Kerne stößt, ist es oftmals nicht einfach, die in Threads aufzuteilen, um Mehrkernsysteme optimal zu nutzen. Man hat erstmal viel mit Synchronisationsproblemen zu kämpfen, die aufwendig debuggt werden müssen. Daher habe ich mich entschlossen, das Verarbeitungsframework aus meinem Signalverarbeitungsprojekt zu abstrahieren und dem gametoolset (was nun bei weitem nicht mehr nur für games zu gebrauchen ist) angefügt.
Über Kommentare würde ich mich freuen. Ich gehe aber nicht davon aus, dass das sofort jemand testen wird, das wird wohl eher für neue Projekte interessant sein.
greetings
_________________ If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung. current projects: ManiacLab; aioxmpp zombofant network • my photostream „Writing code is like writing poetry“ - source unknown
„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb
Registriert: Do Sep 02, 2004 19:42 Beiträge: 4158
Programmiersprache: FreePascal, C++
Ich hab nen bisschen was gebastelt. Die URI-Basisklasse hängt nun mit in gtcore, aber keinerlei Protokoll wird dort implementiert. Dies wurde gemacht, damit die TGTBaseObject Klasse SaveToURL und LoadFromURL Methoden anbieten kann (just for convenience).
Außerdem gibts nun schon ganze zwei examples: a) config: Ein einfaches Konfigurationsbeispiel. Erstellt eine Config-Datei (in den Standardpfaden) und man kann auf denkbar einfachste Weise dort Werte manipulieren: Mit einer aus RTTI-Editoren zusammengesetzten GUI.
b) fifo: Eine einfache Threading-Demo, die die benutzung des TGTThreadFIFO demonstriert. Eigentlich Multi-Threading-Basics, aber vielleicht dennoch hilfreich.
Dies kann noch nicht als release gewertet werden und ist daher erstmal nur im devel-Branch des Repositories. Bei der Gestaltung der Branches richte ich mich übrigens nach A successful git branching model. Damit fährt man wirklich gut, kann ich nur empfehlen. Und branches sind ja bei git wirklich was schön einfach zu bedienendes.
greetings
_________________ If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung. current projects: ManiacLab; aioxmpp zombofant network • my photostream „Writing code is like writing poetry“ - source unknown
„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb
Registriert: Do Sep 02, 2004 19:42 Beiträge: 4158
Programmiersprache: FreePascal, C++
Als ich mich auf der Zugfahrt gestern eigentlich mit Signalanalyse befassen wollte, bin ich auf ernsthafte Probleme mit dem FIFO gestoßen. Ich musste einiges ändern, um eine Race Condition und einen Deadlock zu fixen. Die Fixes werden vermutlich die Gesamtperformance des FIFOs verringern. Die neue Unit ist schon im devel-Branch im Git, Release kann erst später folgen, da einige Dinge so nicht auslieferbar sind (und das Beispiel ggf. noch überarbeitet werden sollte). Es gibt jetzt ein explizit blockendes Pop im Fifo, welches generell eher benutzt werden sollte, wenn man nicht auch Pop benutzt (dann kann WaitData+Pop besser sein). Demnächst muss dann noch ein timeout implementiert werden, aber dafür muss ich noch Funktionen für Windows und MacOS suchen, das wurde nämlich noch nicht in die FPC-RTL portiert (ich nutze die etwas stiefmütterlich behandelten Semaphoren).
greetings
_________________ If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung. current projects: ManiacLab; aioxmpp zombofant network • my photostream „Writing code is like writing poetry“ - source unknown
„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb
Registriert: Do Sep 02, 2004 19:42 Beiträge: 4158
Programmiersprache: FreePascal, C++
Nun gibts erstmal etwas, das man als Release bezeichnen kann. Die Links zum aktuellen Releasetag werde ich im Headpost platzieren. Enthalten sind die bereits genannten Änderungen und Features, außerdem habe ich eine sortierte Queue implementiert, die ich früher schon in einer anderen Klassensammlung von mir hatte und für ein Projekt brauche. Diese (als Generic implementierte) Queue erlaubt es, Double-Werte mit den Elementen zu assoziieren, nach denen diese dann sortiert werden. Ändert sich so ein Wert, muss das der Queue mit der Invalidate-Methode mitgeteilt werden. Die Implementation sollte recht flott sein.
Außerdem gibts für die Clean-Code-Fetischisten (und, weil ich keine Lust hatte, noch ein separates Testprojekt für meine Queue anzufangen) nun Unit-Tests. Die werde ich nach und nach auf die neuen Klassen anwenden, vielleicht auch auf einige alte. Zu finden ist die Testsuite im Unterorder testsuite (überraschung!).
Die Versionsnummer ist einfach mal willkürlich auf 0.8 festgelegt, da eigentlich das wichtigste drin ist, aber dennoch ein paar Dinge fehlen (wie z.B. das Timeout in der Queue) oder ein paar Protokolle für die URL-Implementation. Auch das VFS braucht sicherlich noch etwas feinschliff, die Streamfilter wollte ich sowieso nochmal überarbeiten (was aber wohl erst passieren wird, wenn ich sie das nächste mal brauche).
greetings
_________________ If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung. current projects: ManiacLab; aioxmpp zombofant network • my photostream „Writing code is like writing poetry“ - source unknown
„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb
Registriert: Do Sep 02, 2004 19:42 Beiträge: 4158
Programmiersprache: FreePascal, C++
Ein weiteres Release (Version 0.9, Links im Headpost aktualisiert).
Die größte Neuerung ist das neue Subpaket “nodes”. Dort ist ein Framework für asynchrone Verarbeitung von Daten implementiert. Jeder Verarbeitungsschritt (oder auch mehrere) wird zu einem Thread zusammengefasst und in eine Node gepackt. Diese können dann untereinander verbunden werden, um den Datenfluss zu kontrollieren. Dabei gibt es Typenprüfung, sodass unterschiedliche Datentypen sicher in einem Netzwerk aus Nodes existieren können. Die Node Overmind kümmert sich darum, dass die Threads richtig laufen und keine Aktionen zugelassen werden, die zu einem inkonsistenten Zustand des Netzwerkes führen. Es gibt auch eine spezielle Pseudothreadklasse, die es theoretisch erlaubt, auch Eventbasiert mit den Nodes zu arbeiten. Diese habe ich aber ehrlichgesagt noch nicht getestet (hätte also rein technisch gesehen im devel-branch bleiben sollen…).
Weiterhin habe ich etwas getan, was man eigentlich nicht tun sollte, ich habe ein Interface verändert. IGTLoaderContext wurde aufgespalten, da das Template-Feature vom Gametoolset noch nie benutzt wurde und der Zwang, diese Methoden zu implementieren, sobald man einen Loader Context haben will, nicht angemessen ist.
Im struct-Paket ist eine neue Klasse hinzugekommen, ein Ringbuffer. Dieser erlaubt schnellen synchronisierten Datenfluss zwischen Threads. Da sowohl Schreiben als auch Lesen blockend sind, ist er wirklich nur für multithreading gedacht. Er ist von TStream abgelitten, um maximale Kompatibilität zu erlauben. Der Ringbuffer führt, abgesehen von dem Delay zwischen dem Schreib- und Leseaufruf bzw. dem Delay zwischen der Zeitzuteilung an den Schreib-/Lesethread, keine Latenz in den Datenstrom ein.
Ein Anwendungsbeispiel für die Node-Geschichte ist digitale Signalverarbeitung. Dort kann man die verschiedenen Filter in Threads packen, sodass man z.B. die Kanäle eines Audiostreams parallel auf unterschiedlichen Kernen verarbeiten kann. Oder wenn man zwischendurch zwei Signalpfade hat (z.B. beim Frequency Shifting), die sich aus einem Ausgangssignal heraustrennen, können diese wunderbar automatisch parallelisiert werden. Da die Scheduler von modernen Betriebssystemen (keine Ahnung, wie das bei Windows aussieht) recht flink sind, hat man auch bei mehr Threads als Kernen noch brauchbare Performance.
have fun
_________________ If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung. current projects: ManiacLab; aioxmpp zombofant network • my photostream „Writing code is like writing poetry“ - source unknown
„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb
Mitglieder in diesem Forum: 0 Mitglieder und 0 Gäste
Du darfst keine neuen Themen in diesem Forum erstellen. Du darfst keine Antworten zu Themen in diesem Forum erstellen. Du darfst deine Beiträge in diesem Forum nicht ändern. Du darfst deine Beiträge in diesem Forum nicht löschen. Du darfst keine Dateianhänge in diesem Forum erstellen.