Just to let everyone know that I have found a solution about how to write OOP code in PureBasic without using Interfaces. The following code is a demo solution of the Trihedron problem I have described in my previous post.
Code: Select all
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Project name : OOP without Interface
; File Name : Trihedron.pb
; File version: 1.0.0
; Programming : OK - Demo
; Programmed by : StarBootics
; Date : May 5th, 2024
; Last Update : May 5th, 2024
; PureBasic code : V6.10 LTS
; Platform : Windows, Linux, MacOS X
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
DeclareModule Vec3f
Structure Vec3f
x.f
y.f
z.f
*vt.Vec3fVirtualTable
EndStructure
Prototype.f Proto_Vec3f_Get(*This.Vec3f)
Prototype Proto_Vec3f_Set(*This.Vec3f, x.f)
Prototype Proto_Vec3f_Update(*This.Vec3f, x.f, y.f, z.f)
Prototype Proto_Vec3f_Equal(*This.Vec3f, *Other.Vec3f)
Prototype Proto_Vec3f_Destructor(*to_be_destroyed)
Structure Vec3fVirtualTable
GetX.Proto_Vec3f_Get
GetY.Proto_Vec3f_Get
GetZ.Proto_Vec3f_Get
SetX.Proto_Vec3f_Set
SetY.Proto_Vec3f_Set
SetZ.Proto_Vec3f_Set
Update.Proto_Vec3f_Update
Equal.Proto_Vec3f_Equal
Destructor.Proto_Vec3f_Destructor
EndStructure
Declare Destructor(*to_be_destroyed)
Declare Init(*This.Vec3f, x.f = 0.0, y.f = 0.0, z.f = 0.0)
Declare.i New(x.f = 0.0, y.f = 0.0, z.f = 0.0)
EndDeclareModule
Module Vec3f
Procedure.f Vec3f_GetX(*This.Vec3f)
ProcedureReturn *This\x
EndProcedure
Procedure.f Vec3f_GetY(*This.Vec3f)
ProcedureReturn *This\y
EndProcedure
Procedure.f Vec3f_GetZ(*This.Vec3f)
ProcedureReturn *This\z
EndProcedure
Procedure Vec3f_SetX(*This.Vec3f, x.f)
*This\x = x
EndProcedure
Procedure Vec3f_SetY(*This.Vec3f, y.f)
*This\y = y
EndProcedure
Procedure Vec3f_SetZ(*This.Vec3f, z.f)
*This\z = z
EndProcedure
Procedure Vec3f_Update(*This.Vec3f, x.f, y.f, z.f)
*This\x = x
*This\y = y
*This\z = z
EndProcedure
Procedure Vec3f_Equal(*This.Vec3f, *Other.Vec3f)
*This\x = *Other\x
*This\y = *Other\y
*This\z = *Other\z
EndProcedure
Procedure Destructor(*to_be_destroyed)
FreeStructure(*to_be_destroyed)
EndProcedure
Global Vec3fVirtualTable.Vec3fVirtualTable
Vec3fVirtualTable\GetX = @Vec3f_GetX()
Vec3fVirtualTable\GetY = @Vec3f_GetY()
Vec3fVirtualTable\GetZ = @Vec3f_GetZ()
Vec3fVirtualTable\SetX = @Vec3f_SetX()
Vec3fVirtualTable\SetY = @Vec3f_SetY()
Vec3fVirtualTable\SetZ = @Vec3f_SetZ()
Vec3fVirtualTable\Update = @Vec3f_Update()
Vec3fVirtualTable\Equal = @Vec3f_Equal()
Vec3fVirtualTable\Destructor = @Destructor()
Procedure Init(*This.Vec3f, x.f = 0.0, y.f = 0.0, z.f = 0.0)
*This\vt = @Vec3fVirtualTable
*This\x = x
*This\y = y
*This\z = z
EndProcedure
Procedure.i New(x.f = 0.0, y.f = 0.0, z.f = 0.0)
*This.Vec3f = AllocateStructure(Vec3f)
If *This = #Null
End
EndIf
Init(*This, x, y, z)
ProcedureReturn *This
EndProcedure
EndModule
DeclareModule Trihedron
Structure Trihedron
Position.Vec3f::Vec3f
Tangent.Vec3f::Vec3f
Normal.Vec3f::Vec3f
Binormal.Vec3f::Vec3f
*vt.TrihedronVirtualTable
EndStructure
Prototype.i Proto_Trihedron_Get(*This.Trihedron)
Prototype Proto_Trihedron_Set(*This.Trihedron, *Vector.Vec3f::Vec3f)
Prototype Proto_Trihedron_Reset(*This.Trihedron)
Prototype Proto_Trihedron_Destructor(*to_be_destroyed)
Structure TrihedronVirtualTable
GetPosition.Proto_Trihedron_Get
GetTangent.Proto_Trihedron_Get
GetNormal.Proto_Trihedron_Get
GetBinormal.Proto_Trihedron_Get
SetPosition.Proto_Trihedron_Set
SetTangent.Proto_Trihedron_Set
SetNormal.Proto_Trihedron_Set
SetBinormal.Proto_Trihedron_Set
Reset.Proto_Trihedron_Reset
Destructor.Proto_Trihedron_Destructor
EndStructure
Declare Destructor(*to_be_destroyed)
Declare Init(*This.Trihedron, *Position.Vec3f::Vec3f = #Null, *Tangent.Vec3f::Vec3f = #Null, *Normal.Vec3f::Vec3f = #Null, *Binormal.Vec3f::Vec3f = #Null)
Declare.i New(*Position.Vec3f::Vec3f = #Null, *Tangent.Vec3f::Vec3f = #Null, *Normal.Vec3f::Vec3f = #Null, *Binormal.Vec3f::Vec3f = #Null)
EndDeclareModule
Module Trihedron
Procedure.i Trihedron_GetPosition(*This.Trihedron)
ProcedureReturn *This\Position
EndProcedure
Procedure.i Trihedron_GetTangent(*This.Trihedron)
ProcedureReturn *This\Tangent
EndProcedure
Procedure.i Trihedron_GetNormal(*This.Trihedron)
ProcedureReturn *This\Normal
EndProcedure
Procedure.i Trihedron_GetBinormal(*This.Trihedron)
ProcedureReturn *This\Binormal
EndProcedure
Procedure Trihedron_SetPosition(*This.Trihedron, *Position.Vec3f::Vec3f)
If *Position <> #Null
*This\Position\vt\Equal(*This\Position, *Position)
EndIf
EndProcedure
Procedure Trihedron_SetTangent(*This.Trihedron, *Tangent.Vec3f::Vec3f)
If *Tangent <> #Null
*This\Tangent\vt\Equal(*This\Tangent, *Tangent)
EndIf
EndProcedure
Procedure Trihedron_SetNormal(*This.Trihedron, *Normal.Vec3f::Vec3f)
If *Normal <> #Null
*This\Normal\vt\Equal(*This\Normal, *Normal)
EndIf
EndProcedure
Procedure Trihedron_SetBinormal(*This.Trihedron, *Binormal.Vec3f::Vec3f)
If *Binormal <> #Null
*This\Binormal\vt\Equal(*This\Binormal, *Binormal)
EndIf
EndProcedure
Procedure Trihedron_Reset(*This.Trihedron)
*This\Position\vt\Update(*This\Position, 0.0, 0.0, 0.0)
*This\Tangent\vt\Update(*This\Tangent, 0.0, 0.0, 1.0)
*This\Normal\vt\Update(*This\Normal, 1.0, 0.0, 0.0)
*This\Binormal\vt\Update(*This\Binormal, 0.0, 1.0, 0.0)
EndProcedure
Procedure Destructor(*to_be_destroyed)
FreeStructure(*to_be_destroyed)
EndProcedure
Global TrihedronVirtualTable.TrihedronVirtualTable
TrihedronVirtualTable\GetPosition = @Trihedron_GetPosition()
TrihedronVirtualTable\GetTangent = @Trihedron_GetTangent()
TrihedronVirtualTable\GetNormal = @Trihedron_GetNormal()
TrihedronVirtualTable\GetBinormal = @Trihedron_GetBinormal()
TrihedronVirtualTable\SetPosition = @Trihedron_SetPosition()
TrihedronVirtualTable\SetTangent = @Trihedron_SetTangent()
TrihedronVirtualTable\SetNormal = @Trihedron_SetNormal()
TrihedronVirtualTable\SetBinormal = @Trihedron_SetBinormal()
TrihedronVirtualTable\Reset = @Trihedron_Reset()
TrihedronVirtualTable\Destructor = @Destructor()
Procedure Init(*This.Trihedron, *Position.Vec3f::Vec3f = #Null, *Tangent.Vec3f::Vec3f = #Null, *Normal.Vec3f::Vec3f = #Null, *Binormal.Vec3f::Vec3f = #Null)
*This\vt = @TrihedronVirtualTable
Vec3f::Init(*This\Position, 0.0, 0.0, 0.0)
Vec3f::Init(*This\Tangent, 0.0, 0.0, 1.0)
Vec3f::Init(*This\Normal, 1.0, 0.0, 0.0)
Vec3f::Init(*This\Binormal, 0.0, 1.0, 0.0)
If *Position <> #Null
*This\Position\vt\Equal(*This\Position, *Position)
EndIf
If *Tangent <> #Null
*This\Tangent\vt\Equal(*This\Tangent, *Tangent)
EndIf
If *Normal <> #Null
*This\Normal\vt\Equal(*This\Normal, *Normal)
EndIf
If *Binormal <> #Null
*This\Binormal\vt\Equal(*This\Binormal, *Binormal)
EndIf
EndProcedure
Procedure.i New(*Position.Vec3f::Vec3f = #Null, *Tangent.Vec3f::Vec3f = #Null, *Normal.Vec3f::Vec3f = #Null, *Binormal.Vec3f::Vec3f = #Null)
*This.Trihedron = AllocateStructure(Trihedron)
If *This = #Null
End
EndIf
Init(*This, *Position, *Tangent, *Normal, *Binormal)
ProcedureReturn *This
EndProcedure
EndModule
CompilerIf #PB_Compiler_IsMainFile
Vec3f::Init(MyVector.Vec3f::Vec3f)
MyVector\vt\SetX(MyVector, 2.25)
MyVector\vt\SetY(MyVector, 3.25)
MyVector\vt\SetZ(MyVector, 4.25)
Debug MyVector\vt\GetX(MyVector)
Debug MyVector\vt\GetY(MyVector)
Debug MyVector\vt\GetZ(MyVector)
Debug ""
Debug "-------------------------------"
Debug ""
*MyOtherVector.Vec3f::Vec3f = Vec3f::New(4.25, 3.75, 2.75)
Debug *MyOtherVector\vt\GetX(*MyOtherVector)
Debug *MyOtherVector\vt\GetY(*MyOtherVector)
Debug *MyOtherVector\vt\GetZ(*MyOtherVector)
Debug ""
Debug "-------------------------------"
Debug ""
*MyOtherVector\vt\Destructor(*MyOtherVector)
NewList Positions.Vec3f::Vec3f()
AddElement(Positions())
Vec3f::Init(Positions(), 5.50, 6.25, 7.15)
AddElement(Positions())
Vec3f::Init(Positions(), 6.50, 7.25, 8.75)
ForEach Positions()
Debug Positions()\vt\GetX(Positions())
Debug Positions()\vt\GetY(Positions())
Debug Positions()\vt\GetZ(Positions())
Debug ""
Debug "-------------------------------"
Debug ""
Next
Trihedron::Init(MyTrihedron.Trihedron::Trihedron)
*Position.Vec3f::Vec3f = MyTrihedron\vt\GetPosition(MyTrihedron)
*Tangent.Vec3f::Vec3f = MyTrihedron\vt\GetTangent(MyTrihedron)
*Normal.Vec3f::Vec3f = MyTrihedron\vt\GetNormal(MyTrihedron)
*Binormal.Vec3f::Vec3f = MyTrihedron\vt\GetBinormal(MyTrihedron)
Debug *Position\vt\GetX(*Position)
Debug *Position\vt\GetY(*Position)
Debug *Position\vt\GetZ(*Position)
Debug ""
Debug *Tangent\vt\GetX(*Tangent)
Debug *Tangent\vt\GetY(*Tangent)
Debug *Tangent\vt\GetZ(*Tangent)
Debug ""
Debug *Normal\vt\GetX(*Normal)
Debug *Normal\vt\GetY(*Normal)
Debug *Normal\vt\GetZ(*Normal)
Debug ""
Debug *Binormal\vt\GetX(*Binormal)
Debug *Binormal\vt\GetY(*Binormal)
Debug *Binormal\vt\GetZ(*Binormal)
Debug ""
Debug "-------------------------------"
Debug ""
*MyTrihedron2.Trihedron::Trihedron = Trihedron::New()
*Position = *MyTrihedron2\vt\GetPosition(*MyTrihedron2)
*Tangent = *MyTrihedron2\vt\GetTangent(*MyTrihedron2)
*Normal = *MyTrihedron2\vt\GetNormal(*MyTrihedron2)
*Binormal = *MyTrihedron2\vt\GetBinormal(*MyTrihedron2)
Debug *Position\vt\GetX(*Position)
Debug *Position\vt\GetY(*Position)
Debug *Position\vt\GetZ(*Position)
Debug ""
Debug *Tangent\vt\GetX(*Tangent)
Debug *Tangent\vt\GetY(*Tangent)
Debug *Tangent\vt\GetZ(*Tangent)
Debug ""
Debug *Normal\vt\GetX(*Normal)
Debug *Normal\vt\GetY(*Normal)
Debug *Normal\vt\GetZ(*Normal)
Debug ""
Debug *Binormal\vt\GetX(*Binormal)
Debug *Binormal\vt\GetY(*Binormal)
Debug *Binormal\vt\GetZ(*Binormal)
*MyTrihedron2\vt\Destructor(*MyTrihedron2)
CompilerEndIf
; <<<<<<<<<<<<<<<<<<<<<<<
; <<<<< END OF FILE <<<<<
; <<<<<<<<<<<<<<<<<<<<<<<
Now, with that out of the way I take the opportunity to tell all of you that I'm not going to update Dev-Object anymore. The reason for that is due to the fact that I'm in the process to create my own programming language. For the moment I'm considering a source to source compiler using C as a backend language and use GCC to compile the source code into a program but who knows maybe I will plunge into LLVM and create a real compiler for it down the road.