Wait for image A or B or C forever, then take action accordingly

Asked by denywinarto

Hi, im trying to create an script for game launchers,
there are 3 possibilities when the launcher is clicked.
So sikuli needs to wait until image A or B or C forever,
then take action according to which image shows up, e.g:
imgA appears, click a
imgB appears, click b
imgC appears, click c

ive tried modifying the script from here :
https://answers.launchpad.net/sikuli/+question/195347

def handler(e):
    global isImgA_or_ImgB_or_ImgC
    isImgA_or_ImgB_or_ImgC = True

RegA.onAppear(imgA, handler)
RegB.onAppear(imgB, handler)
RegC.onAppear(imgC, handler)

while True:
    RegA.observe(FOREVER, background=True)
    RegB.observe(FOREVER, background=True)
    RegC.observe(FOREVER, background=True)
    isImgA_or_ImgB_or_ImgC = False
    while not isImgA_or_ImgB_or_ImgC:
        wait(1)
    RegA.stopObserver()
    RegB.stopObserver()
    RegC.stopObserver()
         if exists (imgA):
             click (imgA)
         elif exists (imgB):
             click (imgB)
         else:
             click (imgC)

But i cant get this to work, any idea why?
thanks

Question information

Language:
English Edit question
Status:
Solved
For:
SikuliX Edit question
Assignee:
No assignee Edit question
Last query:
Last reply:

This question was reopened

Revision history for this message
j (j-the-k) said :
#1

On first sight, I can't see any obvious error in your script.
Which part is working/not working?

Does the observer fail or does the following click fail?

If one of the images is on the screen when the scripts start, and is instantly found, your "isImgA_or_ImgB_or_ImgC = False" could overwrite that, so I would put "isImgA_or_ImgB_or_ImgC = False" before the RegX.observe() statements.

Also, you are doing a lot redundant searchoperations, because every observe, exists and click triggers a new search. But this is only a performance issue.

Also, the if exists() block has wrong indent, but I don't know if that's just a launchpad formatting thing.

Please tell if at least the observe-part works, and make sure you have the right regions/images so that we can exclude this as a source of the error.

Revision history for this message
RaiMan (raimund-hocke) said :
#2

totally agree with j

a modified version:

def handler(e):
    global isImgA_or_ImgB_or_ImgC
    isImgA_or_ImgB_or_ImgC = True

RegA.onAppear(imgA, handler)
RegB.onAppear(imgB, handler)
RegC.onAppear(imgC, handler)

while True:
    isImgA_or_ImgB_or_ImgC = False
    RegA.observe(FOREVER, background=True)
    RegB.observe(FOREVER, background=True)
    RegC.observe(FOREVER, background=True)
    while not isImgA_or_ImgB_or_ImgC:
        wait(1)
    RegA.stopObserver()
    RegB.stopObserver()
    RegC.stopObserver()
    if RegA.exists (imgA, 0):
        click RegA.getLastMatch()
    elif RegB.exists (imgB, 0):
        click RegB.getLastMatch()
    else:
        click (RegC.find(imgC))

Another option would be, to use the observe-match-region.

e.g.
def handler(e):
    global someImage
    someRegion = e.region

and then compare the regions.

Revision history for this message
denywinarto (deny-winarto) said :
#3

Sorry, the error is regA is not defined,
how exactly do i define region?
my programming skill is not too good

Revision history for this message
denywinarto (deny-winarto) said :
#4

heres the complete code

http://i957.photobucket.com/albums/ae55/deny_winarto/20120825_111811.jpg

c.png is bug tracker, if it detects it sikuli should press "dont send"
am i doing it correctly?

Revision history for this message
RaiMan (raimund-hocke) said :
#5

A screenshot of the coding does not help much ;-)

You might send me the .sikuli and some screenshots of your app situation.
Then I would be able and willing to give you some hints.

-> mail at: https://launchpad.net/~raimund-hocke

Revision history for this message
denywinarto (deny-winarto) said :
#6

i haven't built it yet,
because i'm afraid it will be gone
on my previous project, i saved the project then when i try to close and reopen it, it wont open..
i dunno why, im running it on xp sp2 on jre 1.6

so i have to make sure it works on before building it..
here's the screenshot of the entire code and the error

http://i957.photobucket.com/albums/ae55/deny_winarto/20120825_200352.jpg

http://i957.photobucket.com/albums/ae55/deny_winarto/20120825_200429.jpg

(for security reason i cant take a screenshot i hope its ok)

Revision history for this message
RaiMan (raimund-hocke) said :
#7

Just copying anyone else's work without understanding, what you are doing, is hard work.

So I recommend, to at least have a quick look to Sikuli's docs, to get a basic understanding about features and how it works.

--- i haven't built it yet, because i'm afraid it will be gone
Just save your work, before you run it.
Do not change anything with a .sikuli folder outside the Sikuli IDE.
Your script's text is in the contained .py file.
If the IDE does not restart: look faq 2005

--- RegA is not defined
Before it is possible to use a variable (a region in this case) it must be defined
RegA = <some area on the screen>

So if you are sure, your images will be found when searching the whole screen:
RegA = Region(SCREEN)
RegB = Region(SCREEN)
RegC = Region(SCREEN)

--- (for security reason i cant take a screenshot i hope its ok)
... but without, I cannot give you any specific help. So surely for me it is ok ;-)

Revision history for this message
denywinarto (deny-winarto) said :
#8

Thanks for the answer,
sorry i'm rather new in this thing,
ive looked into the faqs but still a bit confused..

it works, but when i run it, seems like it wont stop running and the IDE wont reappear..
I've added "exit" but it's still running.. so i cant tell what the error is..

sorry for not providing enough details, it doesnt save. skl files in my pc,
probably because i redirect My Documents to D? So i cant reopen it.. also :
- sikuli doesnt work with jre 1.7, so i had to use 1.6
- on the link you gave me :
--- to set/change System Path and Environment:
Systemsettings -> System -> Extended -> Environmentvariables
where can i find the systemsettings? its not in the IDE or in installation directory
- i also get this bug after saving the project : https://bugs.launchpad.net/sikuli/+bug/944687
but the solution to save in root directory doesn't solve my problem..

Revision history for this message
j (j-the-k) said :
#9

The Systemsettings are your windows operating system settings.
You can open them by clicking Start -> Settings -> System settings on your desktop.

Revision history for this message
RaiMan (raimund-hocke) said :
#10

--- it works, but when i run it, seems like it wont stop running
If the above snippet is still your code: it will run forever intentionally,because the loop does not contain any termination rule.
So you have to use shift-alt-c to stop it or kill the java running process.
BUT AGAIN: ALWAYS save your script, BEFORE running it again after having made any changes.

--- it doesnt save. skl files in my pc
Forget about .skl files (save as executable) - they are of no value for nearly anything - especially if you are a newbee to all this stuff. concentrate on saving your stuff normally after having made changes.
And NEVER touch a .sikuli folder outside the IDE!

--- i also get this bug after saving the project
The mentioned bug applies to saving scripts INTO the root directory of a drive like D:
So do not do it. You should at least have one folder level like D:\mySikuli, where you save your scripts or have even additional folders (but at least one).

--- the script is never lost ...
... but there are some cases, where you cannot reopen it with the IDE.
In these cases, you always find your script text in the .py file contained in the .sikuli folder, which you can open with a normal editor, from where you can bring it back to a new IDE script using copy and paste. The contained images can be brought back to the new script using the <load image> button.

Revision history for this message
RaiMan (raimund-hocke) said :
#11

about loops and how to terminate them regularly: faq 1437

Revision history for this message
denywinarto (deny-winarto) said :
#12

Thanks again raiman,
i managed to get it working,
and yes, you're right, it's because i saved it in root folder lol :p

Just one last thing i can't figure out,
How do i replay the script for this code structure?
I've read https://answers.launchpad.net/sikuli/+faq/1437
But i still can't figure out where to place the while-break,

--------------------------------------------
type("d",KEY_WIN)
doubleClick(Pattern("1346049773218.png").similar(0.85))
RegA = Region(SCREEN)
RegB = Region(SCREEN)
RegC = Region(SCREEN)
RegD = Region(SCREEN)
RegE = Region(SCREEN)
def handler(e):
    global isImgA_or_ImgB_or_ImgC_or_ImgD_or_ImgE
    isImgA_or_ImgB_or_ImgC_or_ImgD_or_ImgE = True
RegA.onAppear(Pattern("XPBLauncherF.png").similar(0.81), handler)
RegB.onAppear(Pattern("ICIMuhunmaaf.png").similar(0.91), handler)
RegC.onAppear(Pattern("1346051181203.png").similar(0.89), handler)
RegD.onAppear(Pattern("1346049877203.png").similar(0.92), handler)
RegE.onAppear(Pattern("QondErrorRep.png").similar(0.88), handler)
while True:
    RegA.observe(FOREVER,background=True)
    RegB.observe(FOREVER,background=True)
    RegC.observe(FOREVER,background=True)
    RegD.observe(FOREVER,background=True)
    RegE.observe(FOREVER,background=True)
    isImgA_or_ImgB_or_ImgC_or_ImgD_or_ImgE = False
    while not isImgA_or_ImgB_or_ImgC_or_ImgD_or_ImgE:
        wait(1)
    RegA.stopObserver()
    RegB.stopObserver()
    RegC.stopObserver()
    RegD.stopObserver()
    if RegA.exists(Pattern("XPBLauncherF.png").similar(0.81),0):
        click(Pattern("OK.png").similar(0.86))
        break
        exit
    elif RegB.exists(Pattern("ICIMuhunmaaf.png").similar(0.91),0):
        click(Pattern("OK.png").similar(0.86))
        break
        exit
    elif RegC.exists(Pattern("1346051181203.png").similar(0.89),0):
        doubleClick(Pattern("1346051181203.png").similar(0.89))
        wait(Pattern("1346088182875.png").similar(0.79), FOREVER)
        click(Pattern("Y.png").similar(0.83))
        click(Pattern("1346050299265.png").similar(0.83))
        break
        exit
    elif RegD.exists(Pattern("1346049877203.png").similar(0.92),0):
        click(Pattern("Y.png").similar(0.83))
        click(Pattern("1346050299265.png").similar(0.83))
        break
        exit
    ->elif RegE.exists(Pattern("ErrorReport.png").similar(0.88),0):
        click(Pattern("Dontsend.png").similar(0.92))
        RegE.stopObserver()
        break
        exit-<
-------------------------------------------------------
See the "->"?
Basically i want it to repeat the script whenever it crashes and found a bug when the program is running,
(you know, the 'send error report' page)

I'm unsure where to place the While True,
If i place it in the beginning, it won't be able to search the send error report image continuously..
Any idea?

*nb: just a feedback, perhaps you could make it compatible with jre 1.7?
There might be alot of users asking about incompability, since by default java always gives newest jre on their site

Revision history for this message
RaiMan (raimund-hocke) said :
#13

--- Java 7
... surely it will be compatible some day in the future, but I cannot tell you when (I am not the developer)

--- break; exit
Because of the nature of the break (jumps out of the loop to the next statement after the loop) a following exit will never be executed. So it can just be deleted.

--- Basically i want it to repeat the script whenever it crashes and found a bug when the program is running,
Not clear, what you are talking about.
Currently all the workflow containing action statements is repeated for ever, until one of the images appears. then the script stops (because of the break statements,that end the loop).
... and the RegE.stopObserver() is misplaced, must be in the block with the others.

If you mean, that only in the case of RegE the loop should be repeated and in all other cases should stop:

# ...
    RegA.stopObserver()
    RegB.stopObserver()
    RegC.stopObserver()
    RegD.stopObserver()
    RegE.stopObserver()
    if RegA.exists(Pattern("XPBLauncherF.png").similar(0.81),0):
        click(Pattern("OK.png").similar(0.86))
        break
        exit
    elif RegB.exists(Pattern("ICIMuhunmaaf.png").similar(0.91),0):
        click(Pattern("OK.png").similar(0.86))
        break
    elif RegC.exists(Pattern("1346051181203.png").similar(0.89),0):
        doubleClick(Pattern("1346051181203.png").similar(0.89))
        wait(Pattern("1346088182875.png").similar(0.79), FOREVER)
        click(Pattern("Y.png").similar(0.83))
        click(Pattern("1346050299265.png").similar(0.83))
        break
    elif RegD.exists(Pattern("1346049877203.png").similar(0.92),0):
        click(Pattern("Y.png").similar(0.83))
        click(Pattern("1346050299265.png").similar(0.83))
        break
    elif RegE.exists(Pattern("ErrorReport.png").similar(0.88),0):
        click(Pattern("Dontsend.png").similar(0.92))
        wait(2) #whatever makes sense and repeat the loop now

Revision history for this message
denywinarto (deny-winarto) said :
#14

    ->elif RegE.exists(Pattern("ErrorReport.png").similar(0.88),0):
        click(Pattern("Dontsend.png").similar(0.92))
        RegE.stopObserver()
        break
        ???
        exit---<

http://i957.photobucket.com/albums/ae55/deny_winarto/20120828_170120.jpg

This part is some kind of bug trap,
you know when a program crashes usually they show 'send error report' window?

The reason i put RegE.stopObserver() there,
is because i want it to continuously monitor for send error report window throughout the script,
(since it might happen anytime due to the nature of the program)

Am i doing it correctly?

And also, i need the script to repeat itself whenever it found that bug.
i.e : after the 'break' part (the ??? part)

So it's something like this :
1.run the script,
2. program crashes,
3. 'send error report' window shows up
4. script clicks 'don't send'
5. repeat the entire script

I'm trying to do the 5th step,
I couldn't find a way to do 'go to line' either
any idea?

Revision history for this message
RaiMan (raimund-hocke) said :
#15

So if you want to ALWAYS observe the 'send error report' event, even during the if ... elif ... elif ... elif processing, then you either have to differentiate this event with its own handler and put the action statements into the handler or put the whole observation into a parallel thread (which might be too oversized).

But what I still do not understand: when one of the images RegA ... D come up, the script does something and then ends. This does not make any sense to me. (means: what is with the program behavior between your above steps 1 and 2, if no crash happens?)

Revision history for this message
denywinarto (deny-winarto) said :
#16

When images RegA/B/C/D come up, code executed and no crash happens,
then the script has accomplished its purpose.

RegE (for error report event) is there so that the script can repeat itself all over again in case the program crashes.
This is for a pc running 24/7 so i need to make sure every scenario is covered
I hope it makes sense, sorry for the confusion

Revision history for this message
RaiMan (raimund-hocke) said :
#17

So final questions to make it clear:
-- does only one of the images RegA..D come up and finishes the process? (exclusive or)
-- might image RegE come up every time, even during processing of events RegA...D ?

Revision history for this message
denywinarto (deny-winarto) said :
#18

Yes to both,
only either A/B/C/D needs to come up and finishes the process.
And E can come up anytime, because i got error report on several different occasions

Revision history for this message
RaiMan (raimund-hocke) said :
#19

Ok, that's rather complicated.

I am out now for some hours (on vacation ;-) and will come back later.

But meanwhile, you can try with my suggestion form comment #15, which applies now.

Revision history for this message
denywinarto (deny-winarto) said :
#20

I got an idea for restarting the script,
what if we add a code to run the same script if the bug occurs?
Is that possible?

Also, i've tried using second handler,
but i cant get the script to run properly, it wont run RegA..D
I've added RegF because it turns out there's another error for network connection problem,
it's same as RegE, it can come up anytime

Any idea where to put the second handler correctly?

type("d",KEY_WIN)
doubleClick(Pattern("1346049773218.png").similar(0.85))
RegA = Region(SCREEN)
RegB = Region(SCREEN)
RegC = Region(SCREEN)
RegD = Region(SCREEN)
RegE = Region(SCREEN)
RegF = Region(SCREEN)
def handler(e):
    global isImgA_or_ImgB_or_ImgC_or_ImgD
    isImgA_or_ImgB_or_ImgC_or_ImgD = True
RegA.onAppear(Pattern("XPBLauncherF.png").similar(0.81), handler)
RegB.onAppear(Pattern("ICIMuhunmaaf.png").similar(0.91), handler)
RegC.onAppear(Pattern("1346051181203.png").similar(0.89), handler)
RegD.onAppear(Pattern("1346049877203.png").similar(0.92), handler)
def handler2(e):
    global isImgE_or_ImgF
    isImgE_or_ImgF = True
RegE.onAppear("XPBLauncherG.png", handler2)
RegF.onAppear(Pattern("QondErrorRep.png").similar(0.88), handler2)
while True:
    RegE.observe(FOREVER,background=True)
    RegF.observe(FOREVER,background=True)
    isImgE_or_ImgF = False
    while not isImgE_or_ImgF:
        wait(1)
    RegE.stopObserver()
    RegF.stopObserver()
    if RegE.exists("XPBLauncherG.png"):
        RegE.stopObserver()
        click(Pattern("OK.png").similar(0.86))
        import pointblank
    elif RegF.exists(Pattern("QondErrorRep.png").similar(0.88),0):
        click(Pattern("1345976311187.png").similar(0.92))
        RegF.stopObserver()
        import pointblank
        break
        exit
    while True:
        RegA.observe(FOREVER,background=True)
        RegB.observe(FOREVER,background=True)
        RegC.observe(FOREVER,background=True)
        RegD.observe(FOREVER,background=True)
        isImgA_or_ImgB_or_ImgC_or_ImgD = False
        while not isImgA_or_ImgB_or_ImgC_or_ImgD:
            wait(1)
        RegA.stopObserver()
        RegB.stopObserver()
        RegC.stopObserver()
        RegD.stopObserver()
        if RegA.exists(Pattern("XPBLauncherF.png").similar(0.81),0):
            click(Pattern("OK.png").similar(0.86))
            break
            exit
        elif RegB.exists(Pattern("ICIMuhunmaaf.png").similar(0.91),0):
            click(Pattern("OK.png").similar(0.86))
            break
            exit
        elif RegC.exists(Pattern("1346051181203.png").similar(0.89),0):
            doubleClick(Pattern("1346051181203.png").similar(0.89))
            wait(Pattern("1346088182875.png").similar(0.79), FOREVER)
            click(Pattern("Y.png").similar(0.83))
            click(Pattern("1346050299265.png").similar(0.83))
            break
            exit
        elif RegD.exists(Pattern("1346049877203.png").similar(0.92),0):
            click(Pattern("Y.png").similar(0.83))
            click(Pattern("1346050299265.png").similar(0.83))
            break
            exit

Revision history for this message
denywinarto (deny-winarto) said :
#21

Ok. i decided to narrow down the bug trap search(E,F) to one of the image search process (C)
I got it to work, like this:

type("d",KEY_WIN)
doubleClick(Pattern("1346049773218.png").similar(0.85))
RegA = Region(SCREEN)
RegB = Region(SCREEN)
RegC = Region(SCREEN)
RegD = Region(SCREEN)
RegE = Region(SCREEN)
RegF = Region(SCREEN)
RegG = Region(SCREEN)
def handler(e):
    global isImgA_or_ImgB_or_ImgC_or_ImgD
    isImgA_or_ImgB_or_ImgC_or_ImgD = True
RegA.onAppear(Pattern("XPBLauncherF.png").similar(0.81), handler)
RegB.onAppear(Pattern("ICIMuhunmaaf.png").similar(0.91), handler)
RegC.onAppear(Pattern("1346051181203.png").similar(0.89), handler)
RegD.onAppear(Pattern("1346049877203.png").similar(0.92), handler)
def handler2(e):
    global isImgE_or_ImgF_or_ImgG
    isImgE_or_ImgF_or_ImgG = True
RegE.onAppear("XPBLauncherG.png", handler2)
RegF.onAppear(Pattern("QondErrorRep.png").similar(0.88), handler2)
RegG.onAppear(Pattern("1346088182875.png").similar(0.79), handler2)
while True:
    RegA.observe(FOREVER,background=True)
    RegB.observe(FOREVER,background=True)
    RegC.observe(FOREVER,background=True)
    RegD.observe(FOREVER,background=True)
    isImgA_or_ImgB_or_ImgC_or_ImgD = False
    while not isImgA_or_ImgB_or_ImgC_or_ImgD:
        wait(1)
    RegA.stopObserver()
    RegB.stopObserver()
    RegC.stopObserver()
    RegD.stopObserver()
    if RegA.exists(Pattern("XPBLauncherF.png").similar(0.81),0):
        click(Pattern("OK.png").similar(0.86))
        break
        exit
    elif RegB.exists(Pattern("ICIMuhunmaaf.png").similar(0.91),0):
        click(Pattern("OK.png").similar(0.86))
        break
        exitC
    elif RegC.exists(Pattern("1346051181203.png").similar(0.89),0):
        doubleClick(Pattern("1346051181203.png").similar(0.89))
        while True:
            RegE.observe(FOREVER,background=True)
            RegF.observe(FOREVER,background=True)
            RegG.observe(FOREVER,background=True)
            isImgE_or_ImgF_or_ImgG = False
            while not isImgE_or_ImgF_or_ImgG:
                wait(1)
            RegE.stopObserver()
            RegF.stopObserver()
            RegG.stopObserver()
            if RegE.exists("XPBLauncherG.png"):
                click(Pattern("OK.png").similar(0.86))
                import pointblank
            elif RegF.exists(Pattern("QondErrorRep.png").similar(0.88),0):
                click(Pattern("1345976311187.png").similar(0.92))
                import pointblank
                break
                exit
            elif RegG.exists(Pattern("1346088182875.png").similar(0.79)):
                click(Pattern("Y.png").similar(0.83))
                click(Pattern("1346050299265.png").similar(0.83))
                break
                exit
    elif RegD.exists(Pattern("1346049877203.png").similar(0.92),0):
        click(Pattern("Y.png").similar(0.83))
        click(Pattern("1346050299265.png").similar(0.83))
        break
        exit

But when i got
"ImportError: No module named pointblank"
(pointblank is the name of this script)
i thought according to this http://sikuli.org/docx/globals.html

We only need
import scriptname
?

What am i missing here?
Or is it impossible to import same script?

Revision history for this message
RaiMan (raimund-hocke) said :
#22

looking at your workflow logic, I understand the following

-1 the script starts and sets up some regions and observer events
-2 a loop is entered, that starts observers A..D
-3 you wait until one of these events is fired
-4 you stop the observers
-5 you evaluate, which of the events A..D was fired (exclusive or, first one wins)
-6 if it is A or B or D, some actions are taken and the loop is ended (comment: again: the exit after the break is useless, because never executed, if you want to terminate your script here, just use exit (written exit() !!) instead of break.
-7 in case of C, you take some actions and start observing E...G (same approach as with steps 2...5 for A...D)
-8 if one of these events fires, you evaluate which one
-9 if it is E or F, it seems, you want to start all over again (import pointblank)
-10 if it is G, you do something and then break the inner loop (the exit does not matter), which finally brings your workflow back to step -2.

The critical part now is step 9.
If I am right, that you want to start your script all over, then it is the same as going back to step -2 (before starting the loop are only one-time-executed statements, which will have the same values, wether you loop again from step -2. or start the script again.
So just replace the import with a break and you have what you want.

your script with modifications:

type("d",KEY_WIN)
doubleClick(Pattern("1346049773218.png").similar(0.85))
RegA = Region(SCREEN)
RegB = Region(SCREEN)
RegC = Region(SCREEN)
RegD = Region(SCREEN)
RegE = Region(SCREEN)
RegF = Region(SCREEN)
RegG = Region(SCREEN)
def handler(e):
    global isImgA_or_ImgB_or_ImgC_or_ImgD
    isImgA_or_ImgB_or_ImgC_or_ImgD = True
RegA.onAppear(Pattern("XPBLauncherF.png").similar(0.81), handler)
RegB.onAppear(Pattern("ICIMuhunmaaf.png").similar(0.91), handler)
RegC.onAppear(Pattern("1346051181203.png").similar(0.89), handler)
RegD.onAppear(Pattern("1346049877203.png").similar(0.92), handler)
def handler2(e):
    global isImgE_or_ImgF_or_ImgG
    isImgE_or_ImgF_or_ImgG = True
RegE.onAppear("XPBLauncherG.png", handler2)
RegF.onAppear(Pattern("QondErrorRep.png").similar(0.88), handler2)
RegG.onAppear(Pattern("1346088182875.png").similar(0.79), handler2)
while True:
    RegA.observe(FOREVER,background=True)
    RegB.observe(FOREVER,background=True)
    RegC.observe(FOREVER,background=True)
    RegD.observe(FOREVER,background=True)
    isImgA_or_ImgB_or_ImgC_or_ImgD = False
    while not isImgA_or_ImgB_or_ImgC_or_ImgD:
        wait(1)
    RegA.stopObserver()
    RegB.stopObserver()
    RegC.stopObserver()
    RegD.stopObserver()
    if RegA.exists(Pattern("XPBLauncherF.png").similar(0.81),0):
        click(Pattern("OK.png").similar(0.86))
        break
    elif RegB.exists(Pattern("ICIMuhunmaaf.png").similar(0.91),0):
        click(Pattern("OK.png").similar(0.86))
        break
    elif RegC.exists(Pattern("1346051181203.png").similar(0.89),0):
        doubleClick(Pattern("1346051181203.png").similar(0.89))
        while True:
            RegE.observe(FOREVER,background=True)
            RegF.observe(FOREVER,background=True)
            RegG.observe(FOREVER,background=True)
            isImgE_or_ImgF_or_ImgG = False
            while not isImgE_or_ImgF_or_ImgG:
                wait(1)
            RegE.stopObserver()
            RegF.stopObserver()
            RegG.stopObserver()
            if RegE.exists("XPBLauncherG.png"):
                click(Pattern("OK.png").similar(0.86))
                break
            elif RegF.exists(Pattern("QondErrorRep.png").similar(0.88),0):
                click(Pattern("1345976311187.png").similar(0.92))
                break
            elif RegG.exists(Pattern("1346088182875.png").similar(0.79)):
                click(Pattern("Y.png").similar(0.83))
                click(Pattern("1346050299265.png").similar(0.83))
                break
    elif RegD.exists(Pattern("1346049877203.png").similar(0.92),0):
        click(Pattern("Y.png").similar(0.83))
        click(Pattern("1346050299265.png").similar(0.83))
        break

Revision history for this message
denywinarto (deny-winarto) said :
#23

Thanks for the answer,
but actually, at step 9, i need it to start back at step 1, not 2.

Because without step 1 the program wont start...
On step 9 the program closes,
either because bug crash (RegE), or network error / no connection (RegF)

Revision history for this message
RaiMan (raimund-hocke) said :
#24

So it is simply, that you have to start your program again after events E and F?

If yes, that is super easy ;-)

At the beginning:

# I guess this starts your program
type("d",KEY_WIN)
doubleClick(Pattern("1346049773218.png").similar(0.85))

# replace it with
def startProgram():
    type("d",KEY_WIN)
    doubleClick(Pattern("1346049773218.png").similar(0.85))
    wait(3) # adjust to your needs
startProgram()

# now in the elif blocks for E and F put this just before the break
startProgram()

So before it goes back to step 2, it restarts your program, which is the only thing, that has to be repeated before looping again to wait for A...D

Revision history for this message
denywinarto (deny-winarto) said :
#25

Thanks RaiMan, that solved my question.

Revision history for this message
denywinarto (deny-winarto) said :
#26

Thanks alot for helping me RaiMan,
much appreciated.
Sikuli is fantastic :D

Revision history for this message
denywinarto (deny-winarto) said :
#27

Sorry to open up this thread again RaiMan,
But apparently that method only loop the encaged area:

i.e:

def startProgram():
 do x
 do y
 do z
startProgram()
While true
 do abc
 etc

Calling startProgram() anywhere in the codes after that only repeat the code:
 do x
 do y
 do z

The code after that is skipped,
So it does not really replay the entire script..
is there anyway to include it?
Changing the startProgram() to the end point (end of replay) wont work, i.e:

def startProgram():
 do x
 do y
 do z
While true
 do abc
 etc
 startProgram()

Is there anyway to make it really replay the entire script?

Revision history for this message
RaiMan (raimund-hocke) said :
#28

you made a new question on that stuff

Revision history for this message
denywinarto (deny-winarto) said :
#29

Yes, it's the one i asked about in other thread,
i used looping to solve this..

About the for-range method,
I couldn't figure out where to put it for the this code :

type("d",KEY_WIN)
doubleClick(Pattern("1346049773218.png").similar(0.85))
RegA = Region(SCREEN)
RegB = Region(SCREEN)
RegC = Region(SCREEN)
RegD = Region(SCREEN)
RegE = Region(SCREEN)
RegF = Region(SCREEN)
RegG = Region(SCREEN)
def handler(e):
    global isImgA_or_ImgB_or_ImgC_or_ImgD
    isImgA_or_ImgB_or_ImgC_or_ImgD = True
RegA.onAppear(Pattern("XPBLauncherF.png").similar(0.81), handler)
RegB.onAppear(Pattern("ICIMuhunmaaf.png").similar(0.91), handler)
RegC.onAppear(Pattern("1346051181203.png").similar(0.89), handler)
RegD.onAppear(Pattern("1346049877203.png").similar(0.92), handler)
def handler2(e):
    global isImgE_or_ImgF_or_ImgG
    isImgE_or_ImgF_or_ImgG = True
RegE.onAppear("XPBLauncherG.png", handler2)
RegF.onAppear(Pattern("QondErrorRep.png").similar(0.88), handler2)
RegG.onAppear(Pattern("1346088182875.png").similar(0.79), handler2)
while True:
    RegA.observe(FOREVER,background=True)
    RegB.observe(FOREVER,background=True)
    RegC.observe(FOREVER,background=True)
    RegD.observe(FOREVER,background=True)
    isImgA_or_ImgB_or_ImgC_or_ImgD = False
    while not isImgA_or_ImgB_or_ImgC_or_ImgD:
        wait(1)
    RegA.stopObserver()
    RegB.stopObserver()
    RegC.stopObserver()
    RegD.stopObserver()
    if RegA.exists(Pattern("XPBLauncherF.png").similar(0.81),0):
        click(Pattern("OK.png").similar(0.86))
        break
    elif RegB.exists(Pattern("ICIMuhunmaaf.png").similar(0.91),0):
        click(Pattern("OK.png").similar(0.86))
        break
    elif RegC.exists(Pattern("1346051181203.png").similar(0.89),0):
        doubleClick(Pattern("1346051181203.png").similar(0.89))
        while True:
            RegE.observe(FOREVER,background=True)
            RegF.observe(FOREVER,background=True)
            RegG.observe(FOREVER,background=True)
            isImgE_or_ImgF_or_ImgG = False
            while not isImgE_or_ImgF_or_ImgG:
                wait(1)
            RegE.stopObserver()
            RegF.stopObserver()
            RegG.stopObserver()
            if RegE.exists("XPBLauncherG.png"):
                click(Pattern("OK.png").similar(0.86))
                break
            elif RegF.exists(Pattern("QondErrorRep.png").similar(0.88),0):
                click(Pattern("1345976311187.png").similar(0.92))
                break
            elif RegG.exists(Pattern("1346088182875.png").similar(0.79)):
                click(Pattern("Y.png").similar(0.83))
                click(Pattern("1346050299265.png").similar(0.83))
                break
    elif RegD.exists(Pattern("1346049877203.png").similar(0.92),0):
        click(Pattern("Y.png").similar(0.83))
        click(Pattern("1346050299265.png").similar(0.83))
        break

That's why i used 2 scripts,
with the other one not having import,
so it's script A importing script loop_A

Revision history for this message
RaiMan (raimund-hocke) said :
#30

It does not help, to always repost the same script.

Talk about, what you want to do:

- do you want to repeat the whole script x times?

- or only part of it under some conditions? (e.g. the part in while True: )

- or what?

use some pseudo code, to show your intention.

e.g. (your script)

do(start application)
do(set up the regions and observers A ... D)
while True: # loop 1
    do(start observers A ... D)
    wait(for one of the events A ... D)
    if event A: do(something) and exit(loop 1)
    if event B: do(something) and exit(loop 1)
    if event C:
        do: something
        while True: # loop 2
            do(set up the regions and observers E ... G)
            do(start observers E ... G)
            wait: for one of the events E ... G
            if event E: do(something) and exit(loop 2)
            if event F: do(something) and exit(loop 2)
            if event G: do(something) and exit(loop 2)
        # end of loop 2
    if event d: do something and exit(loop 1)
# end of loop 1

and it would still be readable without indents.

This is your current workflow in a compact form and it shows, that with event C you only leave the inner loop 2 and then continue with loop 1 (which might be your intention)

So show in the above compact workflow, what you want to repeat n times.