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.

_______________________________________________
Mailing list: https://launchpad.net/~sikuli-driver
Post to     : [email protected]
Unsubscribe : https://launchpad.net/~sikuli-driver
More help   : https://help.launchpad.net/ListHelp

Reply via email to