Module BaseClass (Module as Object)
Share your advanced PureBasic knowledge/code with the community.
Module BaseClass (Module as Object)
Wanted to rewrite my OOP precompiler.
But firmly point this is also to solve without pre-compiler.
My goal is to walk without many new keyname a module in a object. I think I have succeeded.
The module BaseClass causes you with all the necessary components:
- Creating a new class with a "BaseClass" or an inherited class.
- The basic function Object\Release () and Object\AddRef ().
- Declaration of call environment "Initalize" and "Dispose", even when inheritance.
- Declaration of methods and overwrite inheritance methods.
There are few rules:
- The structure of the variables (Properties) must be defined with extends structure of "sBaseClass" or extends structure of "inheritance class".
- The interface for the methods must be defined with extends interface "iBaseClass" or extends interface of "inheritance class".
- The inheriting class must have a BaseClass.
Examples with BaseClassSmall:
- Own Flat Gadgets
BaseClass small version
Update v1.05
- Now compatible to extended version
+ Macro AsNewMethode, Macro CloneObject
Update v1.07
- Bugfix FreeMutex
Update v1.09r4
- Map of classes encapsulated
- Check of the new class in procedure 'AddClass(...)' extended
- Change Macros because map of classes not longer global
- Change CheckInterface. Parameter is not longer required
- Name of classes not longer case sensitive (no case)
Update v1.10
- Change ClassName Management.
The module name is no longer the internal class name. This means that the interface name is now specified for inheritance, and not the module name.
Is therefore more logical.
Update v1.13
- Optimize CheckInterface
Update v1.14
- Change name of Macro 'dq' to '_dq_'
Update v1.16
- Update Method QueryInterface with default result for 'IUnknown'
- Optimize code
Update v1.17
- Added Pointer for Private Attributes (Object)
- Added Pointer for Package Attributes (Classes)
- Added new Macro InitPackage()
- Rename internal BaseSystem structure name Self.udtClass to Class.udtClass
Update v1.21
- Removed Private Macros and Pointer
Modul_BaseClassSmall.pb
But firmly point this is also to solve without pre-compiler.
My goal is to walk without many new keyname a module in a object. I think I have succeeded.
The module BaseClass causes you with all the necessary components:
- Creating a new class with a "BaseClass" or an inherited class.
- The basic function Object\Release () and Object\AddRef ().
- Declaration of call environment "Initalize" and "Dispose", even when inheritance.
- Declaration of methods and overwrite inheritance methods.
There are few rules:
- The structure of the variables (Properties) must be defined with extends structure of "sBaseClass" or extends structure of "inheritance class".
- The interface for the methods must be defined with extends interface "iBaseClass" or extends interface of "inheritance class".
- The inheriting class must have a BaseClass.
Examples with BaseClassSmall:
- Own Flat Gadgets
BaseClass small version
Update v1.05
- Now compatible to extended version
+ Macro AsNewMethode, Macro CloneObject
Update v1.07
- Bugfix FreeMutex
Update v1.09r4
- Map of classes encapsulated
- Check of the new class in procedure 'AddClass(...)' extended
- Change Macros because map of classes not longer global
- Change CheckInterface. Parameter is not longer required
- Name of classes not longer case sensitive (no case)
Update v1.10
- Change ClassName Management.
The module name is no longer the internal class name. This means that the interface name is now specified for inheritance, and not the module name.
Is therefore more logical.
Update v1.13
- Optimize CheckInterface
Update v1.14
- Change name of Macro 'dq' to '_dq_'
Update v1.16
- Update Method QueryInterface with default result for 'IUnknown'
- Optimize code
Update v1.17
- Added Pointer for Private Attributes (Object)
- Added Pointer for Package Attributes (Classes)
- Added new Macro InitPackage()
- Rename internal BaseSystem structure name Self.udtClass to Class.udtClass
Update v1.21
- Removed Private Macros and Pointer
Modul_BaseClassSmall.pb
Code: Select all
;-Begin Module BaseClass Small Version
; Comment : Module as Object
; Author : mk-soft
; File : BaseClassSmall.pb
; Version : v1.21.1
; Created : 16.08.2017
; Updated : 07.06.2020
; Link DE : http://www.purebasic.fr/german/viewtopic.php?f=8&t=29343
; Link EN : http://www.purebasic.fr/english/viewtopic.php?f=12&t=64305
; OS : All
; ***************************************************************************************
DeclareModule BaseClass
; ---------------------------------------------------------------------------
; Internal class declaration
Prototype ProtoInvoke(*This)
Structure udtInvoke
*Invoke.ProtoInvoke
EndStructure
Structure udtClass
Array *vTable(3)
Array Initialize.udtInvoke(0)
Array Dispose.udtInvoke(0)
*Package.sPackage
EndStructure
; ---------------------------------------------------------------------------
; BaseClass declaration
Structure sBaseSystem
*vTable
*Class.udtClass
RefCount.i
Mutex.i
EndStructure
; Public Structure
Structure sBaseClass
System.sBaseSystem
EndStructure
; Public Interface
Interface iBaseClass
QueryInterface(*riid, *ppvObject)
AddRef()
Release()
EndInterface
; ---------------------------------------------------------------------------
Macro _dq_
"
EndMacro
; ---------------------------------------------------------------------------
; Added New Class
Declare AddClass(ClassInterface.s, ClassExtends.s, Size) ; Internal
Macro NewClass(ClassInterface, ClassExtends=)
; Interface helper
Interface __Interface Extends ClassInterface
EndInterface
; Internal class pointer
Global *__Class.udtClass
; Add new class
Procedure __NewClass()
*__Class = AddClass(_dq_#ClassInterface#_dq_, _dq_#ClassExtends#_dq_, SizeOf(ClassInterface) / SizeOf(integer))
EndProcedure : __NewClass()
EndMacro
; ---------------------------------------------------------------------------
; Macros for package attributes
Macro InitPackage(_Attributes_=sPackage)
Procedure __InitPackage()
*__Class\Package = AllocateStructure(_Attributes_)
EndProcedure : __InitPackage()
EndMacro
Macro GetPackage()
*__Class\Package
EndMacro
; ---------------------------------------------------------------------------
; Macro for init object (short)
Macro InitObject(sProperty)
Protected *Object.sProperty, __cnt, __index
*Object = AllocateStructure(sProperty)
If *Object
*Object\System\vTable = *__Class\vTable()
*Object\System\Class = *__Class
*Object\System\RefCount = 0
*Object\System\Mutex = CreateMutex()
__cnt = ArraySize(*Object\System\Class\Initialize())
For __index = 1 To __cnt
*Object\System\Class\Initialize(__index)\Invoke(*Object)
Next
EndIf
ProcedureReturn *Object
EndMacro
; ---------------------------------------------------------------------------
; Macros for init object (advanced)
Macro AllocateObject(Object, sProperty)
Object = AllocateStructure(sProperty)
If Object
Object\System\vTable = *__Class\vTable()
Object\System\Class = *__Class
Object\System\RefCount = 0
Object\System\Mutex = CreateMutex()
EndIf
EndMacro
Macro InitializeObject(Object)
If Object
Protected __cnt, __index
__cnt = ArraySize(Object\System\Class\Initialize())
For __index = 1 To __cnt
Object\System\Class\Initialize(__index)\Invoke(Object)
Next
EndIf
EndMacro
; ---------------------------------------------------------------------------
; Macros for clone object
Macro CloneObject(This, Clone, sProperty)
Clone = AllocateStructure(sProperty)
If Clone
CopyStructure(This, Clone, sProperty)
Clone\System\RefCount = 0
Clone\System\Mutex = CreateMutex()
EndIf
EndMacro
; ---------------------------------------------------------------------------
Macro LockObject(This)
LockMutex(This\System\Mutex)
EndMacro
Macro UnlockObject(This)
UnlockMutex(This\System\Mutex)
EndMacro
; ---------------------------------------------------------------------------
; Macros to defined Initialize, Dispose, Methods
; Add Procedure as Initialize Object
Macro AsInitializeObject(Name)
Procedure __AddInitializeObject#Name()
Protected index
index = ArraySize(*__Class\Initialize()) + 1
ReDim *__Class\Initialize(index)
*__Class\Initialize(index)\Invoke = @Name()
EndProcedure : __AddInitializeObject#Name()
EndMacro
; Add Procedure as Dispose Object
Macro AsDisposeObject(Name)
Procedure __AddDisposeObject#Name()
Protected index
index = ArraySize(*__Class\Dispose()) + 1
ReDim *__Class\Dispose(index)
*__Class\Dispose(index)\Invoke = @Name()
EndProcedure : __AddDisposeObject#Name()
EndMacro
; Add Procedure as Methode or Overwrite inheritance methode
Macro AsMethode(Name)
Procedure __AddMethode#Name()
*__Class\vTable(OffsetOf(__Interface\Name()) / SizeOf(integer)) = @Name()
EndProcedure : __AddMethode#Name()
EndMacro
Macro AsNewMethode(Name)
AsMethode(Name)
EndMacro
; ---------------------------------------------------------------------------
; Debugger functions
Macro CheckInterface()
CompilerIf #PB_Compiler_Debugger
Procedure __CheckInterface()
Protected *xml, *node, ErrorCount
*xml = CreateXML(#PB_Any)
If *xml
*node = InsertXMLStructure(RootXMLNode(*xml), *__Class\vTable(), __Interface)
*node = ChildXMLNode(*node)
Repeat
If Not *node
Break
EndIf
If GetXMLNodeText(*node) = "0"
ErrorCount + 1
Debug "Module " + #PB_Compiler_Module + ": Error Interface - Missing Methode '" + GetXMLNodeName(*node) + "()'"
EndIf
*node = NextXMLNode(*node)
ForEver
FreeXML(*xml)
If ErrorCount
Debug "Module " + #PB_Compiler_Module + ": Error Count " + ErrorCount
CallDebugger
EndIf
EndIf
EndProcedure : __CheckInterFace()
CompilerEndIf
EndMacro
; ---------------------------------------------------------------------------
EndDeclareModule
Module BaseClass
EnableExplicit
; ---------------------------------------------------------------------------
Procedure QueryInterface(*This.sBaseClass, *riid, *ppvObject.integer)
If *ppvObject = 0 Or *riid = 0
ProcedureReturn 80070057ドル ; #E_INVALIDARG
EndIf
If CompareMemory(*riid, ?IID_IUnknown, 16)
LockMutex(*This\System\Mutex)
*ppvObject\i = *This
*This\System\RefCount + 1
UnlockMutex(*This\System\Mutex)
ProcedureReturn 0 ; #S_OK
Else
*ppvObject\i = 0
ProcedureReturn 80004002ドル ; #E_NOINTERFACE
EndIf
EndProcedure
; ---------------------------------------------------------------------------
Procedure AddRef(*This.sBaseClass)
LockMutex(*This\System\Mutex)
*This\System\RefCount + 1
UnlockMutex(*This\System\Mutex)
ProcedureReturn *This\System\RefCount
EndProcedure
; ---------------------------------------------------------------------------
Procedure Release(*This.sBaseClass)
Protected index, cnt
With *This\System
LockMutex(*This\System\Mutex)
If \RefCount = 0
cnt = ArraySize(\Class\Dispose())
For index = cnt To 1 Step -1
\Class\Dispose(index)\Invoke(*This)
Next
FreeMutex(\Mutex)
FreeStructure(*This)
ProcedureReturn 0
Else
\RefCount - 1
EndIf
UnlockMutex(*This\System\Mutex)
ProcedureReturn \RefCount
EndWith
EndProcedure
; ---------------------------------------------------------------------------
Procedure AddClass(ClassInterface.s, ClassExtends.s, Size)
Static NewMap Classes.udtClass()
Protected *class.udtClass, *extends.udtClass, sClassInterface.s, sClassExtends.s
sClassInterface = LCase(ClassInterface)
sClassExtends = LCase(ClassExtends)
CompilerIf #PB_Compiler_Debugger
If FindMapElement(Classes(), sClassInterface)
Debug "Error: Class '" + ClassInterface + "' already exists!"
CallDebugger
End -1
EndIf
If Bool(sClassExtends)
*extends = FindMapElement(Classes(), sClassExtends)
If Not *extends
Debug "Error: Extends Class '" + ClassExtends + "' not exists!"
CallDebugger
End -1
EndIf
EndIf
CompilerEndIf
*class = AddMapElement(Classes(), sClassInterface)
If *class
If Bool(sClassExtends)
*extends = FindMapElement(Classes(), sClassExtends)
CopyStructure(*extends, *class, udtClass)
ReDim *class\vTable(Size)
ProcedureReturn *class
Else
ReDim *class\vTable(Size)
*class\vTable(0) = @QueryInterface()
*class\vTable(1) = @AddRef()
*class\vTable(2) = @Release()
ProcedureReturn *class
EndIf
Else
Debug "Error: Class '" + ClassInterface + "' Out Of Memory!"
CallDebugger
End -1
EndIf
EndProcedure
; ---------------------------------------------------------------------------
DataSection
IID_IUnknown: ; {00000000-0000-0000-C000-000000000046}
Data.l 00000000ドル
Data.w 0000,ドル 0000ドル
Data.b $C0, 00,ドル 00,ドル 00,ドル 00,ドル 00,ドル 00,ドル 46ドル
EndDataSection
EndModule
;- End Module BaseClass
; ***************************************************************************************
Last edited by mk-soft on Sun Jun 07, 2020 12:56 pm, edited 70 times in total.
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
Re: Module BaseClass (OOP)
Description of the Module BaseClassSmall
Update v1.17
Preface
Purebasic is a procedure-oriented programming language, but supports the creation of object-oriented programs.
My goal is not to create an object oriented language for Purebasic, but to simplify the creation of own objects.
For full support of object oriented programming there are other programming languages available.
For some tasks it is advantageous to create them object-oriented.
Here the same effort applies with Purebasic as for example with "C".
Everything has to be defined and created by yourself. The rules for objects and the functions and methods must be kept.
1. The first entry in the object is always the pointer to the table with the methods.
2. The first parameter of the methods is always the pointer to the own object.
Classes
To create an object you need a class.
A class defines the data type of an object.
This defines the table of methods (functions) and attributes (variables).
Constructors and Destructors
Constructors are functions that bring the object into a defined state when it is created and, if necessary, create the required resources.
Destructors are functions that release resources when the object is released.
Constructors can also have parameters, but are not supported by all programming languages.
Destructors have no parameters.
Constructors and destructors have no return value.
Method Super
To inherit a class, you need a super function that passes the methods and attributes to the subclass.
This also includes the constructors and destructors of the class.
Multiple inheritance can therefore result in multiple constructors and destructors that must be called in the correct order.
Interface
Interfaces define the interface which methods exist or must exist.
What Purebasic supports
Purebasic supports interfaces and attributes, as well as inheritance of interfaces and attributes.
- Interface SubClass Extends BaseClass
- Structure SubAttribute Extends BaseAttribute
Call the methods from the interfaces.
What does the module BaseClassSmall support
Creating and managing classes : NewClass(InterfaceName, ...)
- Create tables for methods, constructors, and destructors.
* Note: Contructors with parameters are not supported.
- The method Super, automated.
The base interface with the methods of type IUnknown
- QueryInterface(*riid, *addr)
- AddRef()
- Release()
The base attributes with the structure
- System\vTable : pointer to the method table.
- System\Class : Pointer to the class with the tables of the methods, constructors, destructors and package attributes.
- System\RefCount : Counter to protect the object.
- System\Mutex : Mutex for asynchronous processing of the object.
Assignment of the contructor : Macro AsInitializeObject(Name of the procedure)
Assignment of the destructor : Macro AsDisposeObject(Name of the procedure)
Initialize of package attributes : Macro InitPackage()
Assignment of methods : Macro AsMethod(Name of method and procedure)
Overwrite methods : Macro AsNewMethod(Name of method and procedure)
Creating the object : Macro InitObject or AllocateObject/InitializeObject for the procedure to create the object
- Creating the memory for the object.
- Assignment of the Virtual Table and Basic Attributes.
- Calling the constructors in the correct order.
Method QueryInterface : Object\QueryInterface(*riid, *addr)
- Default Method with result of query IUnknown.
* The method can be overwritten if necessary.
Method AddRef : Object\AddRef()
- Increases the counter of the object.
* This is deduced with Release object. The object is only released after it has been reset to zero.
! Do not overwrite !
Method Release : Object\Release()
- Calling the destructors in the correct order.
- Releasing the memory.
! Do not overwrite !
Checking the Class in Debugger Mode
- Call CheckInterface() at the end of the module.
Last edited by mk-soft on Wed Jun 17, 2020 4:10 pm, edited 24 times in total.
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
Re: Module BaseClass (OOP)
Example 3 (Update)
Code: Select all
; Example 3 v1.13
IncludeFile "Modul_BaseClassSmall.pb"
; *******************************************************************************
DeclareModule User
UseModule BaseClass
Structure sUser Extends sBaseClass
firstname.s
lastname.s
EndStructure
Interface iUser Extends iBaseClass
SetName(FirstName.s, LastName.s)
GetName.s()
GetFirstName.s()
GetLastName.s()
Clone()
EndInterface
UnuseModule BaseClass
Declare.i New()
EndDeclareModule
Module User
UseModule BaseClass
NewClass(iUser)
; ---------------------------------------------------------------------------
Procedure Init(*this.sUser)
*this\firstname = "no name"
*this\lastname = "no name"
Debug "Initalize Object Class User " + *this
EndProcedure : AsInitializeObject(Init)
; ---------------------------------------------------------------------------
Procedure Dispose(*this.sUser)
Debug "Dispose Object Class User " + *this
EndProcedure : AsDisposeObject(Dispose)
; ---------------------------------------------------------------------------
Procedure SetName(*this.sUser, FirstName.s, LastName.s)
With *this
\firstname = FirstName
\lastname = LastName
EndWith
EndProcedure : AsMethode(SetName)
; ---------------------------------------------------------------------------
Procedure.s GetName(*this.sUser)
With *this
ProcedureReturn \lastname + ";" + \firstname
EndWith
EndProcedure : AsMethode(GetName)
; ---------------------------------------------------------------------------
Procedure.s GetFirstName(*this.sUser)
ProcedureReturn *this\firstname
EndProcedure : AsMethode(GetFirstName)
; ---------------------------------------------------------------------------
Procedure.s GetLastName(*this.sUser)
ProcedureReturn *this\lastname
EndProcedure : AsMethode(GetLastName)
; ---------------------------------------------------------------------------
Procedure Clone(*this.sUser)
Protected *clone.sUser
CloneObject(*this, *clone, sUser)
ProcedureReturn *clone
EndProcedure : AsMethode(Clone)
; ---------------------------------------------------------------------------
Procedure New()
InitObject(sUser)
EndProcedure
; ---------------------------------------------------------------------------
CheckInterface()
EndModule
; *******************************************************************************
DeclareModule Adress
UseModule User
Structure sAdress Extends sUser
street.s
postal.i
city.s
country.s
EndStructure
Interface iAdress Extends iUser
SetAdress(street.s, postal.i, city.s, country.s)
GetStreet.s()
GetPostal.i()
GetCity.s()
GetCountry.s()
GetAll.s()
EndInterface
UnuseModule User
Declare New()
EndDeclareModule
Module Adress
UseModule BaseClass
NewClass(iAdress, iUser)
; ---------------------------------------------------------------------------
Procedure Init(*this.sAdress)
Debug "Initalize Object Class Adress " + *this
EndProcedure : AsInitializeObject(Init)
; ---------------------------------------------------------------------------
Procedure Dispose(*this.sAdress)
Debug "Dispose Object Class Adress " + *this
EndProcedure : AsDisposeObject(Dispose)
; ---------------------------------------------------------------------------
Procedure SetAdress(*this.sAdress, street.s, postal.i, city.s, country.s)
With *this
\street = street
\postal = postal
\city = city
\country = country
EndWith
EndProcedure : AsMethode(SetAdress)
; ---------------------------------------------------------------------------
Procedure.s GetStreet(*this.sAdress)
With *this
ProcedureReturn \street
EndWith
EndProcedure : AsMethode(GetStreet)
; ---------------------------------------------------------------------------
Procedure GetPostal(*this.sAdress)
With *this
ProcedureReturn \postal
EndWith
EndProcedure : AsMethode(GetPostal)
; ---------------------------------------------------------------------------
Procedure.s GetCity(*this.sAdress)
With *this
ProcedureReturn \city
EndWith
EndProcedure : AsMethode(GetCity)
; ---------------------------------------------------------------------------
Procedure.s GetCountry(*this.sAdress)
With *this
ProcedureReturn \country
EndWith
EndProcedure : AsMethode(GetCountry)
; ---------------------------------------------------------------------------
Procedure.s GetAll(*this.sAdress)
Protected r1.s
With *this
r1 = \LastName + ";"
r1 + \FirstName + ";"
r1 + \street + ";"
r1 + \city + ";"
r1 + \postal + ";"
r1 + \country
ProcedureReturn r1
EndWith
EndProcedure : AsMethode(GetAll)
; ---------------------------------------------------------------------------
Procedure Clone(*this.sAdress)
Protected *clone.sAdress
CloneObject(*this, *clone, sAdress)
ProcedureReturn *clone
EndProcedure : AsNewMethode(Clone)
; ---------------------------------------------------------------------------
Procedure New()
InitObject(sAdress)
EndProcedure
; ---------------------------------------------------------------------------
CheckInterface()
EndModule
; *******************************************************************************
;- Test
Define.Adress::iAdress *user, *user2
*user=Adress::New()
Debug *user\GetName()
*user\SetName("Toto", "Buddy")
*user\AddRef()
Debug *user\GetName()
*user2 = *user\Clone()
*user2\SetAdress("My Street", 12345, "My City", "My Country")
Debug *user2\GetAll()
Debug *user\Release()
Debug *user\Release()
Debug *user2\Release()
Last edited by mk-soft on Sat May 04, 2019 1:50 pm, edited 8 times in total.
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
Re: Module BaseClass (OOP)
Example 6 Update
Update
Update
Code: Select all
;-TOP
; Example 6 v1.13
IncludeFile "Modul_BaseClassSmall.pb"
; *******************************************************************************
DeclareModule DataSet
UseModule BaseClass
; Properties
Structure sDataSet Extends sBaseClass
*pData
Count.i
Array *pStr(0)
EndStructure
; Methods
Interface iDataSet Extends iBaseClass
Get.s(index)
Count()
EndInterface
UnuseModule BaseClass
; New Object
Declare New(*pData)
EndDeclareModule
Module DataSet
UseModule BaseClass
NewClass(iDataSet)
; ---------------------------------------------------------------------------
Procedure.s Get(*this.sDataSet, index)
With *this
If index < \Count
ProcedureReturn PeekS(\pStr(index))
Else
ProcedureReturn ""
EndIf
EndWith
EndProcedure : AsMethode(Get)
; ---------------------------------------------------------------------------
Procedure Count(*this.sDataSet)
ProcedureReturn *this\Count
EndProcedure : AsMethode(Count)
; ---------------------------------------------------------------------------
Procedure Init(*this.sDataSet)
Protected *pos, len, index
With *this
*pos = \pData
Repeat
len = MemoryStringLength(*pos)
If len
\Count + 1
*pos + len * SizeOf(character) + SizeOf(character)
Else
Break
EndIf
ForEver
Dim \pStr(\Count)
*pos = \pData
Repeat
len = MemoryStringLength(*pos)
If len
\pStr(index) = *pos
index + 1
*pos + len * SizeOf(character) + SizeOf(character)
Else
Break
EndIf
ForEver
EndWith
EndProcedure : AsInitializeObject(Init)
; ---------------------------------------------------------------------------
Procedure New(*pData)
Protected *obj.sDataSet
AllocateObject(*obj, sDataSet)
If *obj
*obj\pData = *pData
EndIf
InitializeObject(*obj)
ProcedureReturn *obj
EndProcedure
; ---------------------------------------------------------------------------
CheckInterface()
EndModule
; *******************************************************************************
;- Test
EnableExplicit
Macro Object(ObjectName, ObjectType)
ObjectName.ObjectType#::i#ObjectType
EndMacro
;BaseClass::ShowClasses()
Define.DataSet::iDataSet *set1, *set2
Define i
Debug "Data 1"
*set1 = DataSet::New(?DataSet1)
For i = 0 To *set1\Count() - 1
Debug *set1\Get(i)
Next
Debug "----------------"
Debug "Data 2"
*set2 = DataSet::New(?DataSet2)
For i = 0 To *set2\Count() - 1
Debug *set2\Get(i)
Next
DataSection
DataSet1:
Data.s "Sontag"
Data.s "Montag"
Data.s "Dienstag"
Data.s "Mittwoch"
Data.s "Donnerstag"
Data.s "Freitag"
Data.s "Samstag"
Data.i 0
DataSet2:
Data.s "Januar"
Data.s "Februar"
Data.s "März"
Data.s "April"
Data.s "Mai"
Data.s "Juni"
Data.s "Juli"
Data.s "August"
Data.s "September"
Data.s "Oktober"
Data.s "November"
Data.s "Dezember"
Data.i 0
EndDataSection
Last edited by mk-soft on Sat May 04, 2019 1:51 pm, edited 6 times in total.
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
Re: Module BaseClass (Module as Object)
Update v1.13
- Change Macro InitObject for small code
- Added Macros AllocateObject and InitalizeObject for new object with parameters
Examples updated...
- Change Macro InitObject for small code
- Added Macros AllocateObject and InitalizeObject for new object with parameters
Examples updated...
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
Re: Module BaseClass (Module as Object)
Update v1.15
* Added debugger functions
- ShowInterface(...)
- CheckInterface(...)
:wink:
* Added debugger functions
- ShowInterface(...)
- CheckInterface(...)
:wink:
Last edited by mk-soft on Mon Aug 15, 2016 10:10 pm, edited 1 time in total.
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
Re: Module BaseClass (Module as Object)
Update v1.16
- optimize code
- added debugging info
GT :wink:
- optimize code
- added debugging info
GT :wink:
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
Re: Module BaseClass (Module as Object)
Update v1.20
-
Update v1.21
- Change NewClass(Extends=BaseClass) -> NewClass(CLassInterface, ClassExtends=BaseClass)
* First parameter now the name of interface
+ The sequence of procedures for the methods not longer the same order as they are defined in the interface.
+ Better CheckInterface
- Added debugger info ShowClasses
* Show all Interfaces
:wink:
-
Update v1.21
- Change NewClass(Extends=BaseClass) -> NewClass(CLassInterface, ClassExtends=BaseClass)
* First parameter now the name of interface
+ The sequence of procedures for the methods not longer the same order as they are defined in the interface.
+ Better CheckInterface
- Added debugger info ShowClasses
* Show all Interfaces
:wink:
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
Re: Module BaseClass (Module as Object)
Update v1.22
- Code cleaned
That is probably the smallest code to use OOP with PureBasic, without a new syntax in PureBasic to develop. :wink:
- Code cleaned
That is probably the smallest code to use OOP with PureBasic, without a new syntax in PureBasic to develop. :wink:
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
Re: Module BaseClass (Module as Object)
Update v1.23
- Safety RefCounter over Mutex
- Safety RefCounter over Mutex
Last edited by mk-soft on Sat Feb 25, 2017 2:55 pm, edited 1 time in total.
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
Re: Module BaseClass (Module as Object)
Update
- Added Macro CloneObject because some things to do
- Added Check mutex
- Added Macro LockObject and UnlockObject
Update
- Added Macro CloneObject because some things to do
- Added Check mutex
- Added Macro LockObject and UnlockObject
Code: Select all
...
Procedure Clone(*this.sUser)
Protected *clone.sUser
CloneObject(*this, *clone, sUser)
ProcedureReturn *clone
EndProcedure : AsMethode(Clone)
...
Code: Select all
;-TOP
; Example 9 v1.13
CompilerIf #PB_Compiler_Thread = 0
CompilerError "Use compiler option theadsafe"
CompilerEndIf
IncludeFile "Modul_BaseClassSmall.pb"
DeclareModule Work
UseModule BaseClass
Structure sWork Extends sBaseClass
Value.i
EndStructure
Interface iWork Extends iBaseClass
Add(Value)
Sub(Value)
EndInterface
Declare New()
EndDeclareModule
Module Work
UseModule BaseClass
NewClass(iWork)
; ---------------------------------------------------------------------------
Procedure Init(*this.sWork)
Debug "Initialize Work"
EndProcedure : AsInitializeObject(Init)
; ---------------------------------------------------------------------------
Procedure Destroy(*this.sWork)
Debug "Dispose Work"
Debug "Result: " + *this\Value
EndProcedure : AsDisposeObject(Destroy)
; ---------------------------------------------------------------------------
Procedure Add(*this.sWork, Value)
Protected result
LockObject(*this)
*this\Value + Value
result = *this\Value
UnlockObject(*this)
ProcedureReturn result
EndProcedure : AsMethode(Add)
; ---------------------------------------------------------------------------
Procedure Sub(*this.sWork, Value = 0)
Protected result
LockObject(*this)
*this\Value - Value
result = *this\Value
UnlockObject(*this)
ProcedureReturn result
EndProcedure : AsMethode(Sub)
; ---------------------------------------------------------------------------
Procedure New()
InitObject(sWork) ; Mehr kommt hier nicht rein!
EndProcedure
; ---------------------------------------------------------------------------
CheckInterface()
EndModule
; ***************************************************************************************
;-Test AddRef
Procedure thAdd(*Object.Work::iWork)
Protected time
*Object\AddRef()
Delay(1000)
;Debug "Start"
For i = 1 To 10
time = Random(200)
*Object\Add(1)
Delay(time)
Next
;Debug "Ready."
*Object\Release()
EndProcedure
Debug "Mainscope Create Object"
Define *Object.Work::iWork
*Object = Work::New()
mutex = CreateMutex()
Debug "Start Threads"
For i = 1 To 1000
th = CreateThread(@thAdd(), *Object)
Delay(5)
If th = 0
Debug "No Thread " + i
EndIf
Next
Debug "Mainscope Wait..."
Repeat
Delay(200)
ref = *Object\AddRef()
ref = *Object\Release()
Debug ref
If ref = 0
Break
EndIf
ForEver
Debug "Mainscope Release Object"
*Object\Release()
Debug "Ready."
Last edited by mk-soft on Sat May 04, 2019 1:53 pm, edited 5 times in total.
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
Re: Module BaseClass (Module as Object)
Update v1.26
- Added QueryInterface for compatible with Interface 'IUnknown'.
-- The default result of QueryInterface is constant 'E_NoInterface' for compatibles with Linux and Mac
-- Show Example 10 to managed AsNewMethode 'QuerInterface'
- Change RefCounter. Begin now with Zero
Helpcode to create own Uuid
- Added QueryInterface for compatible with Interface 'IUnknown'.
-- The default result of QueryInterface is constant 'E_NoInterface' for compatibles with Linux and Mac
-- Show Example 10 to managed AsNewMethode 'QuerInterface'
- Change RefCounter. Begin now with Zero
Helpcode to create own Uuid
Code: Select all
Procedure.s CreateUuid()
Protected Uuid.iid, result.s, i
UuidCreate_(Uuid.iid)
result = " DataSection" + #LF$
result + " Uuid:" + #LF$
result + " Data.l $" + RSet(Hex(Uuid\Data1), 8, "0") + #LF$
result + " Data.w $" + RSet(Hex(Uuid\Data2), 4, "0") + ", $" + RSet(Hex(Uuid\Data3), 4, "0") + #LF$
result + " Data.b $" + RSet(Hex(Uuid\Data4[0]), 2, "0")
For i = 1 To 7
result + ", $" + RSet(Hex(Uuid\Data4[i]), 2, "0")
Next
result + #LF$
result + " EndDataSection" + #LF$
ProcedureReturn result
EndProcedure
; ***************************************************************************************
Uuid.s = CreateUuid()
SetClipboardText(Uuid)
Debug Uuid
Debug "Copied into clipboard"
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
Re: Module BaseClass (Module as Object)
Example 10 - Overwrite Method QueryInterface (For Windows)
Update v1.15
:wink:
Update v1.15
Code: Select all
;-TOP
; Example 10 IUnknown
IncludeFile "Modul_BaseClassSmall.pb"
DeclareModule MyObject
EnableExplicit
Interface iMyObject Extends BaseClass::iBaseClass
Add(Value)
Sub(Value)
Result()
EndInterface
Structure sMyObject Extends BaseClass::sBaseClass
Value.i
EndStructure
; Own Uuid
DataSection
IID_IMyObject:
Data.l 3ドルC4855AF
Data.w 3ドルAC7, 4ドルA60
Data.b $FF, $FF, $FF, 2ドルA, 06,ドル 54,ドル 54,ドル $FF
EndDataSection
Declare New()
EndDeclareModule
Module MyObject
EnableExplicit
UseModule BaseClass
NewClass(iMyObject)
; ---------------------------------------------------------------------------
; Overwrite Methode QueryInterface
Procedure QueryInterface(*This.sBaseClass, *riid, *ppvObject.integer)
Protected *new
If *ppvObject = 0
ProcedureReturn #E_INVALIDARG
EndIf
If CompareMemory(*riid, ?IID_IUnknown, 16)
LockMutex(*This\System\Mutex)
*ppvObject\i = *This
*This\System\RefCount + 1
UnlockMutex(*This\System\Mutex)
ProcedureReturn #S_OK
ElseIf CompareMemory(*riid, ?IID_IMyObject, SizeOf(iid))
*new = New()
If *new
*ppvObject\i = *new
ProcedureReturn #S_OK
Else
ProcedureReturn #E_OUTOFMEMORY
EndIf
Else ; No Interface
ProcedureReturn #E_NOINTERFACE
EndIf
EndProcedure : AsNewMethode(QueryInterface)
; ---------------------------------------------------------------------------
Procedure Initialize(*this.sMyObject)
Debug "Initialize Object " + Hex(*this)
EndProcedure : AsInitializeObject(Initialize)
; ---------------------------------------------------------------------------
Procedure Dispose(*this.sMyObject)
Debug "Dispose Object " + Hex(*this)
EndProcedure : AsDisposeObject(Dispose)
; ---------------------------------------------------------------------------
Procedure Add(*this.sMyObject, Value)
*this\Value + Value
EndProcedure : AsMethode(Add)
; ---------------------------------------------------------------------------
Procedure Sub(*this.sMyObject, Value)
*this\Value - Value
EndProcedure : AsMethode(Sub)
; ---------------------------------------------------------------------------
Procedure Result(*this.sMyObject)
ProcedureReturn *this\Value
EndProcedure : AsMethode(Result)
; ---------------------------------------------------------------------------
Procedure New()
InitObject(sMyObject)
EndProcedure
; ---------------------------------------------------------------------------
DataSection
IID_IUnknown: ; {00000000-0000-0000-C000-000000000046}'
Data.l 00000000ドル
Data.w 0000,ドル 0000ドル
Data.b $C0, 00,ドル 00ドル , 00ドル , 00,ドル 00ドル , 00ドル , 46ドル
EndDataSection
; ---------------------------------------------------------------------------
CheckInterface()
EndModule
; ***************************************************************************************
;-Test
Debug "Create Object"
Define *obj.IUnknown
*obj = MyObject::New()
Debug "--------------------------------"
r1 = *obj\QueryInterface(?IID_IUnknown, @*obj_temp)
If r1 = #S_OK
Debug "QueryInterface IUnknown Ok: Object " + Hex(*obj)
Debug "AddRef: " + *obj\AddRef()
Debug "Release IUnknown: " + *obj\Release()
Debug "Release IUnknown: " + *obj\Release()
EndIf
Debug "--------------------------------"
Define *obj2.MyObject::iMyObject
If *obj\QueryInterface(MyObject::?IID_IMyObject, @*obj2) = #S_OK
Debug "QueryInterface IID_MyObject Ok: Object " + Hex(*obj2)
Debug "Add 1000"
*obj2\Add(1000)
Debug "Sub 100"
*obj2\Sub(100)
Debug "Result: " + *obj2\Result()
Debug "Relaease MyObject: " + *obj2\Release()
EndIf
Debug "--------------------------------"
If *obj\QueryInterface(?IID_IDispatch, 0) = #S_OK
Debug "IDispatch Ok"
Debug "Release IDispatch: " + *obj\Release()
Else
Debug "No Interface IDispatch"
EndIf
Debug "--------------------------------"
Debug "Release Object"
Debug "Release: " + *obj\Release()
DataSection
IID_NULL: ; {00000000-0000-0000-0000-000000000000}
Data.l 00000000ドル
Data.w 0000,ドル 0000ドル
Data.b 00,ドル 00,ドル 00,ドル 00,ドル 00,ドル 00,ドル 00,ドル 00ドル
IID_IUnknown: ; {00000000-0000-0000-C000-000000000046}'
Data.l 00000000ドル
Data.w 0000,ドル 0000ドル
Data.b $C0, 00,ドル 00ドル , 00ドル , 00,ドル 00ドル , 00ドル , 46ドル
IID_IDispatch:
Data.l 00020400ドル
Data.w 0000,ドル 0000ドル
Data.b $C0,00,ドル00,ドル00,ドル00,ドル00,ドル00,ドル46ドル
IID_IClassFactory:
Data.l 00000001ドル
Data.w 0000,ドル 0000ドル
Data.b $C0, 0,ドル 0,ドル 0,ドル 0,ドル 0,ドル 0,ドル 46ドル
EndDataSection
Last edited by mk-soft on Sat Feb 08, 2020 2:02 pm, edited 12 times in total.
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
- ts-soft
- Always Here
Always Here - Posts: 5756
- Joined: Thu Jun 24, 2004 2:44 pm
- Location: Berlin - Germany
Re: Module BaseClass (Module as Object)
Better don't Import UUID.lib : http://www.purebasic.fr/english/viewtop ... 79#p205779
Better use Datasection, make a smaller foot :wink:
Better use Datasection, make a smaller foot :wink:
PureBasic 5.73 | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Old bugs good, new bugs bad! Updates are evil: might fix old bugs and introduce no new ones.
Image
Old bugs good, new bugs bad! Updates are evil: might fix old bugs and introduce no new ones.
Image
Jump to
- PureBasic
- ↳ Coding Questions
- ↳ Game Programming
- ↳ 3D Programming
- ↳ Assembly and C Programming in PureBasic
- ↳ The PureBasic Editor
- ↳ The PureBasic Form Designer
- ↳ General Discussion
- ↳ Feature Requests and Wishlists
- ↳ Tricks 'n' Tips
- Bug Reports
- ↳ Bugs - Windows
- ↳ Bugs - Linux
- ↳ Bugs - Mac OSX
- ↳ Bugs - C backend
- ↳ Bugs - 3D Engine
- ↳ Bugs - IDE
- ↳ Bugs - Documentation
- OS Specific
- ↳ AmigaOS
- ↳ Linux
- ↳ Windows
- ↳ Mac OSX
- ↳ Raspberry PI
- Miscellaneous
- ↳ Announcement
- ↳ Off Topic
- Showcase
- ↳ Applications - Feedback and Discussion
- ↳ PureFORM & JaPBe
- ↳ TailBite