PDA

View Full Version : enumerating types



ReneMiner
06-02-2016, 16:54
Most of the readers here have seen my thinICE-project and tUI with it.
(So you might have a look at the Type_Functions.tBasicU)

Its all based on allocating memory for controls and data at heap-memory.
All it needs is a pointer at the very first position of any variable that extends a basetype where we can read out the typename and we can store pointers of variables that are different udts in a row of DWords.
So the basetype always looks as


Type tTypedBasetype

pType As DWord ' must be very first
' ...
End Type



Imagine you want to draw a list of different geometric shapes as triangles, rectangles and circles or something like that.
Or even process different UI-controls as buttons, menuitems, textboxes, treeviews, codefields...
And all of that in a clearly structured, well readeable and proceedeable type-oriented manner.
All UDTs that Extends tTypedBasetype have first property pType, = to find directly at Varptr|MemoryPtr and it contains the result of below posted function Type_Enumerate = a pointer where the typename can be read out.

Even better:
if an allocated memory-area "knows" of which type it is we can create a variable by reading the typename at its pointer using keyword Like...

So my "idea/suggestion" were to implement a global type-name-enumeration as



' Filename "Type_Functions.tBasicU"


'---------------------------------------------------------------------------------
Function Type_Enumerate(ByVal sType As String, _
Optional ByVal TestExist As Boolean _
) As DWord
'---------------------------------------------------------------------------------
' to create a global uniform Type-name-enumeration
' every type gets stored only once
' the "enumerated" number can be used to compare types.

' every "enumerated" number is unique since it's a memory-pointer
' which is valid until the script ends

' all type-names get stored in UCase and can be read out at this
' pointer using Heap_Get()

' if testExist then will return 0 for "Typename not enumerated yet"

Static hAllTypes As DWord
' this points a heap with a list of pointers to all enumerated type-names

Local Index As Long ' will hold the index of requested pointer


If Not Type_Exists(sType) Then Return 0 ' if it's not a type then return nothing

sType = Ucase$(sType) ' from here all type-names work in UCASE

If HEAP_Size(hAllTypes) Then ' are there any pointers already?
' place virtual Dword-array upon the pointer-list:
Local vPtr(HEAP_Size(hAllTypes)/4) As DWord At hAllTypes

' and scan if any of the list points the requested type-name
Index = Array Scan vPtr Ptr, = sType

If Index Then
Return vPtr(Index)
EndIf

EndIf

' does not exist yet:
If TestExist Then Return 0

' store sType and append its Pointer to function-static hAllTypes
hAllTypes = HEAP_ReAllocByStr(hAllTypes, HEAP_Get(hAllTypes) & MKDWD$(HEAP_AllocByStr(sType)) )

' return last appended pointer
Function = Peek(DWord, HEAP_End(hAllTypes) - 3 )

' use Heap_Get on the result to read the type-name out

End Function


which helps to store & manage pointers + arrays of different udt-variables which are useful if one has to process different types (as controls, shapes, entities, any elements with different properties,... etc. etc. etc.) in a {row | loop}

Thinking of a future built-in to core class cHeap, the class could provide a "slot" to store the type of data stored at This cHeap at the very first position automatic. It needs the size of a DWord...

the unit Type_Functions.tBasicU consists of two more functions:



'---------------------------------------------------------------------------------
Function Type_SizeOf(ByVal sType As String) As Long
'---------------------------------------------------------------------------------
' returns SizeOf("sType")
' it would be useful to have a function that tells us
' the variable-size if we have the typename in a string

If Type_Exists(sType) Then
Select Case Ucase$(sType)
Case "PTR", "STRING"
Function = 4
Case Else
Local data Like sType At 0
Function = SizeOf(data)
End Select
EndIf

End Function

'---------------------------------------------------------------------------------
Function Type_AtPtr(ByVal p As DWord) As String
'---------------------------------------------------------------------------------
' returns Typename of UDTs theirs first element contains a typename-pointer

Function = HEAP_Get(Peek(DWord, p))

' allows for example within other functions:

' Local xxx Like Type_AtPtr(p) At p
' to create a fitting layover on some {allocated memory | string-data}
' equals:
' Local xxx Like Heap_Get(Peek(Dword, p)) At p

End Function


Programmers should be aware in case saving data not to save the typename-pointer but the name it points. :)

ReneMiner
11-02-2016, 11:47
Maybe it's not only useful to enumerate Type-names but also other stuff as Control-names or any other groups of names.
This example demonstrates how to enumerate stuff of any kind in different groups:


' #Filename "enumerate.tBasic"
Uses "console"

Alias HEAP_ReAllocByStr As HEAP_Set ' Heap_ReAllocByStr too long without autocomplete ;)


%TestExist = TRUE ' for better readability
%brightYellow = %CONSOLE_FOREGROUND_GREEN | %CONSOLE_FOREGROUND_RED | %CONSOLE_FOREGROUND_INTENSITY


' --------------------------------------------------------------------
Function TBMain()
' --------------------------------------------------------------------

Local pType(3) As DWord
Local pName(3) As DWord
Local i As Long


pType(1) = Enumerate( "Type", "STRING" )
pType(2) = Enumerate( "Type", "Boolean" )
pType(3) = Enumerate( "Type", "String" )

PrintL "enumerated as 'Type'" In %brightYellow
PrintL "Ptr ", "Data"
For i = 1 To UBound(pType)
PrintL Hex$(pType(i), 8), HEAP_Get(pType(i))
Next
PrintL

pName(1) = Enumerate( "Name", "myWindow" )
pName(2) = Enumerate( "Name", "MYBUTTON" )
pName(3) = Enumerate( "Name", "myButton" )

PrintL "enumerated as 'Name'" In %brightYellow
PrintL "Ptr ", "Data"

For i = 1 To UBound(pName)
PrintL Hex$(pName(i), 8), HEAP_Get(pName(i))
Next
PrintL

Print "myButton in Group 'Type' "
PrintL IIf$(Enumerate("Type", "myButton", %TestExist), "exists", "does not exist")

Print "myButton in Group 'Name' "
PrintL IIf$(Enumerate("Name", "myButton", %TestExist), "exists", "does not exist")

Print "bananas in Group 'Fruits' "
PrintL IIf$(Enumerate("Fruits", "bananas", %TestExist), "exists", "does not exist")


PrintL $CRLF & Repeat$(50, "-")
PrintL "any key to end"

WaitKey

End Function


' ---------------------------------------------------------------------
Function Enumerate( ByVal sGroup As String, _
ByVal sExpression As String, _
Optional ByVal testExist As Boolean _
) As DWord
' ---------------------------------------------------------------------
' enumerated Groups & Strings are case-insensitive

Static pGroups As DWord ' array of groups @heap
Static pLists As DWord ' corresponding array to pGroups

Local lGroup, lExpr As Long ' index of group & expression

Local pGroup() As DWord At 0 ' layover at pGroups
Local pList() As DWord At 0 ' layover at pLists
Local pExpr() As DWord At 0 ' layover at pList(lGroup)


If StrPtrLen(StrPtr(sGroup)) < 1 Then Return 0
If StrPtrLen(StrPtr(sExpression)) < 1 Then Return 0

sGroup = Ucase$(sGroup)
sExpression = Ucase$(sExpression)

' find the group:
ReDim pGroup(HEAP_Size(pGroups)/4) At pGroups

If HEAP_Size(pGroups) Then
lGroup = Array Scan pGroup Ptr, = sGroup
EndIf

If lGroup = 0 Then
If testExist Then Return 0

pGroups = HEAP_Set(pGroups, HEAP_Get(pGroups) & MKDWD$(HEAP_Set(0, sGroup)))
pLists = HEAP_Set(pLists, HEAP_Get(pLists) & MKDWD$(0))

ReDim pGroup(HEAP_Size(pGroups)/4) At pGroups
lGroup = UBound(pGroup)
EndIf

' find the list of pointers of the group
ReDim pList(lGroup) At pLists

If HEAP_Size(pList(lGroup)) Then
ReDim pExpr(HEAP_Size(pList(lGroup))/4) At pList(lGroup)
lExpr = Array Scan pExpr Ptr, = sExpression
If lExpr Then
Return pExpr(lExpr)
EndIf
EndIf

If testExist Then Return 0

' add new expression to the groups expressions-list:
pList(lGroup) = HEAP_Set(pList(lGroup), HEAP_Get(pList(lGroup)) & MKDWD$(HEAP_Set(0, sExpression)))

' return pointer to expression
Function = Peek(DWord, HEAP_End(pList(lGroup)) - 3)

End Function



Still- it would be useful to retrieve SizeOf("<typename in string-expression>")