Observe Region cannot be unregistered

Bug #1891605 reported by Michael Böhm on 2020-08-14
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
Sikuli
Medium
RaiMan

Bug Description

Hi!

I am using Sikulix 2.0.4 on Windows 10 64bit, 2 Monitors.

The script:
def testobserve():
    Reg=Region(1,234,2049,1154)

    Reg.onChange(160, testA)
    Reg.observe(3)
    wait(10)
    Reg.stopObserver() #does not change behavior if this line is there

    Reg.onChange(160, testB)
    Reg.observe(3)

def testA(event):
       print "TESTA"
       #repeat(20) does not change behavior if this line is there

def testB(event):
       print_l "TESTB"
       #repeat(20) does not change behavior if this line is there
testobserve()

results in: (on a continuously changing area)
TESTA
TESTA
TESTA
TESTA
TESTA
TESTA
TESTA
TESTB
TESTA
TESTB
TESTA
TESTB
TESTA
TESTB
TESTA
TESTB
TESTA
TESTB
TESTA
TESTB
TESTA
TESTB
TESTA
TESTB

Bug 1) My understanding is that after the first Reg.observe(3) a new function is registered, and the "old" one will be dropped. But it seems that both functions are registered at the same time, which causes some strange effects. (A-B-A-B-A..)
  Workaround: New Region for every handler
Bug 2) In case there is an error in one of the handler-functions, it breaks without error message
Bug 3) cannot be seen in this example, but I try to explain. When done like above (adding registered handlers) also the found areas drift away. this means after 2-3 added registrations the areas dont match the changed area anymore. it goes so far to match changes outside the screen, which causes error messages (but not exceptions). by using new assigned regions, this behavior goes away, and all works like expected. (this might be related to an IDE bug I am going to open, where the editor window jumps around - sometimes)
Suggestion 1) onChange is really nice, but the buggy observer functions are making me crazy. what about a function like exists(pic,sec) to wait for changes on a Region

Thanks in advance
Michael

description: updated
RaiMan (raimund-hocke) on 2020-08-14
Changed in sikuli:
status: New → Opinion
importance: Undecided → Medium
assignee: nobody → RaiMan (raimund-hocke)
milestone: none → 2.0.5
description: updated
RaiMan (raimund-hocke) wrote :

An observer is registered with a Region object and run against that region.

With one Region object you can register one or more events (onChange, onAppear, ...).
For one region it does not make sense to define more than one onChange event.

When the observer is run (reg.observe() foreground/blocking or background/non-blocking) it checks all the currently registered events for that Region object until stopped (timebased or by stopObserver() in a handler).

So this is not true:
Workaround: New Region for every handler

... this is by design to configure a more complex behavior.

--- to wait for changes on a Region

def handler(event):
    global changes
    changes = event.getChanges()
    event.stopObserver()

changes = None
reg.onChange(handler)
reg.observe(10)
if changes:
    print "got changes"
else:
    print "no changes within 10 seconds"

see: https://sikulix-2014.readthedocs.io/en/latest/region.html#observing-visual-events-in-a-region

Michael Böhm (badboisikulix) wrote :

Hi!
Thanks for the real quick answer!

So I now understand, that Reg.stopObserver() needs to be within the handler function. I will try that.

Still I would like to point out, I spend a lot of time with that doc page you gave. I was not able to figure that out. I still believe with reg.observe(10) it should stop automatically after 10 second - it does not.

However I do have a good workaround now.

For bug 2) - it still don't throw an exception in case there is an error within the handler function.

Thanks a lot!
Michael

RaiMan (raimund-hocke) wrote :

--- reg.observe(10) it should stop automatically after 10 second
... correct --- I will check

--- it still don't throw an exception in case there is an error within the handler function.
... an example would be helpful

Michael Böhm (badboisikulix) wrote :

HI!
Example for the Error issue:

def observertest():

        Reg=Region(1,234,2049,1154)
        Reg.onChange(160, observerhandler)
        Reg.observe(3)
        print ("End")

def observerhandler(event):
        print "Event"
        print 10/0
        print "after division by zero"
        print "Important code, which will never run. And I will never know."

observertest()
exit()

results in:
Event
Event
Event
Event
Event
Event
Event
Event
[info] Exit code: 0
End

no exception

RaiMan (raimund-hocke) wrote :

ok. thanks.

... but that at least means, that the observe stops after 3 seconds ...

Michael Böhm (badboisikulix) wrote :

yes seems so, you fixed that bug (events running after exit) 2 years ago. I opened it..:-)
however, the "End" is print after Exit... maybe just a buffer issue

RaiMan (raimund-hocke) on 2020-08-25
Changed in sikuli:
status: Opinion → Invalid
To post a comment you must log in.
This report contains Public information  Edit
Everyone can see this information.

Other bug subscribers