Announcement

Collapse
No announcement yet.

How to set the Pointer size at runtime

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • How to set the Pointer size at runtime

    Anyone know a way to set the pointer size at runtime?
    Code:
    #COMPILER PBWIN
    #COMPILE EXE
    #DIM ALL
    
    '********************************************************************************
    FUNCTION PBMAIN() AS LONG
    '********************************************************************************
      LOCAL lDebug AS LONG: TXT.WINDOW "Debug", 10,10,50,75 TO lDebug 'Thanks Dave!
    
      LOCAL X AS LONG
      X = 5
    
      LOCAL C AS STRING PTR * X '<-------- I want to set this at runtime
      'LOCAL C AS STRING PTR * 5
      LOCAL D AS STRING
    
      D = "....1....2....3....4....5"
      C = STRPTR(D)
      TXT.PRINT @C[0] & " " & @C[1] & " " & @C[2] & " " & @C[3] & " " & @C[4]
    
      TXT.PRINT "Press any key to exit (just like the old days!)": TXT.WAITKEY$: TXT.END
    END FUNCTION
    Swap in the commented line to see the output (PTR * 5).
    Maybe someone knows how to POKE in the size (similar to poking in the variant size of a Boolean).

  • #2
    You can't (natively) and poking around that way would NOT be advisable.

    PEEK$(address, count) can easily do what you need but, ignoring WHAT you wrote for a second (very vague example), what are you trying to do?


    I've implemented an example as a MACRO here
    Code:
    #COMPILER PBWIN
    #COMPILE EXE
    #DIM ALL
    
    '********************************************************************************
    MACRO GetSect(paramSection) = PEEK$(C+(paramSection*X),X)
    '********************************************************************************
    
    
    '********************************************************************************
    FUNCTION PBMAIN() AS LONG
    '********************************************************************************
      LOCAL lDebug AS LONG: TXT.WINDOW "Debug", 10,10,50,75 TO lDebug 'Thanks Dave!
    
      LOCAL X AS LONG
      X = 5
    
      LOCAL C AS DWORD
      LOCAL D AS STRING
    
      D = "....1....2....3....4....5"
      C = STRPTR(D)
      TXT.PRINT GetSect(0) & " " & GetSect(1) & " " & GetSect(2) & " " & GetSect(3) & " " & GetSect(4)
    
      TXT.PRINT "Press any key to exit (just like the old days!)": TXT.WAITKEY$: TXT.END
    END FUNCTION
    <b>George W. Bleck</b>
    <img src='http://www.blecktech.com/myemail.gif'>

    Comment


    • #3
      I'm playing around with a merge record sort routine. I have one routine to sort by PartNo, one to sort by Description, one to sort by QuantityOnHand, ... It works with a hard coded field, but if I want to sort by another field it requires another sort routine which is 99% the same. I'm trying to knock down many routines into one general routine.

      I could set up an equate to each field and then a CASE SELECT to pick the field but that feels messy.

      I need to pass the starting field location and field length to the routine.

      With the UDT I can just @pString[RecNo] = @pString[RecNo +1] but the compare is what is hanging me up

      Comment


      • #4
        I think the only way to do it is with the Offset to the field and the Length.

        MSort(sInventory, lRecLength, lOffset, lLength)

        In the calling routine I will have to compute the Offset to PartNo, Desc, QtyOnHand... and the Length of the field 20, 50, 12...

        Thanks George

        Comment


        • #5
          I think you want ARRAY SORT... CALL. It allows you to write a function that determines the sort order. Perfect for multi-field sorts of UDTs, you can even mix ascending/descending sorts, field by field. Or am I not understanding what you need to do?
          "Not my circus, not my monkeys."

          Comment


          • #6
            From post 1:
            LOCAL C AS STRING PTR * X '<-------- I want to set this at runtime​
            "X" is the maximum string length of a fixed length string. Just compile-time. If a shorter string is assigned it is padded with spaces. L = INSTR(@C, $SPC) - 1 will give length except when length = X.

            But better (IMO) would be dynamic strings. STRPTR() and LEN() are definitely run-time.

            Cheers,
            Dale

            Comment


            • #7
              Originally posted by Eric Pearson View Post
              I think you want ARRAY SORT... CALL. It allows you to write a function that determines the sort order. Perfect for multi-field sorts of UDTs, you can even mix ascending/descending sorts, field by field. Or am I not understanding what you need to do?
              Hi Eric,

              Yes, I tried DIM I(1 to MaxRec) as InvtRec AT STRPTR(sInventory) and used ARRAY SORT ... Call. It still required a case tree with equates for the different fields but it did work. In my testing my MergeSort was quicker than ARRAY SORT... but just barely. I'm sure that last sentence will start a tangent war on sort speed.

              Comment


              • #8
                Originally posted by Dale Yarker View Post
                From post 1: "X" is the maximum string length of a fixed length string. Just compile-time. If a shorter string is assigned it is padded with spaces. L = INSTR(@C, $SPC) - 1 will give length except when length = X.

                But better (IMO) would be dynamic strings. STRPTR() and LEN() are definitely run-time.

                Cheers,
                I see what you are getting at Dale. What I also needed was the size of the pointer to index through the buffer. @sInventory[RecNo].Desc By changing the RecNo it would advance which record I was looking at.

                Comment


                • #9
                  . . . size of the pointer
                  ????? 4 bytes.
                  Dale

                  Comment


                  • #10
                    Deleted

                    Comment


                    • #11
                      Originally posted by Dale Yarker View Post
                      ????? 4 bytes.
                      By size I mean the size of the UDT indexed by the pointer. Or what the Pointer is pointing to. The size of the record in my case. Yes, the pointer is 4bytes, but what it points to is the UDT size.

                      Code:
                      TYPE MyRecord
                        PartNo AS STRING * 20
                        Desc AS STRING * 50
                        Quantity AS LONG
                      END TYPE
                      
                      LOCAL pInventory as MyRecord Ptr
                      pInventory = STRPTR(Buffer)
                      @pInventory[RecNo].PartNo
                      By incrementing the RecNo above it advances one record at a time or 74 bytes in this example. I'm trying to change the 74 at run time. Probably not possible.

                      Comment


                      • #12
                        Deleted
                        "Not my circus, not my monkeys."

                        Comment


                        • #13
                          SIZEOF

                          But you did the TYPE/END TYPE so why don't you know? Unless some alignment is used.

                          See SIZEOF Help.

                          I'm trying to change the 74 at run time. Probably not possible.
                          Correct.

                          Forget UDTs, Load entire record to STRING, then PARSE COUNT and PARSE$. After the two strings get next four bytes and use CVL(). (for example, the TYPE in post 11)

                          Cheers,
                          Dale

                          Comment


                          • #14
                            Originally posted by Frank Rogers View Post
                            I'm playing around with a merge record sort routine. I have one routine to sort by PartNo, one to sort by Description, one to sort by QuantityOnHand, ... It works with a hard coded field, but if I want to sort by another field it requires another sort routine which is 99% the same. I'm trying to knock down many routines into one general routine.

                            I could set up an equate to each field and then a CASE SELECT to pick the field but that feels messy.

                            I need to pass the starting field location and field length to the routine.

                            With the UDT I can just @pString[RecNo] = @pString[RecNo +1] but the compare is what is hanging me up
                            ,l'm pretty sure that the time difference between your Merge Sort and an ArraySort on your UDTs would be negligible in practice
                            As for needing different routines, this is fairly simple and VERY easy to understand and maintain

                            '
                            Code:
                            #COMPILE EXE
                            #DIM ALL
                            
                            TYPE MyRecord
                              PartNo AS STRING * 20
                              Desc AS STRING * 50
                              Quantity AS LONG
                            END TYPE
                            GLOBAL gsInvSortOrder AS STRING
                            
                            %NoOfItems = 10000
                            
                            FUNCTION PBMAIN() AS LONG
                                LOCAL lDebug AS LONG: TXT.WINDOW EXE.FULL$, 200,50,40,100 TO lDebug
                                LOCAL i AS LONG
                                LOCAL t AS DOUBLE
                                DIM arrInv(1 TO %NoOfItems) AS MyRecord
                                FOR i = 1 TO UBOUND(arrInv)
                                    arrInv(i).PartNo = "Part No" & STR$(i)
                                    arrInv(i).Desc = MID$("abcdefghijklmnopqrstuvwxyz",(i MOD 26) +1,1) & "-Description of Part No " & STR$(i)
                                    arrInv(i).Quantity = RND(0 ,1000)
                                NEXT
                                TXT.PRINT "Array of " & STR$(%NoOfItems) & " inventory itmes created"
                                DO
                                    TXT.PRINT
                                    TXT.PRINT "Sort by [P]art Number,[D]escription,[Q]uantity (any other key to exit)
                                    TXT.WAITKEY$ TO gsInvSortOrder
                                    IF INSTR("PDQ",UCASE$(gsInvSortOrder)) = 0 THEN EXIT DO
                                    t = TIMER
                                    ARRAY SORT arrInv(),CALL SortArray
                                    t = TIMER - t
                                    TXT.PRINT
                                    TXT.PRINT "Sorted " & STR$(%NoOfItems)  & " items in " & FORMAT$(t,"0.000") & " seconds"  & " By " & UCASE$(gsInvSortOrder)
                                    SHowData(arrInv())
                                LOOP
                            
                            'Finalise
                                TXT.COLOR = %RGB_BLUE
                                TXT.PRINT
                                TXT.PRINT "  ....Press any key to exit": TXT.WAITKEY$: TXT.END
                            END FUNCTION
                            
                            FUNCTION SHowData(a() AS MyRecord) AS LONG
                                LOCAL i AS LONG
                                FOR i = 1 TO 3
                                    TXT.PRINT a(i).partno, a(i).desc,a(i).quantity
                                NEXT
                                TXT.PRINT
                                FOR i = UBOUND(a()) - 3  TO UBOUND(a())
                                    TXT.PRINT a(i).partno, a(i).desc,a(i).quantity
                                NEXT
                             END FUNCTION
                            
                            FUNCTION SortArray(p1 AS MyRecord,p2 AS myRecord) AS LONG
                                 SELECT CASE UCASE$(gsInvSortOrder)
                                     CASE "P"
                                         IF p1.PartNo < p2.PartNo THEN FUNCTION = -1 :EXIT FUNCTION 
                                         IF p1.PartNo > p2.PartNo THEN FUNCTION =  1
                                     CASE "D"
                                         IF p1.Desc < p2.Desc THEN FUNCTION = -1 :EXIT FUNCTION 
                                         IF p1.Desc > p2.Desc THEN FUNCTION =  1
                            
                                     CASE "Q"
                                         IF p1.Quantity < p2.Quantity THEN FUNCTION = -1 :EXIT FUNCTION 
                                         IF p1.Quantity > p2.Quantity THEN FUNCTION =  1
                                 END SELECT
                            
                            END FUNCTION
                            '

                            Comment


                            • #15
                              MIght this help you?

                              Code:
                              UNION  MultiPointer
                                   A  AS STRING PTR * 2
                                   B  AS STRING PTR * 3
                                   C  AS STRING PTR * 4
                                   ....
                              END UNION
                              It's a thought.

                              'ARRAY SORT FROM tartpos TO endpos' sounds like it might do the job for you. Just pass in the startpos and endpos to a procedure.

                              Or pass to a MACRO kind of like I demo'd here..

                              CC3+/Win7+: ARRAY SORT UDT array on member name September 04, 2002

                              That's another thought.
                              Michael Mattias
                              Tal Systems (retired)
                              Port Washington WI USA
                              [email protected]
                              http://www.talsystems.com

                              Comment


                              • #16
                                Good suggestion Michael. I played with FROM and TO in ARRAY SORT but it didn't quit flow as smoothly as I liked so I went off in search of making my own. My own wasn't as flexible, so I scraped it for ARRAY SORT Call... It's a tiny bit slower than a hand built sort but flexibility wins this fight.

                                Comment


                                • #17
                                  Code:
                                  UNION MultiPointer
                                  A AS STRING PTR * 2
                                  B AS STRING PTR * 3
                                  C AS STRING PTR * 4
                                  ....
                                  END UNION​
                                  ​ Its not a thought, its nonsense! You still must declare the string as fixed type with a length.

                                  Declare string as longest possible, and get VARPTR of the string. Then use PEEK$() and POKE$ instead of @. You still have to be careful about not accidentally over-writing other variables, and increment the pointer by declared length.

                                  Cheers,
                                  Dale

                                  Comment


                                  • #18
                                    ​ Its not a thought, its nonsense! You still must declare the string as fixed type with a length.​
                                    Depending on the application, it might be exactly what he needs. (How the data are actually stored is not shown)

                                    In a more general sense, I've said for a long time if you don't have some bad ideas, you don't have enough Ideas.

                                    But it really looks like...

                                    Code:
                                    FUNCTION |MACRO SortMyUDTArray (array(), Offset , length)
                                    .. is going to be the way to go.
                                    Michael Mattias
                                    Tal Systems (retired)
                                    Port Washington WI USA
                                    [email protected]
                                    http://www.talsystems.com

                                    Comment


                                    • #19
                                      Originally posted by Frank Rogers View Post
                                      ... It's a tiny bit slower than a hand built sort but flexibility wins this fight.

                                      Comment

                                      Working...
                                      X