diff options
author | Alex AUVOLAT <alexis211@gmail.com> | 2012-05-01 23:48:56 +0200 |
---|---|---|
committer | Alex AUVOLAT <alexis211@gmail.com> | 2012-05-01 23:48:56 +0200 |
commit | 43d0bb8e3997022e5270f7f75f615a47819c929e (patch) | |
tree | 937992d286966edecf81b405e414230c85d19bad /doc/objects.txt | |
parent | e9683297bf480f9590b0e5796f4520fb430e2e03 (diff) | |
download | TCE-43d0bb8e3997022e5270f7f75f615a47819c929e.tar.gz TCE-43d0bb8e3997022e5270f7f75f615a47819c929e.zip |
Basic object system - THIS IS STILL A LONG WAY TO GO!!
Diffstat (limited to 'doc/objects.txt')
-rw-r--r-- | doc/objects.txt | 181 |
1 files changed, 181 insertions, 0 deletions
diff --git a/doc/objects.txt b/doc/objects.txt new file mode 100644 index 0000000..956ad74 --- /dev/null +++ b/doc/objects.txt @@ -0,0 +1,181 @@ +Let me say this in french. Sorry for english-only-speaking people, i'll translate someday. + +L'idée principale motivant le développement de T/CE est celle d'un nouveau protocole entre le +noyau et les applications utilisateur. + +Les objets du systèmes sont accessibles sous la forme d'un système de fichiers dans lequel on +navigue, sauf que les objets sont en fait bien plus que de simples fichiers. + +Ce protocole se base sur trois définitions fondamentales : +-- Interfaces : +Une interface est un ensemble de définitions (de prototypes, donc) de méthodes qui +peuvent être implémentées par un objet du système. +Parmi les méthodes, il y a des méthodes publiques, faites pour être appellées par les +applications utilisateurs, et des méthodes internes au noyau. +-- Classe : +Une classe, c'est un regroupement d'interfaces avec leur implémentation spécifique. +-- Objet : +Un objet du système est d'une classe précise, et correspond donc à un des objets gérés +par le code de cette classe. On peut appeller toutes les méthodes des interfaces implémentées +par la classe de l'objet sur cet objet. + +Ce n'est peut-être pas très clair, alors illustrons : + +Interface : Keyboard +- OutputToConsole(Console) +Interface : Console +- SetActiveVT (VirtualTerminal) +- NewBufferedVT (char*) // crée un nouveau terminal virtuel - char* = le nom +- (internal) receiveKeyboardInput(int) +- (internal) repaint(char*) +- (internal) write(int, char*) +Interface : VirtualTerminal +- Read(int, char*) +- Write(int, char*) +- (internal) receiveKeyboardInput(int) +- (internal) outputToConsole(Console, int, int) // int, int = dimensions de la console + +Classe : PS2Keyboard +- Garde en mémoire la console à qui il envoie les données +- Quand une touche est pressée/relâchée, appeller receiveKeyboardInput sur cette console +- Implémenter la méthode OutputToConsole pour changer la console à qui les données sont envoyées +Classe : TextConsole +- Implémente la gestion de l'écran texte VGA de base +- Garde en mémoire le VirtualTerminal actif +- Transmet l'entrée clavier au VirtualTerminal actif +- Lorsqu'on lui demande de changer le VT actif : + il signale à l'ancien VT de ne plus émettre, + il signale au nouveau VT d'émettre vers cette console + et spécifie au nouveau VT la bonne dimension d'écran +Classe : BufferedVirtualTerminal +- Il garde en mémoire LA Console vers laquelle il doit émettre, ainsi que ses dimensions +- Garde un buffer de tout ce qui passe sur la console, et un buffer de l'écran actif. +- Lorsqu'il reçoit une entrée clavier, la bufferise, puis la restitue lors du prochain appel à Read +- Lorsqu'on écrit quelque chose dessus avec Write, il le garde dans son buffer + et le donne aussi au terminal virtuel de sortie, s'il y en a un + + +Implémentation : + +// Structures + +struct Interface { + char* name; + int method_count; + int public_method_count; + + NumberedMethod numberedMethods[]; + int methodNumbers[]; +}; + +struct NumberedMethod { + Interface *iface; + int numberInIface; +}; + +type MethodPtr (function pointer type); + +struct InterfaceImpl { + Interface *interface; + MethodPtr methods[]; +}; + +struct Class { + char* name; + MethodPtr *findChild; + InterfaceImpl interfaces[]; //zero-terminated list +}; + +struct Object { + Class *class; + void *data; +}; + +// setup code + +void Class_setup(Class* class) { + for (int i = 0; class->interfaces[i] != 0; i++) { + Interface_setup(class->interfaces[i]->interface) + } +} + +ExpandableTable<NumberedMethod*> allMethods; + +void Interface_setup(Interface* iface) { + if (iface->numberedMethods != 0) return; + iface->numberedMethods = malloc(iface->method_count * sizeof(NumberedMethod)); + iface->methodNumbers = malloc(iface->method_count * sizeof(int)); + + for (int i = 0; i < iface->method_count; i++) { + iface->methodNumbers[i] = allMethods.register(&impl->numberedMethods[i]) + iface->numberedMethods[i]->numberInIface = i; + iface->numberedMethods[i]->ptr = impl->methods[i]; + } +} + +void Object_callByNumber(Object *obj, int number, params...) { + NumberedMethod *method = allMethods.get(number); + for (int i = 0; obj->class->interfaces[i] != 0; i++) { + InterfaceImpl impl = obj->class->interfaces[i]; + if (method->iface == impl->interface) { + MethodPtr fct = impl->methods[method->numberInIface]; + return fct (params...) + } + } + return E_NOT_IMPLEMENTED; +} + +// Exemple + +struct ConsoleMethods { + MethodPtr SetActiveVT; + MethodPtr NewBufferedVT; + MethodPtr receiveKeyboardInput; + MethodPtr repaint; + MethodPtr write; +}; + +Interface ConsoleIface = { + name: "Console", + method_count: 5, + public_method_count: 2, + + numberedMethods: 0, methodNumbers: 0, // internal +}; + +ConsoleMethods TextConsole_as_Console = { + SetActiveVT: TextConsole_SetActiveVT, + NewBufferedVT: TextConsole_NewBufferedVT, + receiveKeyboardInput: TextConsole_receiveKeyboardInput, + repaint: TextConsole_repaint, + write: TextConsole_write, +}; + +Class TextConsoleClass = { + name: "TextConsole", + findChild: Console_findChild, + interfaces: { + { ConsoleIface, (MethodPtr*)TextConsole_as_Console }, + 0 + }, +}; + +struct TextConsole { + Object object; + + //... data ... +}; + +// Other example + +struct FolderMethods { + MethodPtr GetChildList; +}; + +Interface FolderIface = { + name: "Folder", + method_count: 1, + public_method_count: 1, + + numberedMethods: 0, methodNumbers: 0, // internal +}; |