Example use of "FirstTime" library function: GUI i

Here you can share completed projects or parts of projects that may be useful to others. You may post files relevant to ZBasic - source code, schematics, etc.
Post Reply
kranenborg
Posts: 57
Joined: 27 July 2009, 14:20 PM
Location: Groningen, The Netherlands
Contact:

Example use of "FirstTime" library function: GUI i

Post by kranenborg »

I have found the "FirstTime" Library function (which returns True the first time it is called after a program download, otherwise False) very useful in an application (MahYong score calculator) where an educational but rather lengthy start-up message about the use of a device only needs to be shown a few times for novice users, after which the message can be skipped since the user is assumed to be sufficiently knowledgeable and only the short welcome greeting needs to be shown.

In the following code excerpt a class "DisplayGUI" has a constructor in which a counter is managed whose task is to keep track of how often the class has been called after a program download. The first time after download the counter (in persistent EEPROM memory) is set to a predefined value, subsequent calls will decrement its value if it is larger than zero.

The class method "ShownEnoughTimes" returns False if the counter is non-zero, True otherwise, and can be used by the application. This method is then used in the "Greeting" method which prints the start-up message, which may be long or short depending on the download history. No user intervention is needed.


Code: Select all

Class DisplayGUI 

	Private Const DownloadCounterAddress as Integer = 100
	Private Const maxIntro as Byte = 10
	Dim downloadStatus as Byte
	
	
	Public Sub _Create()

		If FirstTime Then
			Call PersistentPoke(maxIntro,DownloadCounterAddress)
		Else
			downloadStatus = PersistentPeek(DownloadCounterAddress)
			If downloadStatus > 0 then
				downloadStatus = downloadStatus - 1
				Call PersistentPoke(downloadStatus,DownloadCounterAddress)
			End If
		End If

	End Sub


   Public Function ShownEnoughTimes() as Boolean

		downloadStatus = PersistentPeek(DownloadCounterAddress)
		If downloadStatus > 0 Then 
			ShownEnoughTimes = False
		Else
			ShownEnoughTimes = True
		End If

	End Function

' ...
' ...

' Public method for start-up message:

   Public Sub Greeting()
 
   If Not ShownEnoughTimes Then
       'Generate introductory & educational message here
   End If       

   'Standard greeting message here

   End Sub

End Class
dkinzer
Site Admin
Posts: 3120
Joined: 03 September 2005, 13:53 PM
Location: Portland, OR

Post by dkinzer »

Very nice.

One suggestion would be to use a Persistent class variable, e.g.

Code: Select all

Class DisplayGUI
   Private Static DownloadCounter as Persistent Integer
   ...
End Class
The advantage of doing this is that it allows the compiler to assign the address in Persistent memory rather than managing the address manually.
- Don Kinzer
kranenborg
Posts: 57
Joined: 27 July 2009, 14:20 PM
Location: Groningen, The Netherlands
Contact:

Post by kranenborg »

Thanks Don,

Somehow I had forgotten that ZBASIC variables also can be located in persistent memory; some other systems treat EEPROM as a separate memory bank accessible only through Peek/Poke-like operations. Your proposal will make the solution much more straightforward and simple.

Just one question: to me the necessity of the Static keyword is not entirely clear to me: Since the variable is in persistent memory it will have a permanent location, and the constructor will create a proper initialization as well, effectively making it a "static-like" variable?

BR, Jurjen
kranenborg
Posts: 57
Joined: 27 July 2009, 14:20 PM
Location: Groningen, The Netherlands
Contact:

Post by kranenborg »

Found the asnwer amyself after compiling and then reading section 4.17 of the manual: Class members with the persistent attribute must be declared static ...

/Jurjen
dkinzer
Site Admin
Posts: 3120
Joined: 03 September 2005, 13:53 PM
Location: Portland, OR

Post by dkinzer »

kranenborg wrote:Class members with the persistent attribute must be declared static ...
The Static attribute on a class data member means that the member belongs to the class itself and that it won't be replicated for each instance of the class. The Static attribute requirement for Persistent data items is due to the fact that there is no mechanism for run-time allocation of Persistent memory.
- Don Kinzer
kranenborg
Posts: 57
Joined: 27 July 2009, 14:20 PM
Location: Groningen, The Netherlands
Contact:

Post by kranenborg »

Thanks Don, the solution then simplifies to the following code, tested on a ZX-328nu:

Code: Select all

Option Objects

Class DisplayGUI 

	Private Const maxIntro as Byte = 4 
	Private Static DownloadCounter as Persistent Byte 
     
     
	Public Sub _Create() 

		If FirstTime Then 
			DownloadCounter = MaxIntro
		Else 
			If DownloadCounter  > 0 then 
				DownloadCounter = DownloadCounter - 1 
			End If 
		End If 

	End Sub 


	Public Function ShownEnoughTimes() as Boolean 

		ShownEnoughTimes = Not Cbool(DownloadCounter)

	End Function 

 ' ... 
 ' ... 

 ' Public method for start-up message: 

	Public Sub Greeting() 
   
		If Not ShownEnoughTimes Then 
			Debug.Print "Educational message: So many times left: "; CStr(DownloadCounter) 
		End If        

		Debug.Print "Standard greeting message here" 

	End Sub 

 End Class
 
 
 Sub Main()
 
	Dim GUIobject As DisplayGUI = _Create
 
	Call GUIobject.Greeting
	
 End Sub
Post Reply