Results 1 to 6 of 6

Thread: is Union a step to dynamic UDT-arrays?

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

    is Union a step to dynamic UDT-arrays?

    Not a feature request but some idea that spooks in my head for a few days already...

    Might it be possible to use UNION as a way to dynamic UDT-subsets?

    I know, Union does not support dynamic strings but UDTs "support" them...

    UNION t_Union

    st As ASCIIZ * 12
    b(12) As Byte ' at VarPtr(.st)

    End UNION


    would be the current supported syntax, but

    UNION t_DynamicByteArray

    st As String
    b() As Byte ' at StrPtr(.st)

    End UNION
    is currently not possible...

    Maybe someone can think the idea to an end?
    Last edited by ReneMiner; 14-05-2013 at 16:27.
    I think there are missing some Forum-sections as beta-testing and support

  2. #2
    Super Moderator Petr Schreiber's Avatar
    Join Date
    Aug 2005
    Location
    Brno - Czech Republic
    Posts
    7,128
    Rep Power
    732
    If creating wrappers is OK for you, it can be done this way:
    ' -- Types
    Type tVertex
      x As Single
      y As Single
      z As Single
    End Type
    
    Type tPolygon     
      sVertexBuffer As String ' -- Dynamic string to serve as buffer for our array
    End Type   
    
    ' -- Creating polygon
    Dim p As tPolygon
    
    ' -- Dimensioning the array
    tPolygon_RedimArray(p, 3) ' -- 3 elements
    
    ' -- Assigning array
    tPolygon_Set(p, 1,
                 1, 2, 3)
                 
    tPolygon_Set(p, 2,
                 4, 5, 6)
                 
    tPolygon_Set(p, 3,
                 7, 8, 9)  
                 
    Dim v As tVertex
    Dim i As Long   
    
    ' -- Reading array
    For i = 1 To 3             
      v = tPolygon_Get(p, i)            
      MsgBox 0, UDT_ElementsData_Join(v, ", ")             
    Next  
                        
    ' -- Wrapper routines to manage the array                    
    Function tPolygon_UBound(var As tPolygon)
      Return Len(var.sVertexBuffer)/SizeOf(tVertex)
    End Function
    
    Function tPolygon_RedimArray( var As tPolygon, newUBound As Long, Optional preserveFlag As Long = FALSE )
      
      Long oldUBound = tPolygon_UBound(var)
      
      If newUbound = oldUbound Then Exit Function
      
      If preserveFlag Then
        
        If newUbound > oldUbound Then
          var.sVertexBuffer+= String$(SizeOf(tVertex) * (newUBound-oldUbound), 0)   
        Else                  
          var.sVertexBuffer = LEFT$(var.sVertexBuffer, SizeOf(tVertex) * newUbound)
        End If  
        
      Else            
      
        var.sVertexBuffer = String$(SizeOf(tVertex) * newUBound, 0)  
    
      End If
    
    End Function    
    
    Function tPolygon_Get( var As tPolygon, index As Long ) As String
      
      Long curUBound = tPolygon_UBound(var)
      If Outside(index, 1, curUBound) Then 
        MsgBox 0, "Invalid index"
        Exit Function
      End If         
      
      Dim sArray(curUBound) As tVertex At StrPtr(var.sVertexBuffer)
      
      Return sArray(index)
      
    End Function   
    
    Function tPolygon_Set( var As tPolygon, index As Long, x As Single, y As Single, z As Single )
    
      Long curUBound = tPolygon_UBound(var) 
      If Outside(index, 1, curUBound) Then 
        MsgBox 0, "Invalid index"
        Exit Function
      End If         
      
      Local v As tVertex
      v.x = x
      v.y = y
      v.z = z
                  
      Dim sArray(curUBound) As String * SizeOf(tVertex) At StrPtr(var.sVertexBuffer)
      
      sArray(index) = Peek$(VarPtr(v), SizeOf(tVertex))
      
    End Function
    
    Petr
    Learn 3D graphics with ThinBASIC, learn TBGL!
    Windows 10 64bit - Intel Core i5-3350P @ 3.1GHz - 16 GB RAM - NVIDIA GeForce GTX 1050 Ti 4GB

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

    Lightbulb Alias String As DynamicColorPalette In Union With TBGL_TRGB

    Currently I just use Strings as "dynamic subsets" and like this

    Alias String As DynamicColorPalette
    
    Dim foo As DynamicColorPalette 
    
    ' add colors as
    foo += MKBYT$(Red) + MKBYT$(Green) + MKBYT$(Blue)
    
    
    If StrPtrLen(StrPtr(foo)) > 0 Then
    
    Local lFoo( StrPtrLen(StrPtr(foo))/ SizeOf(TBGL_TRGB) ) As TBGL_TRGB At StrPtr(foo)
    
    ' now would have lFoo(1).R, lFoo(1).G and lFoo(1).B - that's ok
    
    '                  but I always repeatedly
    ' have to put a virtual array over the same thing before...
    
    ' or like this to get just one desired value - fine too 
    
    Local lFoo1 as TBGL_TRGB 
    Memory_Copy(StrPtr(foo) + SizeOf(TBGL_TRGB) * (DesiredIndex -1), VarPtr(lFoo1), SizeOf(TBGL_TRGB))
    
    ' now have lFoo1.R, lFoo1.G and lFoo1.B, surely can peek just one byte out there too...
    Endif
    
    So maybe call it
    Alias String As DynamicColorPalette In Union With TBGL_TRGB
    
    Last edited by ReneMiner; 15-05-2013 at 08:18.
    I think there are missing some Forum-sections as beta-testing and support

  4. #4
    thinBasic MVPs
    Join Date
    Oct 2012
    Location
    Germany
    Age
    54
    Posts
    1,527
    Rep Power
    170
    I have also another solution to emulate dynamic udt-subsets which does not use strings but heap to store, check this example:

    Uses "Console"
    
    Alias DWord As DynamicVariable
    
    Type t_Test
      bBytes   As DynamicVariable
      lLongs   As DynamicVariable
      sStrings As DynamicVariable
    End Type  
    
    Dim DynamicReserve As String ' use this in all subs + functions - so no local declaration-time needed
     
    Dim foo As t_Test
    Dim i   As Long
    
    
    ' "SetBytes(foo.bBytes, 1, 2, 4, 8)" : 
    
    foo.bBytes = HEAP_AllocByStr(MKBYT$(1) + MKBYT$(2) + MKBYT$(4) + MKBYT$(8))
    
    If foo.bBytes Then
      PrintL "UBound foo.bBytes =" + Str$(HEAP_Size(foo.bBytes))
      PrintL "------------------------------"
      For i = 1 To HEAP_Size(foo.bBytes)' / SizeOf(Byte)
        PrintL "foo.bBytes(" + TStr$(i) + ") = " + Str$(Peek(Byte, foo.bBytes + i-1)) 
      Next
    EndIf
    
    foo.lLongs = HEAP_AllocByStr(MKL$(&H10000000) + MKL$(&H20000000) + MKL$(&H30000000) + MKL$(&H40000000))
    
    If foo.lLongs Then 
      PrintL "UBound foo.lLongs =" + Str$(HEAP_Size(foo.lLongs)/SizeOf(Long))
      PrintL "------------------------------"
      
      For i = 1 To HEAP_Size(foo.lLongs) / SizeOf(Long)
        PrintL "foo.lLongs(" + TStr$(i) + ") = " + Str$(Peek(Long, foo.lLongs + (i-1) * SizeOf(Long) )) 
      Next
    EndIf
    
    PrintL "------------------------------"
    
    PrintL "append 1 byte value 32 to foo.bBytes..." 
    
    foo.bBytes = AddByte(foo.bBytes, 32)     
    
    PrintL "oops, forgot 16, so insert at position 5" 
    PrintL
    
    foo.bBytes = InsertByte(foo.bBytes, 5, 16)
    
    PrintL "now foo.bBytes has" + Str$(HEAP_Size(foo.bBytes)) + " elements"
    PrintL "------------------------------"
    
    
    
    If foo.bBytes Then
      For i = 1 To HEAP_Size(foo.bBytes)' / SizeOf(Byte)
        PrintL "foo.bBytes(" + TStr$(i) + ") = " + Str$(Peek(Byte, foo.bBytes + i-1)) 
      Next
    EndIf
    
    PrintL "------------------------------"
    
    foo.sStrings = AddString(foo.sStrings, "World")
    foo.sStrings = AddString(foo.sStrings, "Hello") 
    
    PrintL GetString(foo.sStrings, 2)
    PrintL GetString(foo.sStrings, 1)
    
    
    WaitKey
    ' ------------------------------------------
    Function AddByte(ByVal pBytes As DynamicVariable, Optional bVal As Byte) As DynamicVariable
      
      If HEAP_Size(pBytes) Then
        DynamicReserve = Peek$(pBytes, HEAP_Size(pBytes)) + MKBYT$(bVal)
        HEAP_Free(pBytes)
        pBytes = HEAP_AllocByStr(DynamicReserve)
      Else
        pBytes = HEAP_AllocByStr(MKBYT$(bVal))
      EndIf
      
      Function = pBytes
      
    End Function 
    ' ------------------------------
    Function InsertByte(ByVal pBytes As DynamicVariable, ByVal Position As Long, Optional bVal As Byte) As DynamicVariable
      
      If HEAP_Size(pBytes) Then
        If Position <= 1 Then
          DynamicReserve = MKBYT$(bVal) + Peek$(pBytes, HEAP_Size(pBytes)) 
        ElseIf Position > HEAP_Size(pBytes) Then
          DynamicReserve = Peek$(pBytes, HEAP_Size(pBytes)) + MKBYT$(bVal)
        Else
          DynamicReserve = Peek$(pBytes, Position - 1) + MKBYT$(bVal) + Peek$(pBytes + Position - 1, HEAP_Size(pBytes) + 1 - Position )
        EndIf
        
        HEAP_Free(pBytes)
      
        pBytes = HEAP_AllocByStr(DynamicReserve)
      Else
        pBytes = HEAP_AllocByStr(MKBYT$(bVal))
      EndIf
      Function = pBytes
    
    End Function  
    ' ---------------------------------
    Function AddString(ByVal pStrings As DynamicVariable, Optional sString As String) As DynamicVariable
      
      If HEAP_Size(pStrings) Then
        If sString = "" Then 
          DynamicReserve = Peek$(pStrings, HEAP_Size(pStrings)) + MKDWD$(0)
        Else
          DynamicReserve = Peek$(pStrings, HEAP_Size(pStrings)) + MKDWD$(HEAP_AllocByStr(sString))
        EndIf
        HEAP_Free(pStrings)
      
        pStrings = HEAP_AllocByStr(DynamicReserve)
      
      Else
        If sString = "" Then 
          pStrings = HEAP_AllocByStr(MKDWD$(0))
        Else  
          pStrings = HEAP_AllocByStr(MKDWD$(HEAP_AllocByStr(sString)) )
        EndIf
      EndIf        
          
      Function = pStrings
      
    End Function
    ' --------------------
    Function GetString( ByVal pStrings As DynamicVariable, ByVal Position As Long) As String
      
      If Not Between(Position, 1, HEAP_Size(pStrings)/SizeOf(DynamicVariable)) Then Return ""
      
      If Peek(DynamicVariable, pStrings + (Position-1) * SizeOf(DynamicVariable)) = 0 Then Return ""
      
      Function = Peek$(Peek(DynamicVariable, pStrings + (Position-1) * SizeOf(DynamicVariable)), HEAP_Size(Peek(DynamicVariable, pStrings + (Position-1) * SizeOf(DynamicVariable) )) )
      
    
    End Function
    
    AddByte is not really needed as a seperate function, but to clear the example...Of course it would need Insert-Functions for all used types and also some special treatment when replacing Strings...
    In any case you can Dim a virtual array over this - like
    local myBytes(Heap_Size(foo.bBytes)) as Byte at foo.bBytes
    
    for strings you put a Dword-Array over to read out the "String-Pointers"
    Last edited by ReneMiner; 18-05-2013 at 11:47.
    I think there are missing some Forum-sections as beta-testing and support

  5. #5
    thinBasic author ErosOlmi's Avatar
    Join Date
    Sep 2004
    Location
    Milan - Italy
    Age
    57
    Posts
    8,777
    Rep Power
    10
    Do you know you can have arrays of dynamic strings inside UDT?

    Maybe this can help:
    Uses "Console"
    
    
    Type MyType
        aaa         As String '---Single dynamic string inside UDT
        bbb(100000) As String '---Array of dynamic string inside UDT
        ccc         As Long
        ddd(10)     As Long
    end type
    
    
    dim x1 as mytype
    dim count as long
    
    
    '---Allocate some big data
    x1.aaa    = String$(       10, "X") '--- 10 bytes
    x1.bbb(1) = String$(  1000000, "Y") '---  1 MBytes
    x1.bbb(2) = String$( 10000000, "Z") '--- 10 MBytes
    x1.bbb(3) = String$(100000000, "W") '---100 MBytes
    
    
    
    
    '---Show some big data
    PrintL "x1.aaa   ", x1.aaa    
    PrintL "x1.bbb(1)", LEFT$(x1.bbb(1), 50), "Size:", Len(x1.bbb(1))
    PrintL "x1.bbb(2)", LEFT$(x1.bbb(2), 50), "Size:", Len(x1.bbb(2)) 
    PrintL "x1.bbb(3)", LEFT$(x1.bbb(3), 50), "Size:", Len(x1.bbb(3)) 
    
    
    '---Clean big data
    x1.aaa    = ""
    x1.bbb(1) = ""
    x1.bbb(2) = ""
    x1.bbb(3) = ""
    
    
    PrintL "---Press a key to continue---"
    WaitKey
    
    I know I have to implement it a bit. I should add some important features like:
    1. REDIM [PRESERVE] dynamic string arrays inside UDT (actually they must be defined during UDT declaration
    2. UBOUND/LBOUND work with dynamic string arrays inside UDT
    3. VARPTR/STRPTR work with dynamic string arrays inside UDT
    4. ...
    Last edited by ErosOlmi; 18-05-2013 at 15:04.
    www.thinbasic.com | www.thinbasic.com/community/ | help.thinbasic.com
    Windows 10 Pro for Workstations 64bit - 32 GB - Intel(R) Xeon(R) W-10855M CPU @ 2.80GHz - NVIDIA Quadro RTX 3000

  6. #6
    thinBasic MVPs
    Join Date
    Oct 2012
    Location
    Germany
    Age
    54
    Posts
    1,527
    Rep Power
    170
    Yes I know I can have arrays inside udt... but not variable amount...yet - which I need to bind variable names as pointers (see here) for flexible purpose as binding some arbitrary udt to some listview-control... next step is a treeview
    Last edited by ReneMiner; 18-05-2013 at 15:16.
    I think there are missing some Forum-sections as beta-testing and support

Similar Threads

  1. Quote Of the Day Guess the output (Union)
    By ErosOlmi in forum QOD: Question Of the Day
    Replies: 3
    Last Post: 09-02-2013, 10:08
  2. "Dynamic Arrays" in my UDT...
    By Oscar Ugolini in forum thinBasic General
    Replies: 4
    Last Post: 18-09-2012, 21:12
  3. Little little, step by step :)
    By ErosOlmi in forum Shout Box Area
    Replies: 11
    Last Post: 23-08-2010, 10:44
  4. Using MAT on an array within a Union
    By dcromley in forum Core module
    Replies: 5
    Last Post: 09-04-2009, 11:51
  5. I step back, no more project leader. (Former Should we go on?)
    By Michael Hartlef in forum CM contest 2009
    Replies: 15
    Last Post: 15-10-2008, 01:12

Members who have read this thread: 0

There are no members to list at the moment.

Posting Permissions

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