Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
;-TOP
; -----------------------------------------------------------------------------
CompilerIf #PB_Compiler_Version > 561
CompilerError "Warning: Check ASM-Compiler for valid RBP-Register!"
CompilerEndIf
Macro GetCaller(self) ; Get frame pointer from caller
CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
EnableASM
mov self, ebp
DisableASM
CompilerElse
EnableASM
mov self, rbp
DisableASM
CompilerEndIf
EndMacro
; -----------------------------------------------------------------------------
Prototype protoAdd(Value.i)
Prototype protoSub(Value.i)
Prototype protoResult()
Structure sObject
Add.protoAdd
Sub.protoSub
Result.protoResult
Value.i
EndStructure
Procedure Add(Value.i)
Protected *self.sObject
GetCaller(*self)
;Debug *self
*self\Value + Value
EndProcedure
Procedure Sub(Value.i)
Protected *self.sObject
GetCaller(*self)
;Debug *self
*self\Value - Value
EndProcedure
Procedure Result()
Protected *self.sObject
GetCaller(*self)
;Debug *self
ProcedureReturn *self\Value
EndProcedure
Procedure Init(*self.sObject)
; set procedure address
*self\Add = @Add()
*self\Sub = @Sub()
*self\Result = @Result()
; set default values
*self\Value = 0
EndProcedure
; -----------------------------------------------------------------------------
;-Test
Define a1.sObject
Debug "Init Object"
Init(a1)
;Debug @a1
Debug "Add and Sub"
a1\Add(100)
a1\Sub(20)
Debug "Result = " + a1\Result()
;-Test 2
Debug "Array of object"
Dim args.sObject(1000)
For i = 1 To 1000
Init(args(i))
Next
For i = 1 To 1000
args(i)\Add(Random(100))
;args(i)\Add(1); Random(100))
Next
For i = 1 To 1000
r1 + args(i)\Result()
Next
Debug "Result = " + r1
Information
Ich habe mich mal wieder mit ASM beschäftigt und den Aufruf-Konvention.
Weil 'Fred' unser großer Purebasic Entwickler ist, hält er sich als Profi an den Aufruf-Konvention und verwendet das rbp-register als Zeiger auf den aktuellen Rekord (Frame-Pointer).
Somit können wird auf den Zeiger von der aktuellen Struktur (record) vom Aufrufer zugreifen.
Diese funktioniert natürlich nur so lange, wenn der Compiler kein anderes Verfahren verwendet. Zum beispiel auf ein Prozessor unabhängigen Compiler (LLVM-Compiler)
Zuletzt geändert von mk-soft am 03.09.2017 12:37, insgesamt 2-mal geändert.
Prototypes gibt es seit PB-Version 4.0 und habe die version noch einmal installiert.
Zur Sicherheit habe ich ein CompilerError eingebaut um eine Warnung auszugeben falls jemand diese verwendet.
Ist aber eine interessante Möglichkeit um schnelle Methoden zu schreiben, aber nicht Zukunftssicher.
Der sichere Weg ist weiterhin mit Interfaces zu arbeiten.
; For additional operators there is no need to change anything elsewhere. - e.g:
Procedure Mult(ObjectValue.i, OperationValue.i) : ProcedureReturn ObjectValue * OperationValue : EndProcedure : Mult = @Mult()
Dafür reduziert sich der Aufwand an anderer Stelle.
Der große Vorteil, dass die IDE die Methoden vorschlägt, fällt tatsächlich weg. Da hast Du ganz klar Recht. Aber das ist wohl auch eine Frage der Vorlieben und Gewohnheiten.
Ein Stück weit kann ich Dich verstehen. Ich tue mich auch noch mit OO schwer. Das liegt aber u.a. auch daran, dass ich mich gerne von Fundamentalisten fern halte - egal welche Religion, welches Programmierparadigma oder was auch immer. Mit dem Trick von mk-soft kann man nach meinem Empfinden aber etwas OO-Vereinfachung nutzen ohne sich komplett auf das OO-Spiel einlassen zu müssen.
Ach ich bin jetzt auch kein OOP-Fanatiker. Ich hätte gerne es in PB, aber Fred ist - aus welchen unsinnigen Gründen auch immer - dagegen.
Mit den Execute hat immer den Nachteil, das du mit den Parameter begrenzt bist, egal wie du das drehst und wendest.
Ich weis noch, die Methode wurde schon mal in Englischen Forum besprochen und da kamen sehr schnell Beispiele, wo es auf einmal nicht mehr funktioniert hat. Ich kann mich aber beim besten Willen nicht mehr erinnern. Irgendwie hat diese Lösung nie einer benutzt...
Das größte Problem ist, dass das ganze eine nicht dokumentierte Funktion von PB nutzt. Und diesmal gehts halt wirklich ins Detail runter. Wenns Blöd läuft, funktioniert das zu 99% und genau diese 1% suchst du dann ewig in Fehlerfall.
Problematisch ist auch, das in Zukunft das nicht mehr zwingend Funktioniert. Wenn das Passiert, darfst du deinen Code entweder kompliziert anpassen oder wegschmeißen.
Ich weis noch, die Methode wurde schon mal in Englischen Forum besprochen und da kamen sehr schnell Beispiele, wo es auf einmal nicht mehr funktioniert hat. Ich kann mich aber beim besten Willen nicht mehr erinnern. Irgendwie hat diese Lösung nie einer benutzt...
Also diese Methode funktioniert schon seit der Version 4.0 von 8. Mai 2006 mit der Einführung von Prototypes
Muss also was anderes gewesen sein...
Habe aber selber geschrieben das es nicht unbedingt Zukunftssicher ist, aber interessant und schnell