Array items not "popping" ?? Topic is solved

Get help with using AutoHotkey (v2 or newer) and its commands and hotkeys
User avatar
kunkel321
Posts: 1136
Joined: 30 Nov 2015, 21:19

Array items not "popping" ??

Post by kunkel321 » 11 May 2024, 08:56

I'm working on this "proof of concept" code. The different conditions: left/right/undo all share the same function. I did that so that they would all have access to the same static variables (assigned at the top of the function).

With the msgbox at the bottom of the function, you can see that the static vars are incrementing with left/right presses, and they are getting pushed into the arrays, but it appears that the "undo" part of the arrays is not setting the static variables to previous states.

Any ideas why not? (I can explain more if needed.)

(Note: I realize that the text control doesn't get updated in the 'undo' block... I just haven't gotten that far yet.)

Code: Select all

#SingleInstance
#Requires AutoHotkey v2+
;  text experiment

guiTitle := 'Trimulator (trim simulator)'
str := 'left and right arrows will visually simulate trims'
str := ' ' str ' '
delL := ']' ; delimiter left
delR := '[' ; delimiter right
undoArrL := []
undoArrR := []

mg := Gui(, guiTitle)
mg.SetFont('s16','Consolas')
delta := mg.Add('text', '-wrap cBlue', str)
mg.Show()
mg.OnEvent('Close', (*)=>ExitApp())

#hotif WinActive(guiTitle)
Right::delta.Text := Changer(delta.Text, 'Left')   
Left::delta.Text := Changer(delta.Text, 'Right')  
^z::delta.Text := Changer(delta.Text, 'Undo')  
Esc::ExitApp()
!r::Reload()
#hotif

Changer(txt, direction)
{   static delPosL := 0 ; delimiter position left
    static delPosR := 0 ; delimiter position right
    undoArrL.push(delPosL) ; undo array left
    undoArrR.push(delPosR) ; undo array right

    If direction = "Left" 
    {
        delPosL++
        static tempL := StrReplace(LTrim(txt), delR, '')
        txt := subStr(tempL, 1, delPosL) delL subStr(tempL, delPosL+1)
    }
    Else If direction = "Right"
    {
        delPosR++
        static tempR := StrReplace(RTrim(txt), delL, '')
        txt := subStr(tempR, 1, StrLen(tempR)-delPosR) delR subStr(tempR, (StrLen(tempR)-delPosR)+1)
    }
    Else If direction = "Undo"
    {
        If undoArrL.Length > 1 ; both will be same length, so use either.
        {   
            undoArrL.pop ; removes and returns last array item.
            delPosL := undoArrL[undoArrL.Length]
            undoArrR.pop ; removes and returns last array item.
            delPosR := undoArrR[undoArrR.Length]
        }
    }
    msgbox 'L ' delPosL '`nR ' delPosR '`n`nL len ' undoArrL.Length '`nR len ' undoArrR.Length 
    Return txt
}
ste(phen|ve) kunkel

just me
Posts: 9529
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Array items not "popping" ??  Topic is solved

Post by just me » 11 May 2024, 10:25

Code: Select all

        If undoArrL.Length > 1 ; both will be same length, so use either.
        {   
            undoArrL.pop ; removes and returns last array item.
            delPosL := undoArrL[undoArrL.Length]
            ...
            ...
        }
After this step the contents of delPosL is still included in the array at position undoArrL.Length. The next call of the function with direction 'Left' or 'Right' will push this value a second time.

=> If you set delPosL to a value of undoArrL you must remove this value from the array.

User avatar
kunkel321
Posts: 1136
Joined: 30 Nov 2015, 21:19

Re: Array items not "popping" ??

Post by kunkel321 » 11 May 2024, 16:37

What you are describing certainly matches what I'm seeing... But I'm having a hard time understanding why this happens (and therefore how to fix it).

Here is a simpler version of the effect. Interestingly, with this version, at least the arr.len appears to decrement as expected, but the value of del doesn't.

What I image "should" happen is, for example, I press left 5 times... This causes there to be 5 items in the array (item 1="1", item 2="2", and so on). If I then press ^z, item 5 should get removed (popped) from the array. then, when I set del := arr[arr.length], arr.length will be 4, and so the value in that position gets assigned to del. If I press ^z 4 times, then del should get assigned the value of "1" which is the first array item.

EDIT: Sorry... I was declaring static del at a different location... Here it is, more like the original (longer) code.
EDIT AGAIN: Shoot, sorry again, I had x := instead of del :=. This version works as expected!

Code: Select all

#SingleInstance
#Requires AutoHotkey v2+
; simple array change 

arr := []

left::Funct('left')
^z::Funct("undo")
Funct(x)
{	
	static del := 0 
	if x = "left"
	{ 	
		arr.Push(del)
		del++
	}
	else if x = "undo"
	{
		;MsgBox 'box1, del is ' del '`narr len is ' arr.Length
		arr.Pop
		del := arr[arr.length]
		
	}
	MsgBox 'box2, del is ' del '`narr len is ' arr.Length '`nmax arr item ' arr[arr.length]
}
EDIT 3: Ha!!! I see the error now. The push commands need to go inside the if blocks... Not before them.
ste(phen|ve) kunkel

User avatar
kunkel321
Posts: 1136
Joined: 30 Nov 2015, 21:19

Re: Array items not "popping" ??

Post by kunkel321 » 11 May 2024, 17:00

Okey dokey. Here is the proof of concept working as desired.
Thanks Just me, RussF, and Teadrinker, for the help.

Code: Select all

#SingleInstance
#Requires AutoHotkey v2+
;  text experiment

guiTitle := 'Trimulator (trim simulator)'
str := 'left and right arrows will visually simulate trims'
str := ' ' str ' '
delL := ']' ; delimiter left
delR := '[' ; delimiter right
undoArrL := []
undoArrR := []
undoTxt := []

mg := Gui(, guiTitle)
mg.SetFont('s16','Consolas')
delta := mg.Add('text', '-wrap cBlue', str)
mg.Show()
mg.OnEvent('Close', (*)=>ExitApp())

#hotif WinActive(guiTitle)
Right::delta.Text := Changer(delta.Text, 'Left')   
Left::delta.Text := Changer(delta.Text, 'Right')  
^z::delta.Text := Changer(delta.Text, 'Undo')  
Esc::ExitApp()
!r::Reload()
#hotif

Changer(txt, direction)
{   static delPosL := 0 ; delimiter position left
    static delPosR := 0 ; delimiter position right

    If direction = "Left" 
    {
        undoArrL.push(delPosL) ; undo array left
        undoArrR.push(delPosR) ; undo array right
        undoTxt.push(txt)
        delPosL++
        static tempL := StrReplace(LTrim(txt), delR, '')
        txt := subStr(tempL, 1, delPosL) delL subStr(tempL, delPosL+1)
    }
    Else If direction = "Right"
    {
        undoArrL.push(delPosL) ; undo array left
        undoArrR.push(delPosR) ; undo array right
        undoTxt.push(txt)
        delPosR++
        static tempR := StrReplace(RTrim(txt), delL, '')
        txt := subStr(tempR, 1, StrLen(tempR)-delPosR) delR subStr(tempR, (StrLen(tempR)-delPosR)+1)
    }
    Else If direction = "Undo"
    {  
        If undoArrL.Length > 1 ; both will be same length, so use either.
        {   
            undoArrL.pop ; removes and returns last array item.
            delPosL := undoArrL[undoArrL.Length]
            undoArrR.pop ; removes and returns last array item.
            delPosR := undoArrR[undoArrR.Length]
            undoTxt.Pop
            txt := undotxt[undotxt.Length]
        }
    }
    ; msgbox 'L ' delPosL '`nR ' delPosR '`n`nL len ' undoArrL.Length '`nR len ' undoArrR.Length 
    Return txt
}
ste(phen|ve) kunkel

Post Reply

Return to “Ask for Help (v2)”