Package org.sikuli.api.event

Source Code of org.sikuli.api.event.TargetEventDetectionTask

package org.sikuli.api.event;

import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

import org.sikuli.api.Relative;
import org.sikuli.api.ScreenLocation;
import org.sikuli.api.ScreenRegion;
import org.sikuli.api.Target;

interface EventDetectionTask {
  public void run();
}

class TargetEventDetectionTask implements EventDetectionTask{


  /*
   * equal when all fields refer to same object instances
   */
  @Override
  public boolean equals(Object o) {
    TargetEventDetectionTask w = (TargetEventDetectionTask) o;
    return screenRegion == w.screenRegion &&
        target == w.target &&
        listener == w.listener;
  }

  public TargetEventDetectionTask(ScreenRegion screenRegion, Target target,
      TargetEventListener listener) {
    super();
    this.screenRegion = screenRegion;
    this.target = target;
    this.listener = listener;
    this.lastTargetRegion = null;
  }
  public void setLastTargetRegion(ScreenRegion lastTargetRegion) {
    this.lastTargetRegion = lastTargetRegion;
  }
  public TargetEvent createTargetEvent(){
    return new TargetEvent(target, screenRegion, lastTargetRegion);
  }

  final private ScreenRegion screenRegion;
  final private Target target;
  final private TargetEventListener listener;
  private ScreenRegion lastTargetRegion;


  public void run(){
    ScreenRegion currentTargetRegion = null;
    if (lastTargetRegion == null){         

      currentTargetRegion = screenRegion.find(target);
      if (currentTargetRegion != null){
        // appear
        setLastTargetRegion(currentTargetRegion)
        listener.targetAppeared(createTargetEvent());
        //System.out.println(watchedTarget.getTarget() + " has appeared");
      }else{
        // still vanished
      }


    }else{       

      if (isTargetStillAtTheLastLocation()){
        // still appearing at the same location

      }else{

        currentTargetRegion = screenRegion.find(target);

        if (currentTargetRegion == null){
          // vanished
          listener.targetVanished(createTargetEvent());
          setLastTargetRegion(null);
          //System.out.println(watchedTarget.getTarget() + " has vanished");
        }else{
          // moved
          setLastTargetRegion(currentTargetRegion);
          listener.targetMoved(createTargetEvent());
          //System.out.println(watchedTarget.getTarget() + " has moved to " + currentMatch.getTopLeft());

        }
      }
    }

  }



  private boolean isTargetStillAtTheLastLocation(){

    if (lastTargetRegion == null)
      return false;

    // TODO: only need to find in a small area around the last location
    ScreenRegion r = screenRegion.find(target);
    if (r == null)
      return false;   

    ScreenLocation newLocation = Relative.to(r).topLeft().getScreenLocation();
    ScreenLocation lastLocation = Relative.to(lastTargetRegion).topLeft().getScreenLocation();

    boolean isXClose = Math.abs(newLocation.getX() - lastLocation.getX()) < 3;
    boolean isYClose = Math.abs(newLocation.getY() - lastLocation.getY()) < 3;

    return isXClose && isYClose;
  }
}


public class VisualEventManager {

  // update is rare, could be done by any user thread that adds or removes items
  // iteration is often, but only done on the single thread, the event manager thread
  // write might happen during iteration
  private List<EventDetectionTask> detectionTaskList = new CopyOnWriteArrayList<EventDetectionTask>();

  private VisualEventManager(){
    Thread t = new TargetEventDispatherThread();
    t.setDaemon(true);
    t.start();
  }

  static public VisualEventManager getSingleton(){
    if (ref == null)
      ref = new VisualEventManager();   
    return ref;
  }

  public Object clone() throws CloneNotSupportedException{
    throw new CloneNotSupportedException();
  }
  static private VisualEventManager ref;

  public void addTargetEventListener(ScreenRegion screenRegion, Target target, TargetEventListener listener){
    detectionTaskList.add(new TargetEventDetectionTask(screenRegion,target,listener));   
  }

  public void removeTargetEventListener(ScreenRegion screenRegion, Target target, TargetEventListener listener){
    detectionTaskList.remove(new TargetEventDetectionTask(screenRegion,target,listener));
  }

  public void addStateChangeEventListener(ScreenRegion screenRegion, StateChangeListener listener) {
    detectionTaskList.add(new StateChangeEventDetectionTask(screenRegion,listener));
  }


  // Singlton
  class TargetEventDispatherThread extends Thread {

    @Override
    // TODO: should sleep instead of spinning when list is empty
    // use a producer/consumer
    // this consumes the watchedtargets in a blocking queue
    // the queue should be unbounded
    // on a separate thread, a timer thread, it periodically
    // put new watchedtargets in the queue
    // if there are still unprocessed ones, don't put in this round,
    // try again next time interval
    //
    public void run() {

      while (true){

        try {
          Thread.sleep(1000);
        } catch (InterruptedException e) {

        }

        for (EventDetectionTask task : detectionTaskList){                     
          task.run();
        }
      }



    }

  }


 
}
TOP

Related Classes of org.sikuli.api.event.TargetEventDetectionTask

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.