Rustic workaround for point 1 : Macros for singleton
In each type where singleton behavior is needed, a workaround is to insert the matching singleton code for declaration and body.
To simplify the syntax, 2 macros are called for each type where singleton behavior is needed:
- One macro for the declaration ('singletonDeclaration()') and another macro for the body ('singletonBody()').
- The two macros have a same parameter ('typeName') which is the name of the type which uses these.
- The two macros bodies are encapsulated in a file to include ('singleton.bi') and the file is included once at the main file header.
- The singleton creation is called by the syntax: 'pointer = typeName.createSingleton()'.
- The singleton suppression is called by the syntax: 'typeName.deleteSingleton()'.
- The user must always provide a default constructor body and a destructor body, even empty (code can be insert within each one), and at opposite no constructror declaration neither destructor declaration).
singleton.bi:
Code: Select all
#Macro singletonDeclaration (typeName)
Public:
Declare Static Function createSingleton () As ##typeName Ptr
Declare Static Sub deleteSingleton ()
Private:
Static As ##typeName Ptr ref
Declare Constructor ()
Declare Constructor (Byref rhs As ##typeName)
Declare Destructor ()
Public:
#Endmacro
#Macro singletonBody (typeName)
Dim As ##typeName Ptr ##typeName.ref = 0
Static Function ##typeName.createSingleton () As ##typeName Ptr
If ##typeName.ref = 0 Then
##typeName.ref = New ##typeName
Return ##typeName.ref
Else
Return 0
End If
End Function
Static Sub ##typeName.deleteSingleton ()
If ##typeName.ref > 0 Then
Delete ##typeName.ref
##typeName.ref = 0
End If
End Sub
#Endmacro
The singleton code is simple:
- The default constructor and copy constructor are declared private in order to forbid any object user creation by 'Dim' or 'New'.
- Instead, a public static member function allows creation of a single object by using a private static member pointer to store the unique object address when exists.
- The destructor is declared private in order to forbid any object user suppression by 'Delete'.
- Instead, a public static member sub allows a single suppression of the object by using the private static member pointer to check the unique object address and clear it if exists.
(user must always provide a default constructor body and a destructor body, even empty (some code can be insert within each one), and obviously no constructror declaration neither destructor declaration)
main.bas:
Code: Select all
#Include "singleton.bi"
Type thing
singletonDeclaration(thing)
Dim i As Integer ''for example
'.....
End Type
singletonBody(thing)
'.....
Constructor thing () ''mandatory, even if empty
'.....
End Constructor
Destructor thing () ''mandatory, even if empty
'.....
End Destructor
'---------------------------------------------
Dim As thing Ptr ps1 = thing.createSingleton()
ps1->i = 1234
Print ps1, ps1->i
Dim As thing Ptr ps2 = thing.createSingleton()
Print ps2
thing.deleteSingleton()
Dim As thing Ptr ps3 = thing.createSingleton()
Print ps3, ps3->i
thing.deleteSingleton()
Sleep
[Edit]
- Added a static sub for singleton suppression to avoid multi suppressions by user (the destructor becomes private).
- the default constructor body and the destructor body are removed from the 'singletonBody()' and must be provided even empty by the user (user code can be insert within each one).