Results 1 to 1 of 1

Thread: User-defined typed lists

  1. #1
    thinBasic MVPs
    Join Date
    Oct 2012
    Location
    Germany
    Age
    54
    Posts
    1,529
    Rep Power
    170

    User-defined typed lists

    Today I have some small example to store any list of UDT to some enumerated List-Index without the need of creating arrays for those list-elements because it uses local virtual variables mostly and hides your data in the endless depth of heap.
    It uses one small global array to organize this. The array-size depends on count of lists * 16 bytes - so the array uses only 16 Bytes for one complete list, no matter how many elements it has.
    Size of a list is limited by your memory and the count of elements per list which must not exceed 2^31-1 (&H7FFFFFFF)

    UserLists-Unit comes with 9 Functions, short description:

    First of all you'll have to create some list, therefore call

    List_CreateNew(yourListIndex, sizeOf(yourType))
    - will return value <> 0 if succeeds
    (value is the associated index of Userlists-array)
    thereafter you can add new elements to your list using:

    List_AddElement(yourListIndex)
    which will return a pointer to the new created element or 0 if fails

    List_Exists(yourListIndex)
    will return a value <> 0 if a list with yourListIndex exists
    the number represents the index of Userlists-array which is assigned to yourListIndex

    List_CurrentElement(yourListIndex)
    will return a pointer to the current element of your list or 0 if fails

    List_FirstElement(yourListIndex)
    will return a pointer to the first element of your list and make this the current element of yourListIndex or 0 if fails

    List_LastElement
    (yourListIndex)
    will return a pointer to the last element of your list and make this the current element of yourListIndex or 0 if fails
    List_NextElement(yourListIndex)
    will return a pointer to the next element of your list and make this the current element of yourListIndex or 0 if fails
    List_PreviousElement(yourListIndex)
    will return a pointer to the previous element of your list and make this the current element of yourListIndex or 0 if fails

    List_Reset(yourListIndex)
    will set the current element of yourListIndex to 0 - so you are before the first element and can go through the list using for example
    While List_NextElement(yourListIndex)
    ' do something with current element
    Wend


    ' this is demonstration how to use
    Uses "Console"
    
    #INCLUDE "UserLists.tBasicU"
    
    Type t_myType
      A As Long
      B As Byte
      C As String
    End Type     
    
    %myList1  = 333  ' can be any from 1 To &H7FFFFFFF
      
    Function TBMain()
    
    If List_CreateNew(%myList1, SizeOf(t_myType)) Then
      
      Local lType As t_myType At List_AddElement(%myList1)
      
      lType.A = 123
      lType.B = 1
      lType.C = "Hello"
      
      SetAt( lType, List_AddElement(%myList1) )
      
      lType.A = 345
      lType.B = 2
      lType.C = "World"
    
      SetAt( lType, List_AddElement(%myList1) )
    
      lType.A = 567
      lType.B = 3
      lType.C = "Nice weather today..."
      
      ' go through list without use of additional variables:
      
      List_Reset(%myList1)      ' set current element-index before first listed element
     
      While List_NextElement(%myList1)
        SetAt( lType, List_CurrentElement(%myList1) ) 
        PrintL lType.C
      Wend 
      PrintL
      
      ' now backward, needs a storage-var:
      DWord pElement = List_LastElement(%myList1)
      
      While pElement
        SetAt( lType, pElement)
        PrintL Str$(lType.A)
        pElement = List_PreviousElement(%myList1)
      Wend
      
      PrintL
      
      ' now total list- (create array of pointers):
      
      Long lListNumber = List_Exists(%myList1)
      Long i
      Local dElement(HEAP_Size(Userlists(lListNumber).Elements)/SizeOf(DWord)) As DWord At Userlists(lListNumber).Elements
      
      If UBound(dElement) Then
        For i = 1 To UBound(dElement)
          SetAt( lType, dElement(i) )
          PrintL Str$(lType.B)
        Next
      EndIf
    EndIf
    
    
    WaitKey   
    
    
    End Function
    
    and this is the Userlists.tBasicU, save next to the "main-file"

    Type t_UserList
      UserID   As Long
      lSize    As Long
      Current  As Long 
      Elements As DWord
    End Type
    
    Dim Userlists() As t_UserList : ReDim Userlists(1)
    
    ' --------------------------------------------------------------------------
    Function List_CreateNew(ByVal lID As Long, ByVal lSize As Long) As Long
      
      If lID < 1 Or lSize < 1 Then Return 0
      
      Local lList   As Long
      Local sID     As String = MKL$(lID)
      
      lList = Array Scan Userlists, Byte(UDT_ElementByte(Userlists(1).UserID),SizeOf(Long)), = sID
      If lList Then Return 0
     
      sID = MKL$(0)
     
      lList = Array Scan Userlists, Byte(UDT_ElementByte(Userlists(1).UserID),SizeOf(Long)), = sID
      If lList = 0 Then 
        ReDim Preserve Userlists(UBound(Userlists) + 1)
        lList = UBound(Userlists)
      EndIf
      
      With Userlists(lList)
        .UserID  = lID
        .lSize   = lSize
      End With
      
      Function = lList
      
    End Function  
     
    ' --------------------------------------------------------------------------
    
    Function List_Exists(ByVal lID As Long) As Long 
      
      Static sID As String 
      
      sID = MKL$(lID)
      Function = Array Scan Userlists, Byte(UDT_ElementByte(Userlists(1).UserID),SizeOf(Long)), = sID
    
    End Function
    
    ' --------------------------------------------------------------------------
    
    Function List_AddElement(ByVal lID As Long) As DWord
      
      Local lList As Long = List_Exists(lID)
      If Not lList Then Return 0
      
      Local sBuffer As String = String$(Userlists(lList).lSize, MKBYT$(0))
      Local pResult As DWord  = HEAP_AllocByStr(sBuffer)
      
      If Userlists(lList).Elements Then
        sBuffer = Peek$(Userlists(lList).Elements, HEAP_Size(Userlists(lList).Elements)) + MKDWD$(pResult)
        Userlists(lList).Elements = HEAP_Realloc(Userlists(lList).Elements, StrPtrLen(StrPtr(sBuffer)) )
        Poke$(Userlists(lList).Elements, sBuffer)
      Else
        Userlists(lList).Elements = HEAP_AllocByStr(MKDWD$(pResult))
      EndIf                      
      Userlists(lList).Current = HEAP_Size(Userlists(lList).Elements)/SizeOf(DWord)
      
      Function = pResult
    
    End Function
    
    ' --------------------------------------------------------------------------
    
    Function List_FirstElement(ByVal lID As Long) As DWord
      
      Local lList As Long = List_Exists(lID)
      If Not lList Then Return 0
      
      If Userlists(lList).Elements Then
        Userlists(lList).Current = 1
        Function = Peek(DWord, Userlists(lList).Elements) 
      EndIf
      
    End Function
    
    ' --------------------------------------------------------------------------
    
    Function List_NextElement(ByVal lID As Long) As DWord
      
      Local lList As Long = List_Exists(lID)
      If Not lList Then Return 0
      
      If Userlists(lList).Elements Then
        If HEAP_Size(Userlists(lList).Elements)/SizeOf(DWord) > Userlists(lList).Current Then
          Function = Peek(DWord, Userlists(lList).Elements + Userlists(lList).Current * SizeOf(DWord) )
          Userlists(lList).Current += 1
        EndIf
      EndIf
      
    End Function
    ' --------------------------------------------------------------------------
    
    Function List_LastElement(ByVal lID As Long) As DWord
      
      Local lList As Long = List_Exists(lID)
      If Not lList Then Return 0
      
      If Userlists(lList).Elements Then
        Userlists(lList).Current = HEAP_Size( Userlists(lList).Elements) / SizeOf(DWord)
        Function = Peek(DWord, Userlists(lList).Elements + HEAP_Size(Userlists(lList).Elements) - SizeOf(DWord) ) 
      EndIf
      
    End Function
    ' --------------------------------------------------------------------------
    
    Function List_PreviousElement(ByVal lID As Long) As DWord
      
      Local lList As Long = List_Exists(lID)
      If Not lList Then Return 0
      
      If Userlists(lList).Elements Then
        If Userlists(lList).Current > 1 Then
          Userlists(lList).Current -= 1
          Function = Peek(DWord, Userlists(lList).Elements + (Userlists(lList).Current - 1) * SizeOf(DWord) ) 
        EndIf 
      EndIf
      
    End Function
    ' --------------------------------------------------------------------------
    
    Function List_CurrentElement(ByVal lID As Long) As DWord
      
      Local lList As Long = List_Exists(lID)
      If Not lList Then Return 0
      
      If Userlists(lList).Elements Then 
        If Userlists(lList).Current Then
          If HEAP_Size(Userlists(lList).Elements)/SizeOf(DWord) >= Userlists(lList).Current Then
            Function = Peek(DWord, Userlists(lList).Elements + (Userlists(lList).Current - 1) * SizeOf(DWord) )
          EndIf
        EndIf
      EndIf
      
    End Function
    
    ' --------------------------------------------------------------------------
    
    Function List_Reset(ByVal lID As Long) As Boolean
      
      Local lList As Long = List_Exists(lID)
      If Not lList Then Return FALSE
      Userlists(lList).Current = 0
      Function = TRUE
      
    End Function
    ' --------------------------------------------------------------------------
    
    'Function List_GetElementCount(ByVal lID as Long) as Long
      
    ' Local lList As Long = List_Exists(lID)
    '  If Not lList Then Return 0
    
    ' Function = HEAP_Size(Userlists(lList).Elements)/SizeOf(DWord)
    
    'End Function
    
    have fun!
    Last edited by ReneMiner; 30-05-2013 at 13:34.
    I think there are missing some Forum-sections as beta-testing and support

Similar Threads

  1. Article: User defined entities
    By Petr Schreiber in forum vBCms Comments
    Replies: 0
    Last Post: 03-01-2011, 20:52
  2. User Defined Types
    By Charles Pegge in forum O2h Compiler
    Replies: 3
    Last Post: 18-03-2009, 01:28

Members who have read this thread: 2

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •