Mijikai wrote: Thu Feb 20, 2025 10:26 pm
Whats the actual goal here (i am confused)?
Realizing objects with vtables and interfaces is nothing new.
I’m exploring different approaches!
Yes, I’m trying to find the method that suits me best.
I’ve done a lot of experimenting because, at first, I couldn’t achieve what I wanted—a simpler syntax, as I had imagined.
After testing and seeking help from the AI, we finally came up with a solution that works.
I don’t understand the prototypes introduced by the AI, but it works, so I’m sticking with it for now!
And I’m not using those damn interfaces!
Honestly, I never really understood how interfaces work, and besides, they didn’t fully meet my needs. For example, I couldn’t access object properties directly—only call methods.
Code: Select all
; Code créer par Dieppedalle David avec l'aide de l'IA, le 21/02/2025.
; Code created by Dieppedalle David with the help of AI, on 02/21/2025.
; ======================================================
; Structure des propriétés de l'Objet.
; Structure of the Object's properties.
; ======================================================
Structure ObjectProperties
ID.i ; L'ID de l'Objet | The ID of the Object.
Name.s ; Le nom de l'Objet. | The Name of the Object.
X.i ; La coordonnée ou valeur X. | The X coordinate or value.
Y.i ; La coordonnée ou valeur Y. | The Y coordinate or value.
EndStructure
; ======================================================
; Prototypes pour les méthodes.
; Prototypes for methods.
; ======================================================
Prototype.i ProtoIntFunc() ; Méthode sans paramètre qui retourne un entier. | Method without parameters that returns an integer.
Prototype.s ProtoStrFunc() ; Méthode sans paramètre qui retourne une chaîne. | Method without parameters that returns a string.
Prototype.s ProtoStrFuncWithParams(Title.s, Message.s) ; Méthode avec paramètres (Title, Message) qui retourne une chaîne. | Method with parameters (Title, Message) that returns a string.
; ======================================================
; Une structure où chaque champ contient l'adresse
; de la procédure qui porte le nom du champ.
;
; A structure where each field contains the address
; of the procedure with the same name as the field.
; ======================================================
Structure ObjectMethods
*Abc123.ProtoIntFunc ; *Abc123 est un Pointeur de Type ProtoIntFunc qui est un Prototype. | *Abc123 is a Pointer of Type ProtoIntFunc which is a Prototype.
*Abc246.ProtoIntFunc ; *Abc246 est un Pointeur de Type ProtoIntFunc qui est un Prototype. | *Abc246 is a Pointer of Type ProtoIntFunc which is a Prototype.
*AbcXY.ProtoIntFunc ; *AbcXY est un Pointeur de Type ProtoIntFunc qui est un Prototype. | *AbcXY is a Pointer of Type ProtoIntFunc which is a Prototype.
*AbcStr.ProtoStrFunc ; *AbcStr est un Pointeur de Type ProtoStrFunc qui est un Prototype. | *AbcStr is a Pointer of Type ProtoStrFunc which is a Prototype.
*AbcBox.ProtoStrFuncWithParams ; *AbcBox est un Pointeur de Type ProtoStrFuncWithParams qui est un Prototype. | *AbcBox is a Pointer of Type ProtoStrFuncWithParams which is a Prototype.
EndStructure
; ======================================================
; Structure principale de l'Objet.
; Main Object structure.
; ======================================================
Structure StructureObject
*Properties.ObjectProperties ; Pointeur (*Properties) de type ObjectProperties qui pointe vers les propriétés (état). | Pointer (*Properties) of type ObjectProperties that points to properties (state).
*Methods.ObjectMethods ; Pointeur (*Methods) de type ObjectMethods qui pointe vers les méthodes (comportement). | Pointer (*Methods) of type ObjectMethods that points to methods (behavior).
EndStructure
Global NextObjectID.i = 1
Global *CurrentObject.StructureObject ; Variable globale pour stocker l'Objet courant. | Global variable to store the current Object.
; ======================================================
; Des procédures quelconque.
; Any procedures.
; ======================================================
Procedure.i Abc123()
ProcedureReturn 123 ; Retourne la valeur entière 123. | Returns the integer value 123.
EndProcedure
Procedure.i Abc246()
ProcedureReturn 246 ; Retourne la valeur entière 246. | Returns the integer value 246.
EndProcedure
Procedure.i AbcXY()
; Utilise le contexte global pour accéder aux propriétés de l'Objet courant.
; Uses the global context to access the properties of the current Object.
If *CurrentObject And *CurrentObject\Properties
ProcedureReturn *CurrentObject\Properties\X + *CurrentObject\Properties\Y
Else
Debug "Error: Object Or properties Not initialized."
ProcedureReturn 0
EndIf
EndProcedure
Procedure.s AbcStr()
; Utilise le contexte global pour accéder aux propriétés de l'Objet courant et retourne une chaîne formatée.
; Uses the global context to access the properties of the current Object and returns a formatted string.
If *CurrentObject And *CurrentObject\Properties
ProcedureReturn "X + Y = " + Str(*CurrentObject\Properties\X + *CurrentObject\Properties\Y)
Else
Debug "Error: Object Or properties Not initialized."
ProcedureReturn ""
EndIf
EndProcedure
Procedure.s AbcBox(Title.s, Message.s)
; Affiche une boîte de message avec un titre et un message, puis retourne une chaîne de confirmation.
; Displays a message box with a title and message, then returns a confirmation string.
MessageRequester(Title, Message)
ProcedureReturn "Message displayed !"
EndProcedure
; ======================================================
; Création d'un nouvel Objet.
; Creating a new Object.
; ======================================================
Procedure.i NewObject()
; Déclare un Pointeur (*Object) protégé de type StructureObject, qui prend comme valeur l'adresse de la structure "StructureObject".
; Ensuite, alloue un nouvel Objet de type Structure dynamique.
;
; Declares a protected Pointer (*Object) of type StructureObject, which takes as a value the address of the "StructureObject" structure.
; Then, allocates a new Object of dynamic Structure type.
Protected *Object.StructureObject = AllocateStructure(StructureObject)
; Si l'Objet *Object est bien initialisé.
; If the Object *Object is properly initialized.
If *Object.StructureObject
; Alloue un nouvel Objet "Properties" de type Structure dynamique qui prend comme valeur l'adresse de la structure "ObjectProperties".
; Allocates a new "Properties" Object of dynamic Structure type which takes as a value the address of the "ObjectProperties" structure.
*Object\Properties = AllocateStructure(ObjectProperties)
; Si l'Objet "Properties" n'est pas initialisé.
; If the "Properties" Object is not initialized.
If Not *Object\Properties
Debug "Error: Unable To allocate Object properties."
FreeStructure(*Object) ; Supprime l'Objet car il a pu être créé. | Remove the Object as it has been created.
ProcedureReturn 0
EndIf
; Alloue un nouvel Objet "Methods" de type Structure dynamique qui prend comme valeur l'adresse de la structure "ObjectMethods".
; Allocates a new "Methods" Object of dynamic Structure type which takes as a value the address of the "ObjectMethods" structure.
*Object\Methods = AllocateStructure(ObjectMethods)
; Si l'Objet "Methods" n'est pas initialisé.
; If the "Methods" Object is not initialized.
If Not *Object\Methods
Debug "Error: Unable To allocate Object methods."
FreeStructure(*Object\Properties) ; Supprime les propriétés de l'Objet car elles ont pu être créées. | Remove the properties of the Object as they have been created.
FreeStructure(*Object) ; Supprime l'Objet car il a pu être créé. | Remove the Object as it has been created.
ProcedureReturn 0
EndIf
; Affecte un Numéro d'identification à l'Objets en fonction de la variable NextObjectID.i.
; Assigns an identification number to the object according to the NextObjectID.i variable.
*Object\Properties\ID = NextObjectID.i
NextObjectID.i + 1
; Associe les méthodes aux champs correspondants, chaque champ contient l'adresse mémoire de la procédure qui porte le nom du champ.
; Associates methods with the corresponding fields, each field contains the memory address of the procedure that has the same name as the field.
*Object\Methods\Abc123 = @Abc123()
*Object\Methods\Abc246 = @Abc246()
*Object\Methods\AbcXY = @AbcXY()
*Object\Methods\AbcStr = @AbcStr()
*Object\Methods\AbcBox = @AbcBox()
; Retourne un pointeur qui est l'adresse mémoire de la structure "StructureObject".
; Returns a pointer which is the memory address of the "StructureObject" structure.
ProcedureReturn *Object
Else
ProcedureReturn 0
EndIf
EndProcedure
; ======================================================
; Détruit un objet et libère toute sa mémoire allouée.
; Destroys an Object and releases all its allocated memory.
; ======================================================
Procedure.b DestroyObject(*Object.StructureObject)
; Vérifie si l'objet est valide (non-nul) | Checks if Object is valid (non-null).
If *Object
If *Object\Properties
FreeStructure(*Object\Properties) ; Libère les propriétés | Frees properties.
EndIf
If *Object\Methods
FreeStructure(*Object\Methods) ; Libère les méthodes | Frees methods.
EndIf
FreeStructure(*Object) ; Libère l'objet principal | Frees main Object.
ProcedureReturn 1
Else
Debug "Error: Object Not initialized: " + Str(*Object)
ProcedureReturn 0
EndIf
EndProcedure
; --------------------------------
; Exemple d'utilisation:
; Example of use:
; ======================================================
; Création d'instance.
; Instance creation.
; ======================================================
*MyObject.StructureObject = NewObject() ; Crée un nouvel Objet. | Creates a new Object.
; Si l'Objet existe. | If the Object exists.
If *MyObject
; *CurrentObject est un Pointeur globale définie plus haut dans le code qui sert à savoir l'Objet courant actuel.
; *CurrentObject is a Global Pointer defined earlier in the code, used to identify the current Object.
*CurrentObject = *MyObject ; Enregistre l'Objet courant (*MyObject) dans le pointeur *CurrentObject, sert à ne pas passer l'Objet *MyObject en paramètre des méthodes.
; Saves the current Object (*MyObject) in the *CurrentObject pointer, so as not to pass the *MyObject as a methods parameter.
Debug "Adress Object: " + Str(*MyObject) ; Affiche l'adresse mémoire de l'instance de l'Objet. | Displays the memory address of the Object instance.
Debug "Adress Object Properties: " + Str(*MyObject\Properties) ; Affiche l'adresse mémoire de la structure des propriétés. | Displays the memory address of the properties structure.
Debug "Adress Object Methods: " + Str(*MyObject\Methods) ; Affiche l'adresse mémoire de la structure des méthodes. | Displays the memory address of the methods structure.
Debug "-----------------------------------"
; ======================================================
; Modification des propriétés.
; Modification of properties.
; ======================================================
*MyObject\Properties\Name = "Object #1" ; Définit la propriété Name à "Object #1". | Sets Name property to "Object #1".
*MyObject\Properties\X = 15 ; Définit la propriété X à la valeur de 15. | Sets X property to 15.
*MyObject\Properties\Y = 25 ; Définit la propriété Y à la valeur de 25. | Sets Y property to 25.
Debug "Object ID: " + Str(*MyObject\Properties\ID) ; Affiche la valeur de la propriété ID. | Displays ID property value.
Debug "Object X: " + Str(*MyObject\Properties\X) ; Affiche la valeur de la propriété X. | Displays X property value.
Debug "Object Y: " + Str(*MyObject\Properties\Y) ; Affiche la valeur de la propriété Y. | Displays Y property value.
Debug "Object Name: " + *MyObject\Properties\Name ; Affiche la valeur de la propriété Name sous forme de chaîne. | Displays Name property value as a string.
Debug "-----------------------------------"
; ======================================================
; Appel des fonctions sans passer explicitement les propriétés dans les paramètres.
; Calling functions without explicitly passing properties in parameters.
; ======================================================
Debug "Adress Object Methode Abc123:" + Str(*MyObject\Methods\Abc123) ; Affiche l'adresse mémoire de la méthode Abc123(). | Displays memory address of Abc123 method().
Debug "Adress Object Methode Abc246:" + Str(*MyObject\Methods\Abc246) ; Affiche l'adresse mémoire de la méthode Abc246(). | Displays memory address of Abc246 method().
Debug "Adress Object Methode AbcXY:" + Str(*MyObject\Methods\AbcXY) ; Affiche l'adresse mémoire de la méthode AbcXY(). | Displays memory address of AbcXY method().
Debug "Adress Object Methode AbcStr:" + Str(*MyObject\Methods\AbcStr) ; Affiche l'adresse mémoire de la méthode AbcStr(). | Displays memory address of AbcStr method().
Debug "Adress Object Methode AbcBox:" + Str(*MyObject\Methods\AbcBox) ; Affiche l'adresse mémoire de la méthode AbcBox(). | Displays memory address of AbcBox method().
Debug "-----------------------------------"
Debug "Object Fonction Abc123: " + Str(*MyObject\Methods\Abc123()) ; Appelle et affiche le résultat de la méthode Abc123(). | Calls and displays result from Abc123 method().
Debug "Object Fonction Abc246: " + Str(*MyObject\Methods\Abc246()) ; Appelle et affiche le résultat de la méthode Abc246(). | Calls and displays result from Abc246 method().
Debug "Object Fonction AbcXY: " + Str(*MyObject\Methods\AbcXY()) ; Appelle et affiche le résultat de la méthode AbcXY(). | Calls and displays result from AbcXY method().
Debug "Object Fonction AbcStr: " + *MyObject\Methods\AbcStr() ; Appelle et affiche le résultat de la méthode AbcStr(). | Calls and displays result from AbcStr method().
; Appel de la méthode avec paramètres: - Calling a method with parameters:
Debug "Result of AbcBox: " + *MyObject\Methods\AbcBox("Information", "Hello, world!")
Else
Debug "Erreur: Objet non initialisés: " + Str(*MyObject)
EndIf
In my code, here is an allegory of what it does (Text created by AI, slightly modified by me):
*1. MyObject: The "invisible" master!
Role: It coordinates its two employees (Properties and Methods) without ever directly interacting with the outside world.
Power: It hires and fires its employees using (NewObject() and FreeStructure()).
Limitation: It only sees its employees (Properties and Methods), not the subcontractors (X, Y, Name, AbcXY...).
**2. The employees: Properties and Methods
*Properties (Data Department)
Role: Manages the subcontractors: X, Y, Name.
Actions: Transmits and collects data on their behalf.
Secret: The subcontractors are completely unaware of the existence of *MyObject, and vice versa.
*Methods (Operations Department)
Role: Hires external experts (AbcXY, AbcStr...) to perform tasks.
Actions: Gives orders.
Secret: The experts do not know they are working for *MyObject, and vice versa.
3. The subcontractors: X, Y, Name, AbcXY...
Status: Independent, interchangeable, specialized.
Relationship:
X/Y/Name: Only know *Properties.
AbcXY/AbcStr: Only know *Methods.
Mutual ignorance: None of the subcontractors know that *MyObject exists.
4. Hierarchical control: The genius of the architecture
Level 1: *MyObject (CEO)
Level 2: *Properties (Data Director) and *Methods (Operations Director)
Level 3: X/Y/Name (Data) and AbcXY/AbcStr (Operations)
Advantages:
Encapsulation: No information leakage between levels.
Flexibility: Changing *Properties or *Methods does not affect *MyObject.
Scalability: Easy addition of new subcontractors (e.g., Z, AbcLog...).
5. Philosophical limitation: The isolation of the master
*MyObject is an omniscient but isolated manipulator:
It controls everything through its employees, who act as mere messengers, but it never communicates directly
with the subcontractors for fear of getting its hands dirty or facing issues with justice or karma.
The subcontractors act blindly, unaware of who is mandating them—they are merely pawns.
This is the price of abstraction: *MyObject sacrifices its "visibility" to gain organizational power.