[1.0.1] Region exists(..., 0) failing does not return instantly with scan rates > 1 --- fixed in 1.1.0

Bug #1241993 reported by kurokrosk on 2013-10-19
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
Sikuli
Critical
RaiMan

Bug Description

Version: 1.0.1
64-bit

Procedure: I look for a Pattern myPattern that is NOT in the Region myRegion. The size of the pattern (+similarity) and the region are irrelevant.
Expected behavior: The exists/find should return immediately.
Observed behavior: That is not always the case, there is some delay (up to 0.5s) depending on Settings.WaitScanRate.

The code snippet:

# timer start
if not myRegion.exists(myPattern, 0):
    #timer end

Now the result:

Settings.WaitScanRate = 10
Duration: 0.1s

Settings.WaitScanRate = 5
Duration: 0.2s

Settings.WaitScanRate = 4
Duration: 0.25s

Settings.WaitScanRate = 3
Duration: 0.33s (default setting... this is a significant delay)

Settings.WaitScanRate = 2
Duration: 0.5s

Settings.WaitScanRate = 1
Duration: 0.03s

Settings.WaitScanRate = 0.5
Duration: 0.03s

Settings.WaitScanRate = 0.1
Duration: 0.03s (seems the minimal one can reach on that operation)
...

__________

Bug location:
http://bazaar.launchpad.net/~raimund-hocke/sikuli/sikuli-api/view/head:/src/main/java/org/sikuli/script/Region.java#L1879

#L1881 int MaxTimePerScan = (int) (1000.0 / waitScanRate);
#L1882 int MaxTimePerScanSecs = MaxTimePerScan / 1000;
MaxTimePerScanSecs is equal to 0 when waitScanRate is strictly higher to 1, integer division rules in java...

#L1890 if (timeout < MaxTimePerScanSecs)
This is false (assuming timeout is 0), and additional delay ensue...

RaiMan (raimund-hocke) wrote :

LOL, absolutely right. Thanks for finding.

Changed in sikuli:
status: New → Fix Committed
importance: Undecided → High
assignee: nobody → RaiMan (raimund-hocke)
milestone: none → 1.1.0
summary: - timeout lag on Region find/exists miss
+ [1.0.1] Region exists(..., 0) failing does not return instantly with
+ scan rates > 1

This is my fix:

      int MaxTimePerScan = (int) (1000.0 / waitScanRate);
      int timeoutMilli = (int) timeout * 1000;
      long begin_t = (new Date()).getTime();
      do {
        long before_find = (new Date()).getTime();
        run();
        if (ifSuccessful()) {
          return true;
        } else if (timeoutMilli < MaxTimePerScan) {
          // instant return on first search failed if timeout very small or 0
          return false;
        }

kurokrosk (kurokrosk) wrote :

Looks good to me. I would have added parenthesis around timeout * 1000 to handle timeouts below 1s.

RaiMan (raimund-hocke) wrote :

yes, agreed.
thanks.

RaiMan (raimund-hocke) on 2015-06-24
summary: [1.0.1] Region exists(..., 0) failing does not return instantly with
- scan rates > 1
+ scan rates > 1 --- fixed in 1.1.0
Changed in sikuli:
importance: High → Critical
To post a comment you must log in.
This report contains Public information  Edit
Everyone can see this information.

Other bug subscribers