DGL
https://delphigl.com/forum/

Radon Framework
https://delphigl.com/forum/viewtopic.php?f=13&t=9518
Seite 2 von 5

Autor:  TAK2004 [ Mi Apr 25, 2012 11:18 ]
Betreff des Beitrags:  Re: Radon Framework

Seit dem letzten Post sind wieder einige Sachen passiert, ich muss mich mehr anstrengen mehrere kleine Posts, statt wenige große zu schreiben.

Thread Pool

Ich habe den ThreadPool weiter ausgebaut und nun gibt es auch Serielle Tasks.
Ein Serieller Task stellt sicher, dass die Reihenfolge der Ausführung eingehalten wird.
Wenn man z.B. den Logger als concurrent Task betreibt, dann kann es sein, dass 2 aufeinander folgende Logeinträge verkehrt herrum ausgegeben werden, weil ein Thread, der den 2. Task bearbeitet schneller war als der, der den ersten Task bearbeitet.
Daher die serielle Task Strategie, damit das alles schön geordnet läuft ^^

Man kann nun auch sicher sein, dass alle Task fertig gestellt werden, da nun eine neue Shutdown Methode vom Quit Code aufgerufen wird und diese fährt den Pool runter, wartet bis alle Tasks fertig sind und beendet dann erst.
Ich hatte das Problem, dass noch Tasks im Pool lagen, die auf die Console ausgegeben werden sollten und dies passierte nicht, sogar schlimmer, die Konsole war schon abgeräumt und der Task hat dann ein Fehler geworfen.
Da ich an der Klasse noch ein bisschen schraube werde, um später auch ASYNC API's drüber zu machen, habe ich schon mal auf sämtliche Klassendaten das Pimpl Pattern angewendet. Der Pool ist eine Grundlegende API und Änderungen würden unnötig lange Compilerzeiten bedeuten.

Processor

Es gibt nun eine API, welche das erfasssen von der CPU ermöglicht, dabei sind mehrere Layer verfügbar.
Der tiefste Layer(CPU Architekturabhängiger Code) kapselt den cpuid Befehl und das erfassen aller Level + extension Level.
Der nächste Layer(OS abhängiger Code) kümmert sich um das verarbeiten der CPU-Daten, liefert Informationen über die Logischen Prozessoren, auf welchen der Prozess läuft, auf welchen er forciert werden soll und noch ein bisschen unabhängigen Code für Interpretation.
Der 3. Layer existiert noch nicht, der Code liegt aktuell im 2. Layer und wird irgendwann mal durch ein refactoring raus wandern.

Ich kann im aktuellen Code schon ein Binary mit in die executable packen, im Binary bestimmte Werte setzten und dann auf dem 1. Layer laden lassen. So wäre es möglich SSE, Atomic Operation oder Cache optimierungen zu forcieren, ohne dass die CPU bekannt wäre. Sowas macht auf Consolen und Mobile Devices Sinn, wo man z.B. kein cpuid aber die Specs hat.
Die RF API nutzt den 2. Layer und später den 3. um Laufzeitoptimierungen zu machen.
Der ThreadPool z.B. erstellt meinem i5, mit 4 Logischen Prozessoren 8 Threads aber auf ein i7 wären es 16 Threads, da HT verfügbar ist und somit das System 8 Logische Prozessoren besitzt.
Für eine optimale Auslastung der CPU, soll man die doppelte Anzahl von Logischen Prozessoren verwenden.

Unit Test

Die Unit Test API unterstützt nun auch Errorausgabe, welche vom Jenkins Job dann mehr Informationen liefert und ich schneller fixen kann.

BitSet

Die BitSet Klasse ist fertig und auch mit Unit Tests versehen.

Parameter

Es gibt nun eine API für das verarbeiten von Parametern. Dabei legt man Regel fest, welche aus kurzer Name, langer Name, Argument Typencheck, Beschreibung und die Notwendigkeit, der Regel, bestehen können.
Man übergibt dann eine Liste von Strings, den Regelsatzt und bekommt dann Informationen ob alle okey ist und eine Liste der zutreffenden Regeln und dessen zugewiesenden Argumente.
Code:
  1.     AutoPointerArray<String> param(new String[argc],argc);
  2.     for (UInt32 i=0;i<argc;++i)
  3.         param[i]=String(argv[i]);    
  4.  
  5.     AutoPointerArray<OptionRule> rules(new OptionRule[ApplicationOptions::MAX],ApplicationOptions::MAX);
  6.     rules[ApplicationOptions::Executable].Init(0,0,OptionArgument::Text,"Path to application.",OptionRule::Required);
  7.     rules[ApplicationOptions::DumpCPUID].Init("d","dump",0,"Dump all cpuid levels.",OptionRule::Optional);
  8.     rules[ApplicationOptions::DumpSpecifiedCPUID].Init("dl","dumplevel",OptionArgument::Numeric,"Dump the specified cpuid level.",OptionRule::Optional);
  9.     rules[ApplicationOptions::GenerateJson].Init("g","generate",0,"Generate a report, in json format.",OptionRule::Optional);
  10.    
  11.     if (Parameter::Parse(param,rules))
  12.     {
  13.         if (Parameter::Values()[ApplicationOptions::Executable].IsSet())
  14.             LogInfo("Executable: %s",Parameter::Values()[ApplicationOptions::Executable].Value().c_str());
  15. ...

Das ist nun keine gute Allroundlösung wie z.B. bei Boost oder getopt aber es ist wesentlich verständlicher und der Code ist sehr klein und einfach. Wenn man Komplexere Regelwerke benötigt, dann kann man den Code erweitern oder halt Boost und getopt mit ins Projekt nehmen.

String

Ich hab die String Klasse von einem Template zu einer normalen Klasse gemacht und ShortString, sowie LongString raus geworfen.
Eine Änderung an der String Klasse hat gut 30 Sekunden Kompilierzeit mit sich gezogen, weil es ein Template mit fast 2000 Zeilen Code war und diese in fast jeder anderen Klasse verwendet wird und diese damit auch neu Kompiliert.

Bugfixes

Ich hab einige Code style änderungen gemacht, damit cppcheck glücklicher ist.
Nach einigen Monaten Coden ist tatsächlich mal ein Memleak rein gekommen, wenn man auf 32Bit Prozess Emulation geprüft hat, wurde unter Linux in 2 Codepaths nicht aufgeräumt.
Unter Linux wurde für die high resolution counter Methoden der falsche Befehl verwendet, welcher sehr langsam und ungenau war.
Des weiterem ist die Auflösung nun nicht mehr auf 10ns beschränkt sondern nutzt die bis zu maximal 1ns, was aber beim kombinieren von sämtlichen Time Klassen beachtet werden muss, da diese auf 10ns Resolution arbeiten.

Autor:  TAK2004 [ Fr Mai 25, 2012 14:28 ]
Betreff des Beitrags:  Re: Radon Framework

Wieder ist 1 Monat rum und trotz Diablo3, mein nächste Woche anstehenden Umzug nach Berlin, in das Projekt Drakensang Online und die übernahme eines größeren Projektes bei Part-Time-Scientists hab ich trotzdem noch ein bisschen was geschafft :)

Build process

Ich hab ein bisschen Zeit in das Buildsystem gesteckt, nun sind kleinigkeiten, wie VC++ builds mit exceptions raus.

Platformspezifische Dateien werden nun immer im Projekt angezeigt aber nicht mit gebaut.

Alle Projekte werden nun in Virtuelle Ordner ein sortiert z.B. "Demos->Portable" und "Demos->Network->TCPServer".

Es gibt nun eine Option, um ein VisualGDB fähiges projekt mit zu generieren.
VisualGDB ist eine kostenpflichtiges Addon für VS und erlaubt das bauen und debuggen von gcc kompilierbaren code.
Ich habe mir eine Lizenz zugelegt, da ich nun Windows und Linux parallel in VS entwickeln und testen kann.
Natürlich bin ich nicht nur auf Linux beschränkt, alle OS, die gcc supporten kann ich mit aufnehmen, da ich aber nicht vor habe in naher Zukunft Mobile oder Mac zu supporten, bleibt es bei Windows und Linux.

Der Konfigurationsprozess hat sich erheblich verkurzt, da nun nicht noch ein Programm zum testen von 32 oder 64 bit pointer gebaut werden muss. Hierfür nutzte ich eine CMake interne Lösung. Nun gibt es nur noch ein extra Programm für Endianness check.

Ein Stück Code, der nicht mehr gebraucht wird ist raus geflogen und macht die Konfiguration Datein etwas übersichtlicher, okey eigentlich sind es mehr die Kommentare, die nun geschrieben habe ^^

Refactoring

Der letzte Monat stand im Zeichen des Refactorings, da ich einige kleine aber auch sehr große Änderungen vorgenommen habe.

String

Die String Klasse ist nicht länger ein Template.
Ich habe in der Vergangenheit den String als Template angelegt, damit man neben den 4-8byte pointer noch die Wahl hat den Längentyp fest zu legen und somit zwischen Short, Long, ... Möglichkeiten zu differieren und ein paar Bytes sparen zu können.
Dies habe ich aber nie irgendwo benutzte und es bringt viele Nachteile mit sich, template für ein Basistyp zu verwenden.
Der String-Header ist nahezu in jeder Source File direkt oder indirekt inkludiert und damit wird natürlich bei einer Änderung das ganze Projekt neu gebaut. Nicht gerade das was man will, wenn man Optimierungen, kosmetische Änderungen oder Erweiterungen vor nimmt.

System

Die Init und Quit Funktion vom Framework haben nun weitere Aufgaben bekommen.
So wird im Init die CPU überprüft, dass ist der gleiche Code, welcher im HardProf projekt verwendet wird.
Die Informationen, die daraus resultieren, werden im ThreadPool verwendet, damit eine Optimale Workeranzahl verfügbar ist.
Dies ist damit die erste Runtime Optimierung, die abhängig von der Hardware passiert.

Sockets

Die Netzwerk API ist von Grund auf neu gemacht, es sind einige Klassen raus geflogen, die API ist nun kein Service mehr sondern in System und Network high level unterteilt. Dies erlaubt eine menge Optimierungen in der Verwendung von Netzwerk Code, da kein Layer da zwischen liegt, der immer aufgerufen wird und keine Konvertierungen auf dem Weg passieren müssen.
Es gibt nun auch select support, welcher das zusammen fassen von mehreren Sockets zu einem Pool ermöglicht.
Demos für die API sind angepasst und es gibt auch ein paar neue.
Der Codeumfang für die Netzwerk API hat sich trotz neuer Funktionalität ca. halbiert.

HTTP

Die Erweiterung der Netzwerk API, durch HTTP und HTML hab ich vollständig raus gekickt.
Der Code war zu Anwendungsspezifisch und mehr ein Hack als wiederverwendbarer Code.
Ich habe nun angefangen die Teile, die für REST Services notwendig sind zu implementieren.
Dabei zerlege ich ganz klar das parsen und generieren von den einzelnen Bausteinen im HTTP Protokoll 1.0 und 1.1 sowie die höhere logische Verknüpfung zu einem Client oder Server.
RadonFramework soll kein Web Server anbieten, nur einige der Mittel um sich einen zu bauen.

Sonstiges

Es gab diverse kleine Fixes, damit der Code wieder unter Linux baut.
Fixes für mehrere kleiner Bugs.

Autor:  TAK2004 [ Mi Okt 24, 2012 17:51 ]
Betreff des Beitrags:  Re: Radon Framework

Ich hab viele viele dinge seit der Letzten Version gemacht aber ich will mich auf ein wohl für jeden OGL sehr interessante Änderung beschränken aber diese ist auch recht umfangreich in der Erzählung.

Aktuell überarbeite ich meine Repräsentation, als Application Managment Pattern nutzte ich da PureMVC.
Die View wird über Vektorgrafiken und Texturen Basis Widgets anbieten.
Alles wird in 3D gerendert und ich wollte dafür sorgen, dass ich nicht wie bis jetzt viele Klassen für VBO, Shader und co, für jeden OpenGL Context brauche und noch dazu so stark an OpenGL Version oder einer Rendertechnik binden.
Daher hab ich beschlossen ein OGL Context für die beiden arten von OpenGL Context zu behalten, alle OpenGL API Kapselung Klassen zu entfernen und statt dessen 2 neue Klassen ein zu führen.
Shape und NativeShape sind die neuen Klassen, die sehr viel Magischen Staub besitzten ^^
Shape ist eine Spezifische Highlevel Implementierung, aktuell 2D Shapes.
Diese enthält mein Stiel von Rendertechnik und generiert Code für NativeShape.

NativeShape ist eine generierte Klasse, welche eine sehr Primitive OpenGL bezogene Virtual Machine ist.
Also es kommt ein bytestrom rein, dieser wird von der VM in OpenGL function calls und Hilfsoperationen interpretiert.
Der ganze Code ist generiert, weil ich natürlich mit jeder neuerung von OpenGL oder Anforderung von Platformen keine Lust hab die Specs durch zu gehen und braindead Arbeit zu machen.
OpenGL stellt Spec files für jede Version und ich hab ein c lib geschrieben, welche diese parsen kann und logisch verknüpft.
Darauf hab ich ein weiteres C Programm geschrieben, welches mir mein C++ Code generiert.
Dabei gebe ich an, welche Core Version, mit/ohne Extension und ARB will und bekommen dann fertigen Code, welcher jeder Funktion eine ID zugewiesen hat, die Sprungtabelle für die VM erstellt und diverse kleinigkeiten, wie maximale Parameteranzahl für die OpenGL calls, Anzahl der Parameter,größe und Type für jeden Call zurück gibt.
Die VM ist Register basiert, da dies mehr Platz für optimierung lässt.
Performancetechnisch ist das alles sehr angenehm, da schon das Zeichnen eines einzigen 3Ecks 90% Zeit auf der GPU braucht und 1% in der VM, die restlichen 9% sind MessageLoop und sonstiger overhead.
Die VM erlaubt mir einen sehr entscheidenen Vorteil als Framework.
Ich bin mit einem Model/Texture/Shader/... Format in einem unterwegs und es geht nicht mehr Hardwarenäher. Jedes existierende Format kann in dieses Konvertiert werden und damit biete ich die best mögliche Flexibilität, jeder kann sein eigenen Render drauf packen und man kann auch recht gute statische Analysen machen.
Zu prüfen, ob ein glBegin(GL_QUADS)... glEnd(); wirklich ein vielfaches von 4 Vertices enthält ist ein leichtes und tests könnten auch wesentlich komplexer werden.

Zurück zum Shape.
Meine Shape Klasse kann mehrere Path Objekte aufnehmen und generiert dann Bytecode für das NativeShape.
Path lehnt sich sehr stark an ein SVG Path an, also MoveTo, LineTo, CurveTo und Fill.
Bild
Das Bild ist von gestern und Zeigt ein Shape, welches aus 1 Path und einem Rectangle(abgeleitet von Path) besteht. Die Daten hab ich mir aus dem von Inkscape generierten svg file abgetippt.
Die Rundungen werden in dem Bytecode per BezierCurve interpolation in mesh tesseliert aber die Shaderbasierte Alternative funktioniert auch ist aber in anderem Prototyp Code.
Sobald ich nun noch Stencil Test basiertes Füllen für radial und gradient zum laufen bekommen hab werde ich den Code von Prototyping in Productive Code umbauen.

Ich hab leider recht wenig Erfahrung mit JIT und VM, daher wird da noch sehr viel Luft für Möglichkeiten und Optimierung sein.
Hier mal Links zu den Interessanten Files.
Generierter Header für OGLM
Generierter Source für OGLM

Source für spec und tm file parser
Source für spec und tm file parser
Beispiel Source für die Lib(mein OGLM source generator)

Autor:  TAK2004 [ Do Okt 25, 2012 12:35 ]
Betreff des Beitrags:  Re: Radon Framework

Ich hab nun Stencil Buffer und Füllen von Path eingebaut.
Bild
Aktuell wird ein screenspace rect mit dem gradient farben gezeichnet(proof of concept).
Heute werde ich dann aber aus den Füllinformationen ein Mesh generieren lassen, welches dann zum füllen gezeichnet wird. Dies ist dann zum ersten Korrekt mit der Position und ausrichtung und 2. um einiges weniger Code, denn der ist aktuell recht umfangreich.
Sobald das Füllen von Gradient, Radial und Textur sauber implementiert ist, kann ich mich darum kümmern ein svg Importer und OGLM exporter in mein Converter zu bauen.

Ich hab ein Tool mit im Framework, welches Converter heisst ^^.
Dieses Programm überwacht ein Ordner und konvertiert alle sich ändernden Datein und informiert alle Verbundenen Clients über das sich veränderte Asset.
Der Client kann dann darauf das Asset austauschen, ohne neu zu starten.
Dieses Seperate und aktive Tool hab ich geschrieben, weil ich nicht im Framework die einzelnen Formate, die Entwickler mögen zu importieren und zu pflegen.
Das Tool wird bald in ein seperaten Repo landen und dank Plugin System kann man auch schon Libs verwenden die lgpl und co sind, ohne weiteren Code zu infizieren.
Ich bau dann mit Inkscape die Shapes für einzelne Widgets, exportier die in svg, die werden dann in OGLM konvertiert und diese werden vom Framework verwendet.

Autor:  TAK2004 [ Mi Nov 21, 2012 18:53 ]
Betreff des Beitrags:  Re: Radon Framework

Ich hab mich mal wieder dabei ertappt, dass ich zuviele Baustellen aufgemacht hab und zu wenige abschliesse.
Ich hab z.B. eine OpenGL Machiene angefangen, die ByteCode in OpenGL Calls umwandelt, ein Converter Tool, welches ein Ordner überwacht und mit hilfe von Plugins Medien konvertiert und alle verbundenen TCP Clients benachrichtigt.
Desweiteren hab ich noch die Client/Server Architektur ausgebaut dass ich Protokolle verändern kann ohne neu zu starten(Filewatcher+PluginSystem+HotSwap) und dann hab ich immer noch HardProf auf der Liste. Die Tage kam dann noch ein Code Cleanup dazu und dann sind noch 2-3 Sachen im Linux Port offen.
Alles im allen wieder zuviele Baustellen.
Ich werde mir daher nun erstmal alle Task zusammen suchen und sortieren.
Danach kann ich erstmal das Ausmaß des Chaos erblicken und mir gedanken machen, wie ich das reduziere.
Ich ertappe mich immer wieder dabei, dass ich viele Baustellen auf mache, ein proof of concept fertig hab aber selten zum finalen Code komme.
Aktuell hab ich auch noch kein Schimmer wie ich in der Zukunft Herr dessen werde, denn es ist auch ein bisschen frustrierende soviel Arbeit an zu häufen, noch mehr Task im Hinterkopf zu haben und letzlich so wenig ab zu schiessen.
Wenn wer Tipps hat immer her damit.

Autor:  TAK2004 [ Fr Dez 07, 2012 12:17 ]
Betreff des Beitrags:  Re: Radon Framework

Ich hab nun ein neuen Masterplan ausgeheckt.
http://www.radonframework.org/projects/rf/wiki/DeveloperManualTrunk

Ich hatte überlegt was so schief gelaufen ist und folgende Probleme fest gestellt.
  • kein Zieltermin für eine Version
  • keine definition, wie eine Version aussehen sollte
  • kein langzeit Ziel
  • unzureichende Infrastruktur, um zu testen

Ich hab nun 3 Wochensprints und eine genaue Definition eines Sprintendes.
Mein erstes Langzeitziel ist die Umsetzung der Infrastruktur, zum testen, Code aufräumen und kritische Tests schreiben.

Die Infrastruktur besteht aus einem esxi Server mit diversen Betriebsystemen, welche jeweils in 32Bit/64Bit Version vor liegen und alle sollen zu einem Jenkins Build-Grid zusammen geschlossen werden.

Unter Code aufräumen befinden sich aktuell 3 Punkte.
  • alle Platformabhängigen Calls sollen nach RadonFramework/System und alles was in System liegt und dem nicht entspricht aus System raus
  • System code soll nicht länger mit Service Locator Pattern und #ifdef (OS) Konstrukten arbeiten, sondern über ein neues template konstrukt
  • reduzierung der Warnings in CPPCheck und entfernen aller compiler warnings

Mit kritischen Tests meine ich Systemabhängigen Code, denn dieser ist am zerbrechlichsten, da er für jede Platform neu geschrieben ist.
Ein Bug dort zieht sich 100% durch das ganze Framework.

Autor:  TAK2004 [ Do Jan 24, 2013 14:25 ]
Betreff des Beitrags:  Re: Radon Framework

Der Masterplan hat sich schon mal als gute Idee entpuppt aber natürlich gibt es so kleine Probleme.
Ich hatte gehofft, dass ich mit einem 3Wochen Sprint meine Tasks besser organisiert bekomme und weniger in die Sprints rein packe aber die Realität sieht dann in etwa wie folgt aus.

Sprint Problematik
Nur eine Hand voll kleiner Tasks sind im Sprint gelandet und es sind ja 3 lange Wochen dafür da.
Dann hatte ich sehr viele Abenden und Wochenenden keine Zeit und die Tasks wurden irgendwie nicht fertig und so langsam nahte das Ende.
Ich hatte mich an die Umsetzung der Agenda gemacht und entsprechend alle Demos raus geworfen, Systemcode getrennt und Performance Tests eingebaut.
Jenkins könnte nun rein Theoretisch statische Code analyse, Doku, die ganze palette von valgrind(thread safe, cache usage, memcheck,...), junit performance und unit tests machen, wenn nicht gerade neuer Systemcode für ein Laufzeitcrash unter Linux sorgen würde.
Dieser Crash besteht immer noch und hindert mich an der beendigung der eigentlichen Tasks.
So viel das Kartenhaus zusammen und ich hänge nun schon einige Tage über den Sprint hinaus.

Als Lösung will ich nun Themen orientierte Sprints ausprobieren.
Der Sinn dahinter ist, dass ich ein Thema, wie z.B. "OpenGL Machine muss Guideline Konform sein" für ein Sprint habe.
Das bedeutet, keine warnings, errors oder ähnliches dürfen mehr von dem dazugehörigen Code kommen.
Der Sprint läuft nicht mehr Zeitlich aber dafür gibt es nur Tasks die direkt zu diesem Thema gehören und der Sprint ist abgeschlossen, sobald die dazu gehörigen Task fertig sind.

Ich hatte gehofft, dass ich durch die Zeitlichen Bedingungen effizienter Tasks abarbeiten kann aber es liegt nicht daran, dass ich nicht effizient an den Tasks arbeite, sondern einfach viele andere Dinge in der Freizeit zu tun habe, die nicht mehr Arbeitspenzum zu lassen.

Geschaffte Arbeit
Ich hab einiges geschafft, so konnte ich z.B. einigen toten Code entfernen, OpenGL Rendering raus werfen, einiger Code ist verschoben und natürlich gab es reafactoring im System Namespace.

Ich wollte früher eine abstrakte Möglichkeit bieten, OpenGL 1-4 gewrappt an zu bieten aber das ist nicht nur viel Arbeit, sondern muss auch gepflegt werden und macht für das Entwickeln einer Game Engine z.B. wenig Sinn, da man eigenen spezialisierten Code hat.
Daher ist dieser ganze Teil raus geflogen und übrig sind nur die OGL Context für die einzelnen Versionen und die OpenGL Machine(OGLM).
Über OGLM hab ich ja schon in den vorigen Posts geredet und sehe es als sehr guten Weg für Render Code aufbauten.
Ein späterer Task wird sein, GLEW raus zu werfen, da es eine Menge "style" warnings bei cppcheck wirft und ich den notwendigen Code auch automatisiert generieren kann.

Ich hab alle Demos raus geworfen, da ich viel Zeit investieren musste, um diese zu pflegen und automatisierte Tests zeigen genauso gut wie man die API nutzt.
Daher hab ich auch noch die Performance Tests eingeführt und es werden noch Smoke Tests folgen.

Meine Arbeit wird nun erstmal darin bestehen den runtime Bug in Linux zu beheben und beide Versionen auf den gleichen Stand zu bekommen. Der System Code hat meine volle aufmerksamkeit :)

Autor:  TAK2004 [ Fr Jun 28, 2013 15:57 ]
Betreff des Beitrags:  Re: Radon Framework

Mensch hab ich lange nix mehr geschrieben ^^

Ich arbeite natürlich immer noch am Framework, auch wenn ich in den letzten Monaten nicht so viel gearbeitet hab wie vorher üblich.
In der zwischenzeit hab ich einiges an Code cleanup gemacht, Strukturen refactored und System API stärker getrennt.

Neue System API
Ein großteil der System API läuft nun vom RadonFramework.System namespace aus und hat ein anderen Programmierstiel als der restliche Code.
Für jeden Systemcall wird nun ein Callback
Code:
  1. typedef RFCT::String (*ApplicationDirectoryCallback)();

und external definiert,
Code:
  1. extern ApplicationDirectoryCallback ApplicationDirectory;

im cpp file wird dieses 0 gesetzt und deklariert.
Code:
  1. ApplicationDirectoryCallback RadonFramework::System::IO::FileSystem::ApplicationDirectory=0;

Für die einzelnen sub-namespaces, wo die Callbacks hinterlegt sind gibt es eine Funktion, welche Abfragt ob alle Callbacks korrekt dispatched wurden, eine welche die Funktionen dispatched und eine Debug Funktion, welche die nicht dispatchten Funktionen zurück gibt.
Code:
  1. Bool RadonFramework::System::IO::FileSystem::IsSuccessfullyDispatched();
  2. void RadonFramework::System::IO::FileSystem::GetNotDispatchedFunctions(List<String>& Result);
  3. void RadonFramework::System::IO::FileSystem::Dispatch();

Ich habe eine RAII Klasse Radon, welche im Constructor die Dispatch funktionen von allen System Modulen aufruft.

Nun kommt die Magie des ganzem :)

Stellen wir uns vor, ich will auf eine neue Platform, wo Radon Famework vorher noch nicht gelaufen ist und wir erwarten erheblichen Wiederstand seitens des Betriebssystems und seiner API.
Der Code, welcher gegen das RadonFramework kompiliert wird, würde auf der neuen Platform kompilieren und ausgeführt werden können. Der läuft sehr wahrscheinlich recht schnell in eine Nullpointer Exception aber es sollte kompilieren und starten.
Der Grund liegt darin, dass alle Klassen von RF und natürlich der TestApp gegen die SystemAPI vom RF gelinkt ist und das sind Callbacks.
Dieser Callback ist ein einfacher C-Funktionspointer, welcher 0 initialisiert wird und je nach Platform bzw. System Funktion durch eine gültige Funktion gepatched wird.
Ein C-Funktionspointer benutzt die gleichen CPU Instruktionen wie ein normaler function call, also kein Nachteil seiten Performance oder Speicher. Der vorteil ist aber man kann ihn super einfacher patchen, ohne ASM Code zu brauchen oder im Speicher zu fuhrwerken.
Ein nicht dispatchte System Funktion führt zu einer Exception, wo ein guter Callstack raus kommt, der uns sagt wo und welche Systemfunktion uns Probleme macht.
Zusätzlich gibt es noch die Möglichkeit von den Util Funktionen, im Diagnostic namespace, gebrauch zu machen und sich alle nicht gepachten Funktionen zurück geben zu lassen.
Code:
  1. void RadonFramework::Diagnostics::Debugging::FrameworkDiagnostics::GetAllMissingSystemFunctions(Collections::List<Core::Types::String>& Result);


Ich kann also stupide alle fehlenden Systemfunktionen nach rüsten, die mir nach dem Start gelistet werden oder erstmal die die zu abstürzen führen.

Dies ermöglicht mir z.B. eine weile auf einem System zu entwickeln und wenn ich dann auf ein anderes gehe, sehe ich sehr schnell, welche sachen ich noch für dieses implementieren muss.
Ich kann schnell code auf einem anderem System zum laufen bringen und muss mich nicht erst ne weile um den kompilierprozess kümmern oder gar alles mit einmal implementieren, bevor ich die app überhaupt mal starten kann und merke, dass die implementierung murks ist.

Autor:  TAK2004 [ Sa Jun 29, 2013 12:37 ]
Betreff des Beitrags:  Re: Radon Framework

Contentverwaltung vereinfachen mit dem Converter Tool
Heute will ich mal über das Converter Tool sprechen.
Dieses Tool dient dient zur Contentverarbeitung, also das umwandeln von Audio, Bild, 3D, Shadern, was auch immer in Native Datenformate, die vom Radon Framework direkt verwendet werden können.
Der Gedanke ist, dass man beliebige Formate als Intermediate Format verwendet und das Tool die Datein und Ordern überwacht.
Sobald eine Änderung geschieht, springt der Converter an, konvertiert die Daten und benachrichtigt alle verbundenen Clients.
So kann ich mir sparen, eine API für das laden von diversen Dateiformaten zu bauen oder gar selber loader zu schreiben.
Ich will das Radon Framework frei von Dateiformaten halten, wie z.B. Ogg, Mp3, txt, xml oder ähnlichem und der Converter macht dies für mich.

Aktuell kann der Client Ordner über ein FileWatcher überwachen, Plugins laden und alle Clients per TCP über Änderungen benachrichtigen.
Woran ich gerade arbeite ist der Konvertierungsprozess selber.
Dafür hab ich LuaJit angebunden, welches als Scripting Interface dienen soll.
Der Entwickler lädt/schreibt sich Plugins zum laden von Dateiformaten und Processing Funktionen und über die Scripte ist er dann in der Lage in die Standard Pipeline ein zu greifen.
Wenn z.B. ein 32Bit Höhenmap als Tiff geladen werden soll, dann braucht man ein Plugin, welches dieses Format lesen kann und die Daten in das Native Format umwandelt.
In einer Konfigurations Datei, wird festgelegt, welche Dateitypen mit welchem Script verarbeitet werden sollen.
Am Anfang würde man also sagen, dass die Ladefunktion für Tiff verwendet werden soll, um den Datenblob in nativen Daten zu konvertieren und dann würde vom Konverter der Processing Callback aufgerufen werden und ein Native Datenstruktur übergen.
Das Native Format macht das schreiben von Processing Funktionen einfacher, da alle auf die gleichen Datenstrukturen arbeiten und nicht auf den von den vielen Dateiformaten.
Nun soll man dort wie mit Shadern die Daten bearbeiten können, also neue Daten generieren(ein Bild mit doppelter Auflösung), wie beim Geometry Shader und Daten stream manipulieren(interpolation zwischen Pixeln, um zu skalieren), wie bei Vertex/Fragment Shadern.
Zum Schluss werden die Daten geschrieben und an jeden Verbundenen Client wird der Assetname übermittelt.

So kann dann z.B. der Client das neue Asset laden.

Der Grundgedanke ist, das schreiben von Exportern für diverse Content Erstellungsprogramme zu vermeiden und es nur für den Converter einmal zu machen.
Man könnte dann z.B. ein FBX Loader Plugin schreiben und somit dann auf nahezu jedes 3D Tool zurück greifen, statt nur für das wofür man sein Exporter geschrieben hat.
Es soll auch zur Datenverarbeitung dienen, man hat oft, dass man noch Meshes optimieren will, Texturen nachbeareiten oder gar aus Texturen Mesh generieren will oder Prozedurale Texturen generieren möchte.
Dies soll das Tool auch abdecken, was durch das zerlegen in laden, verarbeiten, schreiben in Plugins sowie das steuern über Scripte möglich wäre.

Für mich selbst kommt folgende Pipeline in frage.
Ein FBX Loader lädt die 3D Daten, wandelt diese in Nativen Code um, normalisiere die Vertexdaten, sortiere so dass der niedrigste Overdraw entsteht und Exportiere dann in OpenGL Machine Byte Code(VM Bytecode von Radon Framework).
Die Processing Funktionen schreibe ich in C++ und nutzte OpenCL und pack das dann als Plugins in den Converter Plugin Ordner.
Mein Client hängt an dem permanent laufenden Converter und kann so Hotloading(eine Technik welche es erlaubt Daten zur Laufzeit aus zu wechseln und gerade bei externen Devices deploy und neustartzeiten umgeht) machen.

Autor:  TAK2004 [ So Jun 30, 2013 13:49 ]
Betreff des Beitrags:  Re: Radon Framework

In den vorigen 2 Posts hab ich über das Converter Tool gesprochen, welches ausserhalb des Frameworks verwendet werden kann und vieleicht auch wird und über die neue Lösung die System API zu kapseln.
Nun will ich die restlichen neuerungen noch zusammen tragen, die während der 6Monate Postfreie Zeit geschehen sind.

Datentypen, Architektur und deren Probleme
Ich verwende wie üblich Indices, Schleifen Zähler und Pointerarithmetik und dafür hab ich UInt32, Int32 verwendet aber dies ist nicht der Weg den man gehen sollte. Int32 und UInt32 sind 32Bit Integer signed und unsigned, was auf einer 32Bit Architektur auch wunderbar funktioniert und effizient ist aber auf einer 64Bit Architektur sind diese Ineffizient und nutzen nicht das ganze Potenzial aus.
Die Lösung von C++ STL ist size_t, welches je nach kompilierter Archtitektur zu einem Standard Datentypen umgestellt wird.
Für gcc 64Bit ist dies long long und für gcc 32Bit long.
Sobald es um Speicher und Daten geht sollte man immer die Datentypen nehmen, die das Maximum des Systems nutzen kann.

Ich hab in der Vergangenheit immer UInt32 und Int32 benutzt, weil ich mich stark an .Net halten wollte, wo diese Typen immer praktiziert werden.
Da ich aber gerne das Maximum raus holen möchte bin ich nun wieder auf Size umgestiegen.

edit: Korrektur
Der einzige Haken an dieser Geschichte ist, dass der C++ Standard für post und pre operator ++/-- ein int vor sieht was echt schlecht ist.
Der post increment operator benötigt ein int, damit es vom pre increment unterschieden werden kann aber dieser wird garnicht benutzt und ist damit nicht weiter wild.

Der Datentype int kann je nach compiler und Architektur so ziemlich alles sein, von einem 8 bis 32Bit signed auf 32Bit Architektur und 32Bit auf 64Bit Architektur.

Hardware tracking
Ich habe angefangen die ganze Funktionalität zum erfassen von Profilingdaten(Hardware, Software) in die neue System API und Highlevel Klassen zu zerlegen.
Diese Funktionalität lege ich über eine neue C-Bibliothek für jederman, der kein Radon Framework nutzen will offen.
Die Bibliothek ist natürlich nicht so kompfortabel wie die C++ Klassen, weil ich wegen C-ABI nur mit Funktionen, Pointern und Structs arbeiten kann.
Allerdings hat es Vorteile, wenn man nicht immer alles selber programmieren muss und C-ABI versteht jede Sprache.

Autor:  TAK2004 [ So Aug 18, 2013 16:55 ]
Betreff des Beitrags:  Re: Radon Framework

Ich bastel aktuell an einem Scene Graph, UI und Editor für Radon Framework.

Ich will nun endlich mal ein Datenbank basierten Scene Graph testen und dafür hab ich einen Editor geplant und für ein Editor brauch ich UI, also hab ich erstmal den Multi Window Support von Framework auf fordermann gebracht.
Für das UI hab ich mich entschieden kein eigenes zu schreiben, sondern ein existierendes zu verwenden.
Ich nutzte libRocket, welches ein MVC UI mit HTML+CSS ist.

Das schöne an libRocket ist, dass man alle Framework spezifischen dinge als Interfaces überladen kann.
Für das rendering muss man z.B. LoadTexture, GenerateTexture, ReleaseTexture, EnableScissorRegion, SetScissorRegion und RenderGeometry implementieren.
Man kann auch noch RenderCompilerGeometry, ReleaseCompiledGeometry und CompileGeometry überladen, da kann man z.B. VBO hinter hängen.
Dann braucht man noch GetElapsedTime und muss Keyboard- und Maus-Events übergeben, der rest kann aber muss nicht überladen werden.
So ziemlich jede Funktion, die für das System gebraucht wird, kann man überladen, sei es FileIO, Font, Logging oder bestehende Decorator.
Man kann Das CSS und HTML sehr einfach erweitern, Scripting interface gibt es auch und die API ist sehr übersichtlich.
Die einzige Abhängigkeit, mit der libRocket kommt ist libfreetype und die kann man auch auswechseln.
libRocket hat auch einige Custom Components, wie z.B. Resize und Move Handle, welches zum verschieben und skalieren von HTML Elementen genutzt werden oder auch sehr praktisch DataGrid und Tabs.
DataGrid ist wie von .Net, wo man ein Source per String an gibt und im Code dann über Events auf diese Triggern und Daten zurück geben kann.
Der große Vorteil, es lädt nur notwendige Teile der Daten also die die nur in einer Tabelle oder Liste zu sehen sind und damit skaliert es auch perfekt, wenn man mehrere millionen Datensätze hat, weil es nur ein Subset anfordert und verarbeitet.
Die Tabs sind durch in Tab und Panel Tags realisiert und tut diese in der angegebenen Reihenfolge linear mappen.
Klickt man Tab 9, dann wird Panel 9 aktiviert.
Wenn der Content zu groß ist und man overflow verwendet, dann bekommt man auch Scrollbars, wofür man die Scissor Region Funktionen braucht, um nur ein Teil des Content zu zeigen.
Also kurz um, sehr sehr cool :)

Ich baue aktuell ein Drag&Drop Window System ein, Drag und Drop ist schon in libRocket drin aber ich brauch noch ein bisschen mehr Kontrolle über die Elemente, die hin und her gezogen werden.

Bild

Ich hab für das schnellere Arbeiten mein neuen FileWatcher mit eingebunden, welcher die HTML und CSS Daten neu lädt, wenn diese sich ändern.
Um zu testen wie gut libRocket mit komplexeren Code klar kommt, hab ich mal meine main.cpp über eine Syntax Higlighter, aus dem Web, gejagt und die html und css eingebunden.
Ich musste noch in alle CSS Zeilen nen Semicolon nach rüsten und die Leerzeichen in pre tag funktionierten nicht aber dann kam was schickes raus.
Mit dem Template System hab ich noch nicht gespielt aber in den Demos, von libRocket, werden die Fenster über ein Template erstellt und das funktionierte gut und sah recht nützlich aus.

In disem Video sieht man wie mein Workflow funktioniert.

Mein Scene Graph nutzt Sqlite als Datenbank und im Frontend kommt ein Node, Component System zum einsatzt.
Es gibt ein Nodetree, wo jeder Knoten mehrere Components haben kann, jede Component ist ein Stück logik und Daten.
Das soll wie bei Unity3D funktionieren, dass es Render, Transform und weitere Komponenten gibt, welche man Stacken kann.
Was mir aktuell Probleme macht ist das Databinding, da ich ungern auf Serialisierung setzen will.
Serialisierung hat Vor- und Nachteile und ich versuche aktuell eine Lösung zu finden, die auf POD Structs arbeitet und nicht auf ein Property System.
Eine Lösung wären Versionierte Chunks, wenn man ein Chunk lädt, dann guckt man nach der ID, nutzt den zugewiesenden Loader und bekommt ein POD Struct, dann guckt man ob es eine neuere Version gibt, ruft die Konvertierung auf und das macht man so lange, bis man auf der aktuellen Version ist.
Sollte man dann Speichern, wird die neueste Version gespeichert, damit der aufwändige Konvertierungsprozess nicht mehr auf tritt.
Der Nachteil ist, man muss für jede Änderung eine Konvertierungsroutine bauen aber braucht dann keine Laderoutine schreiben, weil POD ja 1zu1 im Speicher gemapped werden kann(hoch lebe die C-ABI).
Die Konvertierung sollte man in den meisten Fällen mit einem Template vereinfacht bekommen aber das wird sich in den nächsten Wochen zeigen.

Damit ich später auch Nodes und Components bearbeiten kann, baue ich den Scene Editor.
Das Viewer Fenster zeigt die Szene und das Tool Fenster zeigt den Scene Graph, Property Editor und weitere notwendige Fenster.
Damit das ganze erweiterbar ist, hab ich das editieren in ein extra Fenster gepackt und baue dort ein Docking System für Tabs.

Dateianhänge:
capture1_1_x264_001.mp4_snapshot_00.22_[2013.08.18_17.15.43].jpg [107.87 KiB]
Noch nie heruntergeladen

Autor:  TAK2004 [ Di Aug 27, 2013 16:10 ]
Betreff des Beitrags:  Re: Radon Framework

Ich bin kein großer Fan von HTML und CSS, was mir libRocket wieder mal deutlich gezeigt hat.
Man braucht für bestimmte dinge recht umständliche Hacks und die sind auch nicht immer sauber.
Ich versuche aktuell ein Problem zu lösen, was ich so nicht gedacht hätte, dass es in HTML/CSS überhaupt existiert.

Wenn man ein Block 2 Kinder hat und man möchte Kind-A mit einer festen größe dar stellen und Kind-B soll den rest auf füllen, dann ist dies ganz und garnicht einfach. Es gibt Lösungen, welche overdraw aus schalten und über/unter dem anderen Element starten und somit eine korrekte Lösung vorgaukeln aber sobald man dann eine Scrollbar verwendet oder Transparenzen, dann sieht man diese Probleme.

Dateianhang:
layout.png
layout.png [ 9.86 KiB | 42538-mal betrachtet ]


So stelle ich mir das eigentlich vor aber das klappt im Fall von Vertikal Fill-Fixed und Fixed-Fill, sowie Horizontal Fixed-Fill und Fill-Fixed nicht.
Ein weiteres Problem was ich aktuell noch habe sind Aspect ratio und skalierende UI.

Wenn man sich z.B. Dota 2 oder Starcraft 2 an guckt, dann merkt man, dass auf unterschiedlichen Auflösungen die UI mit skaliert und sich auch der Aspect ratio an passt.

Ich hab am Wochenende ein weilchen gegoogelt und probiert aber konnte keines der Probleme Lösen :\
Wenn sich wer in diesem Bereich aus kennt, ich bin für Vorschläge offen.

Mein neuer Scene Graph benutzt das PImpl Pattern für die Klassen, da diese recht häufig im Code vor kommen kann und sich dies auf die Kompilierzeiten auswirkt, hab ich ein Template gebaut, welches auf einem der Boost PImpl Vorschläge basierte und dann stark angepasst.
Ich kann nun Nodes verwalten und will als nächstes diese in einer sqlite DB speichern und lesen.

Autor:  TAK2004 [ Mi Okt 02, 2013 16:26 ]
Betreff des Beitrags:  Re: Radon Framework

Dank Lord Horazont hab ich eine Lösung für mein Problem gefunden und es nennt sich Flexbox.
Flexbox ist ein Spezifikations Erweiterung für CSS2 und soll das Layouting in HTML stark vereinfachen.
XUL Runner benutzt Flexbox für die darstellung von Applikationen und das reicht mir als Beweis, dass es Funktioniert.
Ich hab mir LibRocket geklont und bin dabei eine erweitung zu schreiben.
Alle CSS Attribute und sind drin und werden korrekt gelesen und ich arbeite nun daran den Algorithmus zum layouten um zu setzen.
Ich benutzte noch den Mozilla Code(recht übersichtliche ~4k Zeilen Code) als Vorlage, weil die Specs ganz schön verwaschen beschrieben sind und für mein Geschmack zuviel Luft für Fehlinterpretationen zu lassen.

So langsam programmiere ich auch wieder mehr und hab letztes Wochenende auch einiges am File System API gemacht.
Ich benutze URI's für alles und auf unterster Ebene tu ich die dann in Systempfade umwandeln.
Dabei ist mir ein Fehler aufgefallen, dass ich die URI's escape und das System dies nicht toll findet ^^, daher hab ich erstmal alle Problemstellen mit der unescape Methode ersetzt, damit z.B. Space ein Space wird und nicht %20 bleibt.
Aufgefallen ist mir das, als ich die Fensterpositionen meines Scene Graph Editors im User ApplicationData Ordner speichern wollte und Windows %20 nicht akzeptierte.

Ich hab noch die ApplicationData und User ApplicationData Ordner für Windows hinzu gefügt und das Eventhandling von Fenstern verbessert.
Bis dato hatte ich nicht auf Positionsänderungen reagiert und dies hab ich nun noch integriert.
Im laufe der Integration, zum speichern von Fensterpositionen, hab ich ein einfaches Property System eingebaut, welches nix weiter als ein Hashmap für je ein Datentyp liefert.
Code:
  1. Hashmap<const char*, Int32, hashfnc, cmpfnc, FastOperation<const char*, Int32, hashfnc, cmpfnc> > Int32Properties;

Unabhängig, das das wirklich ekelig aus sieht, hab ich fest gestellt, das ich die ganze Zeit sparse hash table benutzt hab, welches auf Speichereffizienz optimiert ist und ich aber in diesem Fall schnelle Operationen haben wollte und das ist in der google Lib dense hash table.
Also hab ich die Hashmap Klasse erstmal notdürftig umgebaut, dass ich zwischen verschiedenen Implementierungen wechseln kann.
Ich muss mal gucken wie ich das als Policies gut verpacken kann, ohne alles doppelt und dreifach zu schreiben.
Die Performanceunterschiede liegen übrigens zwischen 50-100x schneller aber ist dafür ~3x mehr Speicherverbrauchend.
Boost und tr1 hashmap spielt nicht mal in der Liga und von daher sind beide Lösungen schneller als die mit C++11 standardisierte Hash table.

Da Flexbox noch ein weilchen Zeit in Anspruch nehmen wird, werde ich erstmal parallel eine Treelist bauen.
Damit ich schon mal an mein Editor und mein neues SceneGraph Konzept testen kann.

Autor:  TAK2004 [ Di Okt 08, 2013 10:20 ]
Betreff des Beitrags:  Re: Radon Framework

Winter is comming!
Das merk ich, weil ich wieder mehr programmiere.
Ich hab gestern/heute mich mal meine OpenGL Virtual Machine gekümmert und deren Code generierung.
Khronos hat mit OpenGL 4.4 ihr registry von spec und tm auf xml umgestellt und entsprechend hab ich nun auch mal ein neues Tool geschrieben.
Das neue Format hat ledeglich 2 folgende Probleme.

1.) Parametertypen werden sehr schräg beschrieben.
Code:
  1. <param>const <ptype>GLint</ptype> *const*<name>firstparameter</name></param>

Das Hauptproblem ist die Beschreibung des Parameters, denn ich hab nur für diesen Konzeptfehler gut 3x soviel Code :\
Code:
  1. <param>const <ptype>GLint</ptype> *const*<name>firstparameter</name></param>

Code:
  1. <param><ptype>GLint</ptype> *<name>firstparameter</name></param>

Wie man an den Beispielen sehen kann, gibt es ab und zu post und pre modifier für jeden Typen und das macht das parsen kompliziert.
Man hat soviele Sonderfälle, weil man gucken muss ob es überhaupt ein ptype gibt, dann ob es noch davor und danach ein Knoten hat, der nicht name ist.
Mit Flags kann man das auch nicht erschlagen, dann es auch Konstruktionen wie *const* gibt, was ein pointer auf ein pointer ist.
Ideal wäre gewesen, wenn man dies direkt als Pre- und Post-Tags mit rein gepackt hätte.

2.) Die Parameter haben ein Fehler oder werden noch schräger beschrieben.
Es gibt im XML folgenden sonder Fall.
Code:
  1. <param>const void *<name>firstparameter</name></param>

Das geschulte Auge sollte sich nun fragen. "Wo ist denn der ptype ?" Richtig nicht vorhanden, ein gemeiner Sonderfall, wobei ich von einem Fehler ausgehe, denn es gibt ja den Typen GLvoid, der überall sonnst verwendet wird -_-

Alles im allen aber trotzdem eine verbesserung, da ich nur ein Abend gebraucht hab ein Parser zu bauen und meine Sachen korrekt zu exportieren.
Der Code sieht natürlich noch ziemlich schrecklich aus aber tut sein dienst ^^

OpenGL Registry reader
libSpec.cpp
libSpec.h

OGL VM code generator
main.cpp

Den Code werde ich bei Zeiten mal aufräumen, aktuell ist es ein mixin von altem c code in neuen c++ code ^^

Ich hab dann mal glew geupdated und fest gestellt, das dort einige Bugs in den Funktionsdeklerationen sind.
Mein Plan ist mich von glew zu lösen und das laden von Funktionen mit in den OGL VM zu packen.
So kann ich auch Code gegen den Treiber validieren, wenn es Funktionen für ein Feature-Set nicht gibt, kann ich den Code von der Ausführung Blockieren.

Flexbox
Ich arbeite auch an der Flexbox integration in libRocket weiter und dort geht es auch so langsam aber sicher vorran.
Mal sehen ob ich noch dieses Jahr damit fertig werde, bei der aktuellen Geschwindigkeit wird es knapp xD

Autor:  TAK2004 [ Fr Okt 11, 2013 10:22 ]
Betreff des Beitrags:  Re: Radon Framework

Radon Framework Converter
Ich hab gestern mein Plan für den Converter recht fest geklopft und so wird der Funktionieren.
Es gibt ein Application Data Directory z.B. C:/users/thomas/AppData/Roaming/Radon Framework/Converter und dort liegt eine config.ini sowie der plugins, scripts, assets, export und temp directory.
Wenn nicht anders in der config.ini angegeben, dann guckt er für alle C-Plugins im plugins Ordner, für Processing Scripts im scripts Ordner, der assets Order wird vom Filewatcher überwacht, export werden verarbeitete Assets gelagert und temp wird für temporäre Assets verwendet.
Wenn die App startet, dann wird die config gelesen, es werden alle Plugins geladen, dann die Processing Scripts registriert, dann legt der Filewatcher sich über den assets Ordner und startet ein TCP Server.

Wenn nun ein Asset sich ändert, dann werden alle Processing Scripts aufgerufen und der Dateiname übergeben.
Das Script kann nun entscheiden, ob es auf die Datei reagiert und was es macht.
Ich stelle 2 Funktionen, um Temporären Assets und Exports zu registrieren.
Diese erlauben das speichern in den jeweiligen Ordnern und Exports sendet ein broadcast an alle verbundenen Clients, mit dem export Dateinamen.
Der Client kann den Namen eines export Assets senden und dann sendet der Server als Antwort den File Content.

Die Plugins sind Erweiterungen für die Processing Scripts.
Jedes mal, wenn ein Processing Script ausgeführt wird, werden alle Funktionen, die durch Plugins verfügbar sind registriert.
Als Scripting System verwende ich LuaJit.

Aktuell fehlt das registrieren der Plugin Funktionen im Processing Script und der Filewatcher ist aktuell wieder kaputt.

Seite 2 von 5 Alle Zeiten sind UTC + 1 Stunde
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/