this Type is aimed at a 'Most Recently Used' implementation (MRU), which means:
- latest entry at the lowest position (index = 0) of array (string-array)
- at start, the pre-defined (sized) array is filled, first
- whenever it's full, the entry at UBound() is deleted, before the new string is added
Code: Select all
' History_type_test2.bas -- 2018-07-13, by MrSwiss
'
' compile: -s console
'
Type History
Private:
As ZString Ptr p_str ' only for real strings (NOT binary strings!)
Public:
Declare Destructor() ' we need a custom destructor here! (whenever dealing with ptr's)
Declare Sub add_str(h() As History, ByRef n_str As Const String) ' this is the workhorse
Declare Sub show(ByVal row As UByte=1, ByVal col As UByte=1, ByVal fgc As UByte=7, ByVal bgc As UByte=0)
End Type
Destructor History()
' on destruction: free the allocated mem. (discard zstring ptr's data)
If This.p_str <> 0 Then DeAllocate(This.p_str) : This.p_str = 0
End Destructor
Sub History.add_str( _ ' add a new string (deleting one, if needed)
h() As History, _ ' array's are always ByRef (implicit, specifier NOT allowed)
ByRef n_str As Const String _ ' read only
)
Dim As ULong siz = Len(n_str), lb = LBound(h), ub = UBound(h)
' always add new string at index: 0 (aka: at the top, in a up-counting loop)
If h(ub).p_str <> 0 Then DeAllocate(h(ub).p_str) ' kill the oldest string (free the mem.)
For m As UInteger = ub To lb + 1 Step -1 ' copy ptr's values to new location (in array)
h(m).p_str = h(m - 1).p_str ' push all remaining, one position down (0 becomes 1 etc.)
Next
h(lb).p_str = CAllocate(siz + 1, 1) ' allocate cleared mem. for the new string
*h(lb).p_str = n_str ' copy string data --> finished
End Sub
Sub History.show( _
ByVal row As UByte = 1, _ ' default: top
ByVal col As UByte = 1, _ ' default: left
ByVal fgc As UByte = 7, _ ' foreground color, default: grey
ByVal bgc As UByte = 0 _ ' background color, default: black
)
Locate row, col ' cursor positioning
If fgc <> 7 OrElse bgc <> 0 Then ' if there is/are user defined color(s): use it/them
Color(fgc, bgc) : Print *This.p_str : Color(7, 0) ' after use: reset to default
Else ' use default console colors
Print *This.p_str ' dereference the ptr (to show string data)
End If
End Sub
' end type definition
' ===== Test/Demo code =====
' pick a random positive number, from a pre-defined range (return type = ULong)
#Define ULRange(l, h) ( CULng(Rnd * ( (h) - (l) ) + (l)) ) ' useful for indexing
Randomize
Dim As History hist(0 To 9) ' fixed size array, 10 elements
Dim As String t_str(0 To 49), _ ' fixed size array, 50 elements
title = "*** History (a MRU type) -- Test/Demo ***"
For i As UInteger = 0 To 49 ' generate t_str() data
If i > 9 Then ' occures more than below 10
t_str(i) = " " + Str(i) + " test-string " ' prepend a single space
Else
t_str(i) = " " + Str(i) + " test-string " ' prepend two space's
End If
Rnd : Rnd : Rnd : Rnd : Rnd : Rnd ' heat up randomizer
Next
For f As Integer = 6 To 0 Step -1 ' initialize array partly (to show it filling up)
' any valid index can be used below: hist(index) ... (nul is safe, always)
hist(0).add_str(hist(), t_str(f)) ' consecutive from string-array
Next
' finished: preparing things (ready, to start main-loop)
Do
Color 15 : Print title : Print String(Len(title), "~") : Color 7
For i As UInteger = LBound(hist) To UBound(hist)
hist(i).show(i + 4, 3, 14, 1) ' any position & color's (yellow, dark-blue)
Next
hist(0).add_str(hist(), t_str(ULRange(0, 49))) ' use a random chosen new string
If Len(InKey()) > 0 Then Exit Do ' on user action: QUIT prog.
Sleep(2000) : Cls ' give some time to: 'look at it'
Loop
' clean up ...
Erase(hist) : Erase(t_str) ' destroy array's (assures Destructor() call)
' ===== END Test/Demo code ===== ' ----- EOF -----