Page 5 of 5 FirstFirst ... 345
Results 41 to 46 of 46

Thread: TypeOf- ideas

  1. #41
    thinBasic MVPs
    Join Date
    Oct 2012
    Location
    Germany
    Age
    54
    Posts
    1,533
    Rep Power
    171

    Getting multi-dimensional

    I could have opened another thread for the following but it's an extension of the previous and all grows on the results of this thread, especially on the new Like-keyword.


    Who has read it knows that I already made Items which allow to append elements or 1-dimensional arrays of elements to any quad-variable, so for example an array of some maintype can have attached different sized 1-dimensional subarrays or single elements of different subtypes without having to change anything about the maintype.
    Long Read  ' keep that forum-variable in mind! 
    
    Repeat
    

    Now I created MD_Items = multidimensional items.

    MD_Items need a size of 28 bytes in the first place but they have a few heaps attached to store the bounds (12 Bytes per dimension) and SizeOf(datatype)*ElementsTotal anyway.
    They allow to append data of any type stored in up to a quarter million dimensions which is very naturalistic, true-to-life and often needed. No, just kidding- it leaves you the freedom to have any reasonable amount of dimensions without a limitation to care about...

    A minimum of 2 dimensions is required, for 1-dimensional just stick to simple Items or set the low+high-bounds both to 1 for one of the two dimensions.
    Each dimensions bounds can be in a range from -2,147,483,648 to 2,147,483,647 so means they allow to dim for example elements alike
    #pseudo-syntax !!!
    
    Dim foo(-123 to 25, 44 to 76, -99 to -13, 15) 
    
    ' first dimension in a range from -123 to 25, 
    ' second dimension in a range from 44 to 76
    ' third dimension in a range from -99 to -13
    ' fourth dimension in a range from 1 to 15
    
    the code above is not the real syntax but just to demonstrate how one would have to understand it.

    For dynamically passing indexes I simply Aliased the MKL$-functionality As MKIndex, so this allows to pass any amount of dimensions and their indexes in one parameter.

    To create some multidimensional array of any type it needs to specify the type which will be enumerated by EnumType-Function, so one passes the result of EnumType together with the boundaries. There are two ways to specify bounds:

    Either pass Ubounds of all dimensions only, so all dimensions indexes are 1-based as usual. That would mean to pass just one time MKIndex(...) after the EnumType().

    Optional you may pass low-bounds and high-bounds so all dimensions indexes start at the passed low-bound and end at the passed high-bound.
    The number of passed indexes has to match the number of dimensions always in this case, so even if lowbound of only one dimension starts with 1 you need to pass it then.

    Now for the example above - this would be the syntax to use:
    Dim foo as MD_Item
    foo.Create( EnumType ("typename_here"), MKIndex( -123, 44, -99, 1), MKIndex( 25, 76, -13, 15) )
    
    The first MKIndex() usually are the lowbounds and the second MKIndex() describes the upper bounds, but the create-function will take care of if you pass a higher number as first, so you can do it as you want, even mixed- as long as both have the same amount of dimensions.

    To access some element of the multidimensional array you can retrieve a pointer to it using
    dataPtr = <MD_Item-variable>.GetPtr( MKIndex(indexOfDimension1, indexOfDimension2 [,...]) )
    
    or you can place some overlay like this
    Local myElement Like foo.GetType At foo.GetPtr( MKIndex(1,2[,3[,...]]) )  
    'now can treat myElement as defined in Type
    

    Usage-example:

     
    #INCLUDE "Item.tBasicU"   
     
    Uses "console"
     
    Global Function_CalledFrom As DWord ' this global will tell a type-function where to find data
     
    ' have some example-type t_Test: 
      
    Type t_test
      I1 As Long  ' we simply store dimensions indexes here
      I2 As Long  ' to recheck if all done correctly
      I3 As Long
    
      Identify  As Function 
      SetTo     As Function
    End Type
     
    Function t_Test.Identify()
     
      If Function_CalledFrom Then
    ' not called from a variable of this type but from a pointer
    ' so Me is not dimensioned yet...
        Local Me As t_Test At Function_CalledFrom
        Function_CalledFrom = 0
      EndIf
       
      PrintL "My Index: (" & Me.I1 & ", " & Me.I2 & ", " & Me.I3 & ")"
     
    End Function
     
    Function t_Test.SetTo(ByVal I1 As Long, ByVal I2 As Long, ByVal I3 As Long) 
     
      If Function_CalledFrom Then
        Local Me As t_Test At Function_CalledFrom
        Function_CalledFrom = 0
      EndIf
     
      Me.I1 = I1
      Me.I2 = I2
      Me.I3 = I3
         
    End Function
    ' ------------------------------------------------------  
    ' now create some multi-dimensional Item 
     
    Dim foo As MD_Item 
    foo.Create( EnumType("t_Test"),  _  ' of type t_test
                MKIndex(-1,-2, -3),  _  ' lowbounds  (3 dimensions)
                MKIndex( 1, 2, 3 )   _  ' highbounds (3 dimensions)
                )                            
                
       'should have "foo(-1 to 1, -2 to 2, -3 to 3)"  now        
       '                    3    *   5   *    7
       '                  ======================
       '                  105 elements of t_Test
    
    Dim e, i, j, k As Long
    
      For i = 1 To foo.nDims   ' .nDims tells us the number of dimensions
        PrintL "Dimension " & i & ": " & foo.GetLowBound(i) & " To " & foo.GetHiBound(i)
      Next
      PrintL
      PrintL "Have a total of " & foo.ElementsTotal & " elements  of " & foo.GetType
      
      PrintL $CRLF + Repeat$(42, "-")
      PrintL $CRLF + "Press any key to continue" + $CRLF
      WaitKey
    
      For i = foo.GetLowBound(1) To foo.GetHiBound(1)
        For j = foo.GetLowBound(2) To foo.GetHiBound(2)
          For k = foo.GetLowBound(3) To foo.GetHiBound(3) 
            e += 1
            PrintL "Element " & e & $TAB & i, j, k
    
           ' request pointer to element(i,j,k) and store to global:
            Function_CalledFrom = Foo.GetPtr( MKIndex(i, j, k) )
           ' call type-function, stored global will be used in that function to place Me: 
            Call "t_Test.SetTo"(i, j, k)
          Next
        Next
      Next
      
      PrintL $CRLF & "do some checks now:" & $CRLF
    
      ' check element 0,0,0
      PrintL "should print: My Index: (0, 0, 0)"
      Function_CalledFrom = Foo.GetPtr( MKIndex(0, 0, 0) )  
      Call "t_Test.Identify"
      
      ' check element 1,1,1
      PrintL "should print: My Index: (1, 1, 1)"
      Function_CalledFrom = Foo.GetPtr( MKIndex(1, 1, 1) )  
      Call "" & foo.GetType & ".Identify"
    
      ' check element -1,-1,-1
      PrintL "should print: My Index: (-1, -1, -1)"
      Function_CalledFrom = Foo.GetPtr( MKIndex(-1, -1, -1) )  
      Call "t_Test.Identify"
    
      ' check element "not specified"
      PrintL "this is the very first element:"
      Function_CalledFrom = Foo.GetPtr()  
      Call "t_Test.Identify"
    
    PrintL $CRLF + Repeat$(42, "-")
    PrintL $CRLF + "Press the famous ANY-key to end"
     
    WaitKey
    

    There's no Redim-functionality for MD_Items but for non-preserve simply destroy and create new.
    Also Redim Preserve can be achieved:
    As first create temporary a new MD_Item in the desired new dimensions, then for-next-loop through all dimensions in boundaries that are common to both data-fields and place the data to preserve to the temp-element using
    Memory_Set( <tempMD_Item>.GetPtr( MKIndex(i,ii[,...]) ), _
                Memory_Get( <myMD_Item>.GetPtr( MKIndex(i,ii[,...]) ), SizeOf(typename_here) ) _
              )
    
    finally:
    Memory_Swap( Varptr(<myMD_Item>), Varptr(<tempMD_Item>), SizeOf(MD_Item) )
    ' can destroy the temporary MD_Item which contains the "old information & data" now
     <tempMD_Item>.Destroy()
    
    and Redim Preserve is done...


      incr Read
    Until Read >= %Understand
    
    The attached unit contains both, Items and MD_Items
    #MinVersion 1.9.12.0
    Attached Files Attached Files
    Last edited by ReneMiner; 24-04-2014 at 14:27.
    I think there are missing some Forum-sections as beta-testing and support

  2. #42
    thinBasic MVPs
    Join Date
    Oct 2012
    Location
    Germany
    Age
    54
    Posts
    1,533
    Rep Power
    171
    coming to something totally different than the above, but since Like-Keyword was invented here somehow I have some additional idea to use it somewhere else, could be very useful, probably also using As

    Uses "console"
    
    String A = "Long"
    Long   B = 123
    
    PrintL str$( Peek( Like A, Varptr(B) ) )
    ' PrintL str$( Peek( As B, VarPtr(B) ) ) 
    
    WaitKey
    
    should print out 123
    I think there are missing some Forum-sections as beta-testing and support

  3. #43
    Super Moderator Petr Schreiber's Avatar
    Join Date
    Aug 2005
    Location
    Brno - Czech Republic
    Posts
    7,129
    Rep Power
    732
    Hi Rene,

    this function could do that for you :
    Uses "console"
     
    String A = "Long"
    Long   B = 123
     
    Long x = LikePeek( A, VarPtr(B) ) 
    PrintL x
            
    WaitKey             
    
    Function LikePeek(vType As String, pVariable As DWord) As String
    
      Dim x Like vType
         
      String rawResult = Peek$( pVariable, SizeOf(x) )
      
      Select Case MCase$(vType)
        Case "Byte"
          rawResult = CVBYT(rawResult)
    
        Case "Currency"
          rawResult = CVCUR(rawResult)
    
        Case "Double"               
          rawResult = CVD(rawResult)
    
        Case "Dword"               
          rawResult = CVDWD(rawResult)
    
        Case "Ext", "Extended"
          rawResult = CVE(rawResult)
    
        Case "Integer"                  
          rawResult = CVI(rawResult)
    
        Case "Long"                  
          rawResult = CVL(rawResult)
    
        Case "Quad"                  
          rawResult = CVQ(rawResult)
    
        Case "Single"
          rawResult = CVS(rawResult)
          
        Case "Word"
          rawResult = CVWRD(rawResult)
          
      End Select
      
      Return rawResult
    
    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

  4. #44
    thinBasic MVPs
    Join Date
    Oct 2012
    Location
    Germany
    Age
    54
    Posts
    1,533
    Rep Power
    171
    so to say as this:

    #MINVERSION 1.9.12.0
     
    Uses "console"
    
    String A = "Long"
    Long B = 123
    
    Function PeekLike(ByVal sType As String, ByVal pData As DWord) As String
    
    Local x Like sType At pData
    
    Function = x
    
    End Function
    
    PrintL PeekLike A, VarPtr(B)
    
    
    
    PrintL $CRLF & "Any key to end"
    WaitKey
    
    that returning string for dynamic types is nice hack
    now can peek udts and standard-types...
    Last edited by ReneMiner; 29-07-2014 at 21:26.
    I think there are missing some Forum-sections as beta-testing and support

  5. #45
    Super Moderator Petr Schreiber's Avatar
    Join Date
    Aug 2005
    Location
    Brno - Czech Republic
    Posts
    7,129
    Rep Power
    732
    Haha,

    that is even simpler. Cool code


    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

  6. #46
    thinBasic MVPs
    Join Date
    Oct 2012
    Location
    Germany
    Age
    54
    Posts
    1,533
    Rep Power
    171
    just for fun i did the reverse operation, that is to "poke" a numerical string as different types to some place, really great, now i know how to bind user-data to a listview-alike control...


    #MINVERSION 1.9.12.0
     
    Uses "console"
    
    DWord someHeap = HEAP_Alloc(64)
    
    
    Function PeekLike(ByVal sType As String, ByVal pData As DWord) As String
    
      Local x Like sType At pData
    
      Function = x
    
    End Function 
    
    Function PokeLike(ByVal sType As String, ByVal pData As DWord, ByVal sVal As String ) As String
    
      Local x Like sType At pData
      
      If UCase$(sType) = "STRING" Then
        x = sVal
      Else  
        x = Val( sVal )
      EndIf
      
      Function = x
         
    End Function
    
    
    PokeLike "Ext", someHeap, "123.456" 
    
    PrintL PeekLike "Ext", someHeap
     
    
    PrintL $CRLF & "any key to end"
    WaitKey
    
    Last edited by ReneMiner; 30-07-2014 at 17:47.
    I think there are missing some Forum-sections as beta-testing and support

Page 5 of 5 FirstFirst ... 345

Similar Threads

  1. OOP ideas
    By ErosOlmi in forum Suggestions/Ideas discussions
    Replies: 13
    Last Post: 26-08-2013, 20:26
  2. More Ideas
    By peter in forum Sources, Templates, Code Snippets, Tips and Tricks, Do you know ...
    Replies: 3
    Last Post: 27-10-2012, 14:47

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
  •