Defined() as Local Scope Destructor
Posted: Sun Oct 21, 2012 11:42 am
Hi,
For the project I'm currently working on, I've found a very useful way to use the PureBasic compiler function 'Defined()'.
I wanted to share that with you, perhaps this will give you other ideas as well to use this very powerful feature of PureBasic.
For my project I've implemented a hierarchical logging system. Basically it allows to have a hierarchical view of which classes/procedures have been visited and from exactly where each log message has been produced and in which context.
Normally, to implement this in C++, you use a simple local object on the stack. When it is created (constructor called) it send a 'Log.Enter()' signal/message/call to the logging system, and when this object leave the scope of the procedure, the destructor is called and send a 'Log.Leave()' signal/message/call to the logging system. In between you use this object to log messages.
This is pretty automatic, you don't have to worry about the life time of this local object nor it's hierarchical nature/management.
In C, you have to do this manually whenever you leave your procedure. At each 'exit point' of your procedure you have to call for 'Log_Leave()'.
In PureBasic you have to do the same. But, thanks to this Defined() compiler function, you can bring back the automatic management of 'scope destructor' with the help of some macros too.
Here LOG_ENTER() is a Macro that define a local variable and automatically call for 'LogEnter()'. (in the actual implementation these macro and procedure also have arguments to define the 'area' and 'class/procedure' of this part of the code).
Then the ret() macro is defined this way:
'log_args' is a local variable used by the other logging macros to post messages, and 'LogLeave()' is then the logging system procedure that need to be called whenever the code exit the Procedure.
Thanks to the PureBasic 'Defined()' compiler function, I don't have to think about this anymore, it will automatically call for 'LogLeave()' whenever I exit a procedure and this, only if it 'detects' the use of the logging system through the definition of the specific local variable used by this system.
On a side note it also work for Procedures that return nothing, I use a ret( void ) macro for this, 'void' being defined as nothing.
This is very practical and in my case it simulates the automatic C++ scope destructor of local objects.
For the project I'm currently working on, I've found a very useful way to use the PureBasic compiler function 'Defined()'.
I wanted to share that with you, perhaps this will give you other ideas as well to use this very powerful feature of PureBasic.
For my project I've implemented a hierarchical logging system. Basically it allows to have a hierarchical view of which classes/procedures have been visited and from exactly where each log message has been produced and in which context.
Normally, to implement this in C++, you use a simple local object on the stack. When it is created (constructor called) it send a 'Log.Enter()' signal/message/call to the logging system, and when this object leave the scope of the procedure, the destructor is called and send a 'Log.Leave()' signal/message/call to the logging system. In between you use this object to log messages.
This is pretty automatic, you don't have to worry about the life time of this local object nor it's hierarchical nature/management.
In C, you have to do this manually whenever you leave your procedure. At each 'exit point' of your procedure you have to call for 'Log_Leave()'.
In PureBasic you have to do the same. But, thanks to this Defined() compiler function, you can bring back the automatic management of 'scope destructor' with the help of some macros too.
Code: Select all
Procedure.i MyProc()
LOG_ENTER()
Protected my_result.i = 0
; ../..
ret( my_result )
EndProcedure
Then the ret() macro is defined this way:
Code: Select all
Macro ret( r )
CompilerIf Defined( log_args, #PB_Variable )
LogLeave()
CompilerEndIf
ProcedureReturn r
EndMacro
Thanks to the PureBasic 'Defined()' compiler function, I don't have to think about this anymore, it will automatically call for 'LogLeave()' whenever I exit a procedure and this, only if it 'detects' the use of the logging system through the definition of the specific local variable used by this system.
On a side note it also work for Procedures that return nothing, I use a ret( void ) macro for this, 'void' being defined as nothing.
This is very practical and in my case it simulates the automatic C++ scope destructor of local objects.