Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

Problems Putting Code into Functions.


  • Please log in to reply
5 replies to this topic
Citricot
  • Members
  • 8 posts
  • Last active: Jun 26 2014 03:36 PM
  • Joined: 28 Feb 2014

Right, so I have a large chunk of code that I need to call repeatedly, but for some reason whenever I put it into a function and then call the function later, something goes wrong. I have tried declaring all variables as global, but it seems that that isn't the issue. It's happened to me multiple times and I'd usually just end up pasting the contents of the function wherever it was called instead of dealing with this mess, but this time I have a sizeable chunk that I will likely need to edit a few times.

 

I've pasted the code below, if that'd help. It seems to completely skip over the  "If ( ImgSearch ...." sections, though all of the variables I have used are declared globally much earlier. 

 

I'd rather not paste this where the current "CoreProcess()" function calls are, as there are around 6 of them, but I'm not sure what other options I have. Any ideas? 


CoreProcess()
{
WinActivate, iv char-1.vi

If ( ImgSearch = 1 ) 
{
WinActivate, iv char-1.vi
MemCheck := 0
z = 0
MemSearch:
While ((MemCheck != 1))
        {
            WinActivate, iv char-1.vi
            ToolTip, Searching for memory. (%z% runs), 0, 0
            Sleep 500
            z:=z+1
            WinActivate, iv char-1.vi
            ImageSearch, PosXMem, PosYMem, 1, 1, A_ScreenWidth, A_ScreenHeight,*125 Files

\memory.bmp
            ;ImageSearch, xx, yy, 1, 1, 1919, 1079,*12 selec.png
            if ErrorLevel = 2
                {
                }
            else if ErrorLevel = 1
                {
                    MemCheck := 0
                }
            else
                {
                    Tooltip
                    MemCheck := 1
                    PosXMem := PosXMem + 60
                    PosYMem := PosYMem + 50
                }
        }
           
}      


PosX = 63
PosY = 57
WinActivate, iv char-1.vi
Click %PosXMem%, %PosYMem%
Send {Backspace}{Backspace}%Mem%

If ( ImgSearch = 1 ) 
{
WinActivate, iv char-1.vi
RunCheck := 0
z = 0
RunSearch:
While ((RunCheck != 1))
        {
            ToolTip, Searching for Run. (%z% runs), 0, 0
            Sleep 500
            z:=z+1
            WinActivate, iv char-1.vi
            ImageSearch, PosX, PosY, 1, 1, A_ScreenWidth, A_ScreenHeight,*125 Files\run2.png
            ;ImageSearch, xx, yy, 1, 1, 1919, 1079,*12 selec.png
            if ErrorLevel = 2
                {
                }
            else if ErrorLevel = 1
                {
                    RunCheck := 0
                }
            else
                {
                    Tooltip
                    RunCheck := 1
                    PosX := PosX + 10
                    PosY := PosY + 10
                }
        }
           
}      
WinActivate, iv char-1.vi
Click %PosX%, %PosY%
WinActivate, iv char-1.vi
Exists = 0
While (Exists != 1)
{
WinActivate, Select a file to save.
    IfWinExist, Select a file to save.
    {
        Exists := 1
    }
}



CoordMode Mouse, relative

WinActivate, Select a file to save.
PosXName := 660
PosYName := 400
WinActivate, Select a file to save.
Click %PosXName% %PosYName%
Send {Backspace}^a{Backspace}      
Send S3 IV %Temp%K Pins %Pins%

PosXSave := 763
PosYSave := 403
WinActivate, Select a file to save.
Click %PosXSave% %PosYSave%

CoordMode, mouse, screen

}


guest3456
  • Members
  • 1704 posts
  • Last active: Nov 19 2015 11:58 AM
  • Joined: 10 Mar 2011

Heh. I will attempt to help you. Where to begin.. 
 
First, indent your code better. what you've got is very tough to follow.
 
Second, there is not enough code provided to know the true cause. From what I can tell, all you've provided is one standalone function. You have not defined any variables as global, nor have you defined the function as assume-global. So from what you've pasted, none of your variables which you expect to already contain values will work.
 
Now, the true question, why are you trying to use a function at all? You are passing no parameters, and you are returning no value. You might as well just turn the entire thing into a subroutine/label.
 

CoreProcess:
   WinActivate, iv char-1.vi

   If ( ImgSearch = 1 ) 
   {
      WinActivate, iv char-1.vi
      ;...

return

Labels will be in global scope, so all of your variables should be accessible. Then when you want to call this block of code multiple times, you can simply do GoSub, CoreProcess. This will likely solve your problem, although you'll want to revisit why you have other labels inside as well (mentioned below).

However, if you are intent on using functions, keep reading.
 
You can always check to see if the variables have values or not by doing a quick debug before they are used (with proper indenting shown):
 

CoreProcess()
{
   WinActivate, iv char-1.vi

   MsgBox, ImgSearch = %ImgSearch%   ;// get used to doing this A LOT. its a useful debugging tool

   If ( ImgSearch = 1 ) 
   {
      WinActivate, iv char-1.vi
      ;...

 
If the msgbox is showing no value for your ImgSearch variable, then clearly that block won't execute. If you've defined that variable previously in global scope outside of the function, then you could specifically declare that variable global, or declare the entire function as global.
 

CoreProcess()
{
   global                    ;// make all variables global

   WinActivate, iv char-1.vi
   ;...

 
 
You may want to reread this page if you haven't already:
http://www.autohotke...s/Functions.htm
 
 
Third, you've got subroutine labels inside of your function such as MemSearch: and RunSearch:. If you are also calling these labels from outside of your func, then you are likely to similarly run into issues. As a good practice, you shouldn't place labels inside of functions unless you are sure you know what you're doing. Maybe they should be their own funcs...

Fourth, this function is huge. Its not a great idea to just copy everything into one large function. Usually its better to start small. Refactor out a small piece of the code into a smaller function. Make sure that works. Then go larger. Its very hard to read your code since the formatting and indentation isn't good. From my understanding, this is what you are doing:
 

CoreProc()
{
   Search for memory image
   Do some clicks
   Search for run image
   Do some clicks
   Do some more clicks to save a file
}

Those are distinct tasks that you may want to consider having individual functions for.
For example:
 

CoreProcess()
{
   global
   WinActivate, iv char-1.vi

   If ( ImgSearch = 1 ) 
   {
      MemSearch()
   }
   ;...
}


MemSearch()
{
   WinActivate, iv char-1.vi
   MemCheck := 0
   z = 0
   MemSearch:
   While ((MemCheck != 1))
   {
      WinActivate, iv char-1.vi
      ToolTip, Searching for memory. (%z% runs), 0, 0
      Sleep 500
      z:=z+1
      WinActivate, iv char-1.vi
      ImageSearch, PosXMem, PosYMem, 1, 1, A_ScreenWidth, A_ScreenHeight,*125 Files\memory.bmp
      ;ImageSearch, xx, yy, 1, 1, 1919, 1079,*12 selec.png
      if ErrorLevel = 2
      {
      }
      else if ErrorLevel = 1
      {
         MemCheck := 0
      }
      else
      {
         Tooltip
         MemCheck := 1
         PosXMem := PosXMem + 60
         PosYMem := PosYMem + 50
      }
   }
}

Its still not great, but its better. Similarly you could follow the same idea with labels, and have multiple smaller labels 



Citricot
  • Members
  • 8 posts
  • Last active: Jun 26 2014 03:36 PM
  • Joined: 28 Feb 2014

Hey, thanks! That's a lot of info, thank you for taking the time to type it out.

 

I will likely use Gosub as you mentioned, I hadn't heard of that, though I think the problem might have been with forgetting to call "WinActivate, iv char-1.vi" as global.

 

As far as the actual function's mechanics, I have tested all of the code outside of function brackets and it works fine. Also, the internal labels are not called from outside the function.



guest3456
  • Members
  • 1704 posts
  • Last active: Nov 19 2015 11:58 AM
  • Joined: 10 Mar 2011

Yea just try making one big label instead of a function.

 

And you wouldn't be calling WinActivate as global. That doesn't make sense. WinActivate is a command, not a variable.



Citricot
  • Members
  • 8 posts
  • Last active: Jun 26 2014 03:36 PM
  • Joined: 28 Feb 2014

And you wouldn't be calling WinActivate as global. That doesn't make sense. WinActivate is a command, not a variable.

 

That's what I thought until I saw

 

CoreProcess()

{
global
WinActivate, iv char-1.vi

 
in your last example. 
 
Could you explain why you added "global"?


guest3456
  • Members
  • 1704 posts
  • Last active: Nov 19 2015 11:58 AM
  • Joined: 10 Mar 2011

I guess you didn't read the link I provided.

 

Using global by itself puts the entire function in assume-global mode.