sikuli-driver team mailing list archive
-
sikuli-driver team
-
Mailing list archive
-
Message #36902
Re: [Question #286253]: Need a region is quiet (not changing) function
Question #286253 on Sikuli changed:
https://answers.launchpad.net/sikuli/+question/286253
Status: Open => Solved
Spencer Keller confirmed that the question is solved:
Well I wrote it and it works very well. I now feel like my code is
making a reasonable check to see if the application is done loading
rather than just some arbitrary sleep. Use it and enjoy and comments
are always welcome.
Spence
-----------------------------------------------------------------------------
To use:
public void waitForQuite(final Region region) {
QuietHandler observeHandler = new QuietHandler(region);
region.onChange(observeHandler);
region.observe();
if (observeHandler.timedOut() == true) {
Sysytem.out.println("The QuietHandler timed out.");
}
}
-----------------------------------------------------------------------------
package com.solidfire.vat.util;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.atomic.AtomicBoolean;
import org.sikuli.basics.Settings;
import org.sikuli.script.ObserveEvent;
import org.sikuli.script.ObserverCallBack;
import org.sikuli.script.Region;
/**
* A Sikuli ObserverCallBack class that checks to see if a Region has reached a
* "quiet" state. A "quiet" state being defined as a region that has not changed
* in a specified amount of time. The amount of time is determined by the
* checkRate specified at the time of construction. The default value is 2
* seconds.
*/
public class QuietHandler extends ObserverCallBack {
static private long _defaultCheckRate = 500;
static private long _defaultTimeout = 30000;
static private int _quietCount = 4;
private Region _watchRegion = null;
private int _pixelCnt = 0;
private int _counter = 1;
private Timer _timer = new Timer();
private AtomicBoolean _timesUp = new AtomicBoolean(false);
private AtomicBoolean _regionChanged = new AtomicBoolean(true);
/**
* Construct a new QuietHandler for the specified region. Use the default
* check rate of 1/2 seconds (500 ms) and default time out of 30 seconds
* (30000 ms).
*
* @param region the region that is being observed for change.
*/
public QuietHandler(final Region region) {
this(region, _defaultCheckRate, _defaultTimeout);
}
/**
* Construct a new QuietHandler for the specified region and the specified
* check rate. Use the default time out of 30 seconds (30000 ms).
*
* @param region the region that is being observed for change.
* @param checkRate time in milliseconds between checks for region changes.
*/
public QuietHandler(final Region region, final long checkRate) {
this(region, checkRate, _defaultTimeout);
}
/**
* Construct a new QuietHandler for the specified region, the specified
* check rate, and the specified time out.
*
* @param region the region that is being observed for change.
* @param checkRate time in milliseconds between checks for region changes.
* @param timeout time in milliseconds when the checks for changes times out and
* terminates the observation.
*/
public QuietHandler(final Region region, final long checkRate, final long timeout) {
super();
_watchRegion = region;
_pixelCnt = Settings.ObserveMinChangedPixels;
Settings.ObserveMinChangedPixels = 1;
_timer.scheduleAtFixedRate(getQuietTask(), 0, checkRate);
_timer.schedule(getTimesUpTask(), timeout);
}
@Override
public void changed(final ObserveEvent event) {
_regionChanged.set(true);
}
/**
* Did the observed region reach a "quiet" state or did it time out. A
* "quiet" state is defined as a region that has not changed in a specified
* amount of time. The amount of time is determined by the checkRate
* specified at the time of construction. The default value is 2 seconds.
*
* @return false if the region reached the quiet state, true if not.
*/
public boolean timedOut() {
return _timesUp.get();
}
/*
* Return a timer task that sets the "times up" flag to true.
*/
private TimerTask getTimesUpTask() {
return new TimerTask() {
public void run() {
_timesUp.set(true);
}
};
}
/*
* Return a timer task that checks to see if the observed region has changed
* since it was last called. If the region has changed, a "quiet counter" is
* set to 1, its' starting value. However if it has not changed the
* "quiet counter" is incremented by one and if it reaches 4, all timer
* tasks are cancelled, the regions observer is stopped and the region is
* deemed to be "quiet". The task also checks to see if a timeout has
* occurred in which case everything is shut down ending the observation.
*/
private TimerTask getQuietTask() {
return new TimerTask() {
public void run() {
// Is time up?
if (_timesUp.get() == true) {
cleanUp();
return;
}
// Reset the change flag to false then see if the region changed
// since we were last called?
// If not increment the counter else reset the counter to 1.
if (_regionChanged.getAndSet(false) == false) {
_counter++;
} else {
_counter = 1;
}
if (_counter >= _quietCount) {
cleanUp();
}
}
};
}
/*
* Cancel both of the timer tasks, reset the ObserveMinChangedPixels, and
* tell the region to stop the observer.
*/
private void cleanUp() {
_timer.cancel();
_timer.purge();
Settings.ObserveMinChangedPixels = _pixelCnt;
_watchRegion.stopObserver();
}
}
--
You received this question notification because your team Sikuli Drivers
is an answer contact for Sikuli.