Results 1 to 10 of 10

Thread: String-in-String-Pointers?

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

    String-in-String-Pointers?

    Today I need some idea or advice how to get the following done:

    I'm creating own UI for my current app. Now I want to create a listbox-alike control that shall be multiple usable and show different arrays of strings.
    So for example the box is supposed to show a list of files, stored to
    Dim sFile() as String
    
    and the next time/another listbox is to show a list of sCountries() or sNames() or whatever. The problem is, how can I store a pointer to the correct array, so the listbox-drawing-routine "knows" which array and how many items to fill in, since the arrays are all dynamic string-arrays and they might change their location in memory when redimensioned?

    Is there a cool way alike calling functions? - So I could store the arrays name (!) in another string like this:

    '...
    Gadget(%gListboxFile).ArrayToUse = "sFile()"
    Gadget(%gListboxName).ArrayToUse = "sName()"
     '...
    
    Sub DrawListbox(Byval Index as Long) 
     
     Static i as Long
    
    ' -- pseudo-code:
    
     Local sString() Alias Gadget(Index).ArrayToUse As String
    
    For i = 1 to Ubound(sString)
      PrintL sString(i)
    Next i
    
    End Sub
    
    Last edited by ReneMiner; 25-03-2013 at 15:55.
    I think there are missing some Forum-sections as beta-testing and support

  2. #2
    thinBasic author ErosOlmi's Avatar
    Join Date
    Sep 2004
    Location
    Milan - Italy
    Age
    57
    Posts
    8,777
    Rep Power
    10
    Wow Renč, you always find some interesting ways of doing things
    Alias of a variable name using a string is something I really like.
    Do not know how to implement but I like the idea!
    Maybe in near future ... who knows

    Back to what could be done right now, it comes to my mind 2 quick ways:

    Uses "Console"
     
    Dim sFile(2) As String = "123", "456"
    Dim sName(3) As String = "ABC", "DEF", "EFG"
    
    
    '--------------------------------------------------------------
    '---Method 1: just pass the string array 
    '--------------------------------------------------------------
    Sub DrawListbox_Method1(ByRef sString() As String)
      Static i As Long
      PrintL "Inside function: " & Function_Name
      For i = 1 To UBound(sString)
        PrintL i, sString(i)
      Next '<<<---Do not indicate for variable, thinBasic knows it
    End Sub
    
    
    DrawListbox_Method1(sFile)
    DrawListbox_Method1(sName)
    
    
    
    
    '--------------------------------------------------------------
    '---Method 2: pass a string representing the name and then SELECT CASE ... using the name
    '             thinBasic will Declare just one sString that will fall into the CASE
    '--------------------------------------------------------------
    Sub DrawListbox_Method2(ByVal sArrayName As String) 
      Static i As Long
      Dim InvalidName As Boolean
      
      PrintL "Inside function: " & Function_Name
      Select Case Ucase$(sArrayName)
        Case "SFILE"
          Dim sString(UBound(sFile)) As String At VarPtr(sFile(1))
        Case "SNAME"
          Dim sString(UBound(sName)) As String At VarPtr(sName(1))
        Case Else
          InvalidName = %TRUE
      End Select
     
      If Not InvalidName Then
        For i = 1 To UBound(sString)
          PrintL i, sString(i)
        Next  '<<<---Do not indicate for variable, thinBasic knows it
      Else
        PrintL "Variable " & sArrayName & " seems ... vanished :D"
      End If
    End Sub
    
    
    DrawListbox_Method2("sFile")
    DrawListbox_Method2("sName")
    DrawListbox_Method2("ThisWillNotExists")
    
    
    WaitKey
    
    BUT ATTENTION: there is a BUG in thinCore.dll also in versions previous 1.9.4
    It free memory also for variables created using DIM ... AT ... when variables are strings while it should not do it!
    I do not understand how I could have introduced such a stupid bug ????????
    So please get attached thinCore.dll and place into your \thinBasic\ directory before executing above examples
    Attached Files Attached Files
    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

  3. #3
    thinBasic author ErosOlmi's Avatar
    Join Date
    Sep 2004
    Location
    Milan - Italy
    Age
    57
    Posts
    8,777
    Rep Power
    10
    No, bug has always be there.
    And this explains also some strange behaves I was facing in the past.

    I'm making changes and some tests than I will publish a new beta version (maybe this evening CET)

    @Renč: I will publish (this evening) more info with some pictures about dynamic strings and StrPtr/VarPtr meaning hoping this will give more ideas and clarify dynamic strings memory handling.


    Sent from my iPhone using Tapatalk
    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

  4. #4
    thinBasic MVPs
    Join Date
    Oct 2012
    Location
    Germany
    Age
    54
    Posts
    1,527
    Rep Power
    170
    OK, thanks Eros, I'm alway happy to have and use the latest available Version, so I got the feeling my computer understands an up-to-date language.

    Your second example comes closest to my needs but the point is, I wanted to get around using "Select Case" and "If" as much as possible and prefer to give quick straight orders rather than cumbersome comparing before. It'll do the job for my current project- but not as flexible that I could use the handling for Gadget "listbox" from another script without any changes.

    [goodMorningThoughts]
    That's why I think, it would be great improvement if thinBasic could "recognize" a variable from it's name - and not just through a pointer - as it can do already with subs & functions. It would make computers that run thinBasic real smart-asses compared to others and might start a(n/r)evolution in basic programming since it's real understandable, easy Basic. And I'm unable to predict how many ways people find to use it, if they got the possibillities.

    A 2-year old child recognizes stuff from names after pointing to it a few times - and not just from looks - it's a precondition to thinking.
    - Pointers we have...

    A 4-year old will understand that there are often more than just one word for the same thing.
    - Virtual Variables we have also...

    A 6-year old can read his and others names and "imagine" a face to the name...
    - hmm,...

    Grown-ups don't care what others do nor think, they make up their own mind...
    - yep,
    [/goodMorningThoughts]

    Some small questions I wonder about: to ReDim uses up lots of time. How is that with virtual variables?
    It should be pretty much faster since it doesn't really allocate additional space - but I'm not sure about it...
    and additional to that:

    Is possible to ReDim the size of the real variable through the virtual one?

    (senseless example since the array-name is present in Sub):
    Dim A() as Long
    Redim A(100)
    ....
    Sub SomeSub()
    
    Local dummy() As Long At 0
    Redim dummy(Ubound(A)) At Varptr(A(1))
    ...
    
    Redim dummy(200) ' At VarPtr(A(1)) ???
    
    ' can Ubound(A) return 200 now?
    
    End Sub
    
    Last edited by ReneMiner; 26-03-2013 at 12:16.
    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
    Quick reply while I have 5 minutes pause at work.


    Quote Originally Posted by ReneMiner View Post
    to ReDim uses up lots of time. How is that with virtual variables?
    It should be pretty much faster since it doesn't really allocate additional space - but I'm not sure about it...
    Yes: virtual variables are much faster because memory is not allocated/de-allocated/re-allocated.
    They just use the memory virtual variables points to.


    Quote Originally Posted by ReneMiner View Post
    Is possible to ReDim the size of the real variable through the virtual one?

    (senseless example since the array-name is present in Sub):
    Dim A() as Long
    Redim A(100)
    ....
    Sub SomeSub()
    
    Local dummy() As Long At 0
    Redim dummy(Ubound(A)) At Varptr(A(1))
    ...
    
    Redim dummy(200) ' At VarPtr(A(1)) ???
    
    ' can Ubound(A) return 200 now?
    
    End Sub
    
    No.
    Virtual variable can just use the memory and not allocate/de-allocate/redim memory allocated by other part of your application.
    They would not be "virtual" but real variables.
    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
    Just because fits this topic, I got some new weired stuff in mind - related to that String "somewhat special inside"-thing.

    Because currently I think about FAST loading meshes into TBGL in any way - don't care how - I came to the conclusion the fastest would be to pump the data from HD directly to a displaylist.
    small example here some code snippet to visualize what data to await:
      TBGL_NewList %ListID
        TBGL_BeginPoly %GL_TRIANGLES
         TBGL_Normal 1.23, 2.34, 3.45
         TBGL_Color 12, 34, 45
         TBGL_TexCoord2d 0.1, 1.2   
         TBGL_Vertex 1.23, 2.34, 3.45
        TBGL_EndPoly
      TBGL_EndList
    
    I already made a routine to save my data this way (plain *.txt-file) so user can import his 3d-stuff directly to his script by copy & paste from texteditor.

    However - if I save the data to binary - which might be the fastest way to load & save - I would have to run through my binary data and convert somehow to parameters for all those TBGL-Methods which would use somewhat of calculation-time and a few steps from binary saved data to create valid codelines in the right order.

    Now my thoughts going to

    local myFile as Dword = File_Open(fName, "INPUT")
    local sRead as String 
    '...
    While Not File_EOF(myFile)
    
      sRead = File_LineInput(myFile)
      ' now sRead holds one line as in code above...
      
      ' Call_IfExists sRead ??? - naa - almost...
    
      ' because i had to make Val() from the parameters,
      ' that would mean to parse the line sRead in advance
    
      ' no - I think about some
       
       Execute$(sRead) 
    
    Wend
    
    so basically - treat the string-content as it would be a thinBasic-code-line in the script.
    I know it will not work with Select Case nor multiline-if, so just one statement per line is limit i think,
    -variables inside or constants ? - complicated but maybe...

    That way I could save data to plain scriptlines in the order they shall be executed without any need to order them again. Of course I won't read line-by-line as in the example, but so example becomes clearer. I could give the statements directly from file to tB to be executed.
    The lines would not stay in memory forever as they would in an include-unit-file and I think there are more uses possible, imagine to save all visual-designer-stuff somehow like this, or other run-once-at-startup-stuff...all lines from top to bottom get executed once - and then they're done & gone from memory...

    As usual the programmer is responsible which strings shall be executed here.
    maybe can be more versions of this:
    to CORE/String-Functions:
    Execute$(sString) as in this example
    to CORE/String
    ExecuteArray$(sStringArray[,startIndex[,endIndex]])
    to CORE/String
    ExecuteParse$(sString) ' $crlf as delimiter expected i'd say...

    to FILE-Module which directly does
    LineInput + executes it in one call.
    File_ExecuteLine$(nFilenum) ' similar to File_LineInput + Execute$()
    File_ExecuteFile$(sFilename) ' similar to File_Load + ExecuteParse$()


    always have such weired ideas...
    Last edited by ReneMiner; 09-04-2013 at 13:09.
    I think there are missing some Forum-sections as beta-testing and support

  7. #7
    thinBasic author ErosOlmi's Avatar
    Join Date
    Sep 2004
    Location
    Milan - Italy
    Age
    57
    Posts
    8,777
    Rep Power
    10
    ... great idea

    Not just around the corner and I cannot still promise anything but I think there will be the possibility to load an external text file on request when needed and interpret it as "on the fly script source code" like it would be part of the script itself.

    In my mind I still have to find solutions for few technical problems but at first sight it seems doable.
    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

  8. #8
    thinBasic MVPs
    Join Date
    Oct 2012
    Location
    Germany
    Age
    54
    Posts
    1,527
    Rep Power
    170
    OK, I would suggest new file-extension for these too, so thinAir will open it for edit from the built-in explorer and not just through File\Open from menu to open a *.txt -file. maybe *.tBasicE or *.TBTxt
    - or make thinAir display & open *.txt from list below explorer-treeview...would be nice to use thinAir for quick writing/changing ReadMe.txt without changing to notepad also.
    Last edited by ReneMiner; 10-04-2013 at 18:21.
    I think there are missing some Forum-sections as beta-testing and support

  9. #9
    thinBasic MVPs
    Join Date
    Oct 2012
    Location
    Germany
    Age
    54
    Posts
    1,527
    Rep Power
    170
    I got some solution in the meantime to get String-In-String-Pointers done - so I am able to assign some UDT-variable to some object - in this example is a small listview just for demonstration-purpose. You'll need the latest thinCore.dll to run this. Run NewTest.tBasic but put SHEET.tBasicU into the same folder.

    Uses "TBGL"
    #INCLUDE "SHEET.tBasicU"
                                                               
    Type t_myType
      Identity   As String
      Phone      As String
      Reputation As Long
      Cash       As Double
    End Type   
    
    
    Dim myList() As t_myType 
    
    Dim mySheet  As Long
    
    Dim hWnd       As DWord      
    
    Dim lCharwidth, lCharHeight As Long
    
    Function TBMain() 
      
      
      ' -- Create and show window
      hWnd = TBGL_CreateWindowEx("TBGL script - press ESC to quit", 640, 480, 32, %TBGL_WS_WINDOWED)
      TBGL_ShowWindow
       
      TBGL_BuildFont TBGL_FontHandle("Lucida Console", 12), 1
      TBGL_SetActiveFont 1
      TBGL_GetFontTextSize("X", lCharWidth, lCharHeight)
      ' make the rows a little higher
      lCharHeight += 4 
      
      Fill_myList() ' just fill the demonstration-UDT-array with some data
      
      ' now "bind" the data-structure to some sheet which manages the grid to sort those
      ' items and draw them all below their headers, so tell every header which UDT-Element to use 
    
    '                                       name of variable, size of one element
      mySheet = SHEET_Create("myList", SizeOf(t_myType)) 
      
    '           sheetID, Header-Caption, Variable-Type, Flags, Offset from first Element,  number of chars = width of header
      
      SHEET_AddHeader(mySheet, "Name",      %VarType_String, 0, UDT_ElementOffset(myList(1).Identity), 10)
      SHEET_AddHeader(mySheet, "Phone",     %VarType_String, 0, UDT_ElementOffset(myList(1).Phone)   , 12)
      SHEET_AddHeader(mySheet, "Reputation", %VarType_Long,   0, UDT_ElementOffset(myList(1).Reputation))
      SHEET_AddHeader(mySheet, "Cash",       %VarType_Double, 0, UDT_ElementOffset(myList(1).Cash), 10)
      
       
      ' -- Resets status of all keys
      TBGL_ResetKeyState()
       
      TBGL_UseTexturing(FALSE)  ' will just draw text and boxes...
      TBGL_RenderMatrix2D(0, 480, 640, 0) ' and just 2D
      TBGL_DepthFunc(%TBGL_ALWAYS)
         
      TBGL_SetActiveFont 1
      TBGL_Color 255, 255, 127  
      
      
         
      ' -- Main loop
      While TBGL_IsWindow(hWnd)
         
        TBGL_ClearFrame
        ' call to draw some Listview-alike sheet now...
    
          Draw_Sheet(mySheet)   
        
        TBGL_DrawFrame
         
        ' -- ESCAPE key to exit application
        If TBGL_GetWindowKeyState(hWnd, %VK_ESCAPE) Then Exit While
     
      Wend
     
      TBGL_DestroyWindow
    End Function
     
    ' -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    Sub Draw_Sheet(ByVal Index As Long)
    
      Static sHeader As String
      Static X, Y, Vartype, Flags, Offset, nChars, lLeft    As Long
      Static MainType, SubType, IsArray, DataPtr, nElements As Long
      Static pPtr As DWord
    
    ' as you see- this sub does not know anything about myList() but displays it's content...
      
      thinBasic_VariableGetInfoEX(Sheet(Index).VarName, MainType, SubType, IsArray, DataPtr, nElements)
      
      lLeft = 8 ' leave a little border
      
      For X = 1 To Sheet(Index).nHeaders
        
        If SHEET_GetHeaderInfo(Index, X, sHeader, VarType, Flags, Offset, nChars) Then
        
          TBGL_PrintFont sHeader, lLeft, lCharHeight 
          If nElements Then
            For Y = 1 To nElements
              pPtr = DataPtr + Offset + (Y-1) * Sheet(Index).Varsize
              
              Select Case VarType
            
                Case %VarType_Long
                 TBGL_PrintFont( TStr$(Peek(Long, pPtr)), lLeft, (1+Y) * lCharHeight)
            
                Case %VarType_Double
                  TBGL_PrintFont( Format$(Peek(Double, pPtr), "0.00" ), lLeft, (1+Y) * lCharHeight )
            
                Case %VarType_String
                  TBGL_PrintFont( Peek$(Peek(DWord, pPtr), StrPtrLen(Peek(DWord, pPtr)) ), lLeft, (1+Y) * lCharHeight)
                
                 ' for this script I just used those 3 VarTypes- more would be too confusing here
              End Select
            Next
          End If
        EndIf
        
    ' calculate left margin for next header:
        lLeft += nChars * lCharWidth + 8
        
      Next  
    
    End Sub
    
    ' ---------------------------------------------------------------------------------------- 
    Sub Fill_myList() 
    
      ReDim myList(5)
    
      With myList(1)
        .Identity   = "Petr"
        .Phone      = "unknown"
        .Reputation = 10000
        .Cash       = 12345.67
      End With
      
      With myList(2)
        .Identity   = "Eros"
        .Phone      = "busy"
        .Reputation = 10000
        .Cash       = 23456.78
      End With    
      
      With myList(3)
        .Identity   = "John"
        .Phone      = "911"
      End With
      
       With myList(4)
        .Identity   = "Michael"
        .Phone      = "iPhone 4"
        .Reputation = 5000
        .Cash       = -5.67
      End With         
     
      With myList(5)
        .Identity   = "Max"
        .Phone      = "000-000-0000"
        .Reputation = 10
        .Cash       = 1.00
      End With          
    'add more elements to myList or change the content... Draw_Sheet() will be up-to-date anytime 
     
     
      
    End Sub
    ' ---------------------------------------------------------------------------------------
    
    Maybe this is an idea to populate UI-Controls as MLGrid or Listview.

    PS. I could not find built-in Equates to specify var-types - I think there should be some...
    and- in SHEET_AddHeader could be some Sheet(Index).Width += nChars * something + some border - but I did not use it here, neither did I use flags as %align_left or %align_right here to not too complicate it.

    The 169-lines Sheet-Unit consists of declarations for the functions and three subs to handle the sheets.
    Attached Files Attached Files
    Last edited by ReneMiner; 17-05-2013 at 19:13.
    I think there are missing some Forum-sections as beta-testing and support

  10. #10
    thinBasic MVPs
    Join Date
    Oct 2012
    Location
    Germany
    Age
    54
    Posts
    1,527
    Rep Power
    170
    Variables ByString work already but still urge for some solution for the following.

    Some users might remember I was creating some UI-controls that have different properties. The solution was to use Union, but this wastes a lot of memory since all controls use as much as the largest control - the one with the most properties- does.

    Now I attempt to Extend single elements of my main-CTRL/Gadget-Array as in this simplyfied example, so imagine Subtype1 would be a button or timer and the other one would be a property-list or grid or whatever...
    Uses "Console"
    
    
    Alias DWord As SomeSubType
    
    Type t_mySubType1
      A As Long
      B As Byte
      C As DWord
    End Type
    
    Type t_mySubType2
      A As Long
      B As Byte
      C As DWord
      D As Double
    End Type     
    
    
    Type t_myMainType
      Style As String
      X     As Long
      Y     As Long
      pST   As SomeSubType
    End Type
    
    Dim foo(5) As t_myMainType
    
    foo(1).Style = "t_mySubtype1"
    foo(1).pST   = HEAP_Alloc(SizeOf(t_mySubtype1))
    
    
    foo(2).Style = "t_mySubtype2"
    foo(2).pST   = HEAP_Alloc(SizeOf(t_mySubtype2))
    
    fine till here- you see what I'm up to...
       ' now I'm stuck...
       ' I would need a method to get the UDT-Structure
       ' from the name stored in foo().Style
       ' would have to work as follows:
           
    foo(1).Style = "t_mySubtype1"
    foo(1).pST   = HEAP_Alloc(SizeOf( ByString(foo(1).Style) )  
    
       ' and also will not work
    Dim Subtype As ByString(foo(1).Style) At foo(1).pST
       ' because
    Dim Subtype As ByString(foo(2).Style) At foo(2).pST  
       ' will now throw Error: Variable already exists 
       ' also
    ReDim Subtype As ByString(foo(2).Style) At foo(2).pST  
       ' is not possible because SubType is not an array...
    Reset Subtype As ByString(foo(2).Style) At foo(2).pST  
       ' also not possible...
     
    WaitKey
    
    I need something that holds the information of the UDT-structure. In thinCore.inc I've not found such thing
    Also would be great if a virtual layover could be changed in Type somehow
    Last edited by ReneMiner; 11-06-2013 at 15:21.
    I think there are missing some Forum-sections as beta-testing and support

Similar Threads

  1. C: string functions
    By danbaron in forum Science
    Replies: 2
    Last Post: 11-07-2011, 19:38
  2. String library comparison
    By ErosOlmi in forum C / C++
    Replies: 1
    Last Post: 20-05-2008, 18:11

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
  •