Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Referencing variables via pointers
#1
A little proof of concept method for a bigger program that I'm playing around with, which allows us to reference variables by offset rather than by name.

Code: (Select All)
Dim foo As Integer
Dim foo2 As _Unsigned _Byte
Dim foo3 As Long

Print foo, foo2, foo3

ToggleVar _Offset(foo), Len(foo)
ToggleVar _Offset(foo2), Len(foo2)
ToggleVar _Offset(foo3), Len(foo3)

Print foo, foo2, foo3

ToggleVar _Offset(foo), Len(foo)
ToggleVar _Offset(foo2), Len(foo2)
ToggleVar _Offset(foo3), Len(foo3)

Print foo, foo2, foo3

Sub ToggleVar (variable_offset As _Offset, variable_size As _Byte)
    Static m As _MEM
    m = _Mem(variable_offset, variable_size)
    Select Case variable_size
        Case 1
            temp%% = _MemGet(m, m.OFFSET, _Byte)
            _MemPut m, m.OFFSET, Not temp%% As _BYTE
        Case 2
            temp% = _MemGet(m, m.OFFSET, Integer)
            _MemPut m, m.OFFSET, Not temp% As INTEGER
        Case 4
            temp& = _MemGet(m, m.OFFSET, Long)
            _MemPut m, m.OFFSET, Not temp& As LONG
        Case 8
            temp&& = _MemGet(m, m.OFFSET, _Integer64)
            _MemPut m, m.OFFSET, Not temp&& As _INTEGER64
    End Select
End Sub

Take a moment and be certain to notice that these are 3 different type variables all being processed and altered via the same SUB. Smile
Reply
#2
What's the point of using pointers when QB64 points the variables to C/C++, whch does the pointer work for you?

Point... I mean Pete
Reply
#3
(10-21-2022, 03:58 PM)Pete Wrote: What's the point of using pointers when QB64 points the variables to C/C++, whch does the pointer work for you?

Point... I mean Pete

If you look at the first code, you'll see that I'm self-referencing my variables -- regardless of their type.  (As long as they're integers here, which is all that really makes sense to NOT between TRUE and FALSE states.)  For this simple demo, to showcase the proof-of-concept, it's not all that impressive.  I can hear you now, just muttering, "Why not just write a FUNCTION:"

Function Toggle&& (x as _INTEGER64)
    Toggle&& = NOT x
end Function

All well and good, but let's expand this concept to the next step.  Imagine creating a button on the screen which the user can use to toggle some options ON or OFF.  Easy enough, right?  I'm certain you've did it a dozen times in the past...

Now imagine that you need to toggle 10 different variables, and they're not the sort that fit nice in an array.  How do you work those up?  10 different SUBs, with one to manage each toggle??

How about one SUB that looks like the following:

Code: (Select All)
Sub ToggleVar (variable_offset As _Offset, variable_size As _Byte)
    $Checking:Off
    Static m As _MEM
    m = _Mem(variable_offset, variable_size)
    Select Case variable_size
        Case 1: _MemPut m, m.OFFSET, Not _MemGet(m, m.OFFSET, _Byte) As _BYTE
        Case 2: _MemPut m, m.OFFSET, Not _MemGet(m, m.OFFSET, Integer) As INTEGER
        Case 4: _MemPut m, m.OFFSET, Not _MemGet(m, m.OFFSET, Long) As LONG
        Case 8: _MemPut m, m.OFFSET, Not _MemGet(m, m.OFFSET, _Integer64) As _INTEGER64
    End Select
    $Checking:On
End Sub

Then you set up your Togglebox routine to look like:

Code: (Select All)
SUB ToggleBox (x, y, wide, high, var_offset as _Offset, var_size as _BYTE)
    If _mousebutton(1) and _mousex >= x and _mousex <= x + wide and _mousey >= y and _mousey <= y + high then
       'mouse button is down in the designated area
       Togglevar var_offset, var_size
    END IF
END SUB

So now you draw and caption your box as usual, but now you can have it reference an internal variable and NOT the value of that variable, without having to worry about types matching so you're passing via reference and not by value.

ToggleBox 100, 100, 200, 50, _Offset(foo), LEN(foo)   <-- that's all it'd take to turn box from 100,100 to 300,150, into a toggle for the variable foo.
ToggleBox 100, 100, 200, 50, _Offset(foo2), LEN(foo2)   <-- that's all it'd take to turn box from 100,100 to 300,150, into a toggle for the variable foo2.

You can use it to be certain to pass a variable by reference, regardless of type, rather than just passing by value.  Smile
Reply
#4
I usually just create a integer or long variable that I generally name "togs". I assign certain bits of it to various effects, then just toggle the bits on and off with 

SUB Toggle (var AS INTEGER)
    togs = _TOGGLEBIT(togs, var)
END SUB 'Toggle


Then I just test

IF togs AND bit#^2 THEN ... ELSE ... when I'm display processing.

I find it easy and fast enough for the stuff I do. I often just create constants for the bit numbers for more comment friendly code.

An intriguing idea that I'll have wrap my poor tender head around, but is there a _MEM type speed or optimization advantage to this?

Hell just reading the post learned me a new thing you can do with _OFFSET
DO: LOOP: DO: LOOP
sha_na_na_na_na_na_na_na_na_na:
Reply
#5
I understand the mechanics, I just can't wrap my head around anything I would ever use it for. I think my coding style is not aligned with this type of approach. Actually, the whole mem thing reminds me of a matrix function I built to run a graphics GUI. While coding a key input / wp routine in C/C++, I can't say if I ever got all the pointer requirements right, but the damn thing worked anyway. Go figure. I'm just greatfull BASIC doesn't require using pointers.

The concept of this approach is neat, but only time will tell if I ever find a project that would benefit from this approach.

Pete
Reply
#6
(10-22-2022, 01:25 AM)Pete Wrote: I understand the mechanics, I just can't wrap my head around anything I would ever use it for. I think my coding style is not aligned with this type of approach. Actually, the whole mem thing reminds me of a matrix function I built to run a graphics GUI. While coding a key input / wp routine in C/C++, I can't say if I ever got all the pointer requirements right, but the damn thing worked anyway. Go figure. I'm just greatfull BASIC doesn't require using pointers.

The concept of this approach is neat, but only time will tell if I ever find a project that would benefit from this approach.

Pete

Currently, my little project that'll try to incorporate this method, is just a simple menu-making program.  Here's my basic thinking for the menu setup:

first, register the menu and get a valid handle for it, so we can later check mouse/keyboard input against that stored in the handle's data structure.

Then add menu items, and it's at this point that we configure for their actions when triggered:

AddMenuItem "Allow FullScreen: ", "Toggle Event", _Offset(AllowFullScreen), Len(AllowFullScreen)
AddMenuItem "Set Font Size: ", "Set Event (6 - 64)", _Offset(FS), Len(FS)
AddMenuItem "Save Program", "Sub Event: SUB_SAVE", 0, 0

The first menu item says that when you click on it, you toggle the state of the variable called AllowFullScreen.  If TRUE, the program would be full screen, otherwise it's just a window.
The second menu item says when you click on it, it'll pop up an input dialog for you to set the current font level with a number from 6 to 64.
The third menu item says when you click on it, it'll jump to your SUB Save and save the program for you from there.

It's a case of:

AddMenuItem (Menu Caption), (Menu Action), (Variable Associated with Action), (Variable Length Associated with Action)



Normally, I'd process a menu at the point where we check to see what was interacted with.  Similar to
    IF Menu(1,1) = ClickedOn Then Toggle FullScreen
    If Menu(1, 2) = ClickedOn Then FontSize = GetValue (6, 64)
    If Menu(1, 3) = ClickedOn Then Save
    ... and so on...

Problem with that is you're defining the menu in one spot, processing input on it in another, executing what happens in another spot in your code...  It's a lot of jumping around in various places, and it's a PITA to make certain that it all plays together nicely when you go in 6 months from now and add another feature to that menu.  

Somehow, it just seems simpler to me to define the entry AND its corresponding action at the same time and place, than it does to scatter it about in the code like the vast majority of people have been doing over the years.

At the moment, it's just a thought exercise that I'm trying to sort out to see IF I can get it to work with the tools QB64 offers us.  I like the *concept* behind it; I just don't know if I can mangle the language and think outside the box enough to actually get it to work for all the things that I'm hoping I can twist it for....  YET!  Tongue
Reply
#7
@SmcNeill
Steve, are you abducted to the dark side of coding?
You are trying to make OOP in QB64! That is fantastic, but also very far from usual Basic.
Reply
#8
Blast that Google translator. You meant addicted, not abducted. Someone who is abducted is taken away against his or her will, or simply "taken away" like the abductor muscles in our thighs, which are used to move the legs apart.

Oh well, I can barely write in one language, and a lot of my friends say it isn't English.

Good luck with your text scroller in the other thread. If you need any help, just ask.

Pete

Might as well face it you're abducted to love.
Reply
#9
Thanks for giving me lesssical lessons, as you say Google translator isn't for helping in this case.

I'll try to do a professional demo of a vertical scrolling bar in ASCII.
Surely I must modularize my code and expand the code for getting this
Reply




Users browsing this thread: 2 Guest(s)