1
1
package org.sikuli.script;
6
5
import java.io.IOException;
6
import java.awt.AWTException;
8
import org.sikuli.script.natives.FindInput;
9
import org.sikuli.script.natives.FindResult;
10
import org.sikuli.script.natives.FindResults;
11
import org.sikuli.script.natives.Mat;
12
import org.sikuli.script.natives.Vision;
8
14
public class EventManager {
9
final static int APPEAR = 0;
10
final static int VANISH = 1;
11
final static int CHANGE = 2;
12
private static EventManager _instance = null;
13
private long _c_instance = 0;
14
private Map<Integer, SikuliEventObserver> _obMap;
15
protected enum State {
16
UNKNOWN, APPEARED, VANISHED
15
19
private Region _region;
19
System.loadLibrary("VisionProxy");
20
System.out.println("EventManager loaded.");
28
public static EventManager getInstance(){
30
_instance = new EventManager();
20
private Mat _lastImgMat = null;
21
private Map<Object, State> _state;
22
private Map<Object, Match> _lastMatch;
23
private Map<Object, SikuliEventObserver> _appearOb, _vanishOb;
24
private Map<Integer, SikuliEventObserver> _changeOb;
25
private int _minChanges;
35
28
public EventManager(Region region){
36
_c_instance = createEventManager();
37
_obMap = new HashMap<Integer, SikuliEventObserver>();
30
_state = new HashMap<Object, State>();
31
_lastMatch = new HashMap<Object, Match>();
32
_appearOb = new HashMap<Object, SikuliEventObserver>();
33
_vanishOb = new HashMap<Object, SikuliEventObserver>();
34
_changeOb = new HashMap<Integer, SikuliEventObserver>();
41
37
private <PSC> float getSimiliarity(PSC ptn){
52
private <PSC> String getFilename(PSC ptn){
54
if( ptn instanceof Pattern ){
55
fname = ((Pattern)ptn).imgURL;
57
else if( ptn instanceof String){
60
if( !(new File(fname)).exists() && Settings.BundlePath!=null)
61
fname = Settings.BundlePath + File.separator + fname;
65
private int getObserverId(SikuliEventObserver ob){
66
int id = ob.hashCode();
67
while(_obMap.containsKey(id)){
68
id+=(int)(Math.random()*100);
74
private SikuliEventObserver getObserverFromId(int id){
75
return _obMap.get(id);
78
48
public <PSC> void addAppearObserver(PSC ptn, SikuliEventObserver ob){
79
int handler_id = getObserverId(ob);
80
addObserver(_c_instance, APPEAR, getFilename(ptn), getSimiliarity(ptn),
81
handler_id, 0, 0, _region.w, _region.h);
49
_appearOb.put(ptn, ob);
50
_state.put(ptn, State.UNKNOWN);
84
53
public <PSC> void addVanishObserver(PSC ptn, SikuliEventObserver ob){
85
int handler_id = getObserverId(ob);
86
addObserver(_c_instance, VANISH, getFilename(ptn), getSimiliarity(ptn),
87
handler_id, 0, 0, _region.w, _region.h);
91
public void addChangeObserver(SikuliEventObserver ob){
92
int handler_id = getObserverId(ob);
93
float change_threshold = -1f;
94
addObserver(_c_instance, CHANGE, "", change_threshold,
95
handler_id, 0, 0, _region.w, _region.h);
54
_vanishOb.put(ptn, ob);
55
_state.put(ptn, State.UNKNOWN);
58
public void addChangeObserver(int threshold, SikuliEventObserver ob){
59
_changeOb.put(new Integer(threshold), ob);
60
_minChanges = getMinChanges();
63
protected void callAppearObserver(Object ptn, Match m){
64
AppearEvent se = new AppearEvent(ptn, m, _region);
65
SikuliEventObserver ob = _appearOb.get(ptn);
66
ob.targetAppeared(se);
69
protected void callVanishObserver(Object ptn, Match m){
70
VanishEvent se = new VanishEvent(ptn, m, _region);
71
SikuliEventObserver ob = _vanishOb.get(ptn);
72
ob.targetVanished(se);
76
protected void checkPatterns(ScreenImage img){
77
Finder finder = new Finder(img, _region);
78
for(Object ptn : _state.keySet()){
82
boolean hasMatch = false;
85
if(m.getScore() >= getSimiliarity(ptn)){
87
_lastMatch.put(ptn, m);
90
Debug.log(9, "check pattern: " + _state.get(ptn) + " match:" + hasMatch);
91
if(_appearOb.containsKey(ptn)){
92
if(_state.get(ptn) != State.APPEARED && hasMatch)
93
callAppearObserver(ptn, m);
95
if(_vanishOb.containsKey(ptn)){
96
if(_state.get(ptn) != State.VANISHED && !hasMatch){
97
callVanishObserver(ptn, _lastMatch.get(ptn));
101
_state.put(ptn, State.APPEARED);
103
_state.put(ptn, State.VANISHED);
105
catch(IOException e){
106
Debug.error("Can't access "+ ptn +"\n" + e.getMessage());
112
protected void callChangeObserver(FindResults results) throws AWTException{
113
for(Integer n : _changeOb.keySet()){
114
List<Match> changes = new ArrayList<Match>();
115
for(int i=0;i<results.size();i++){
116
FindResult r = results.get(i);
117
if( r.getW() * r.getH() >= n )
118
changes.add(_region.toGlobalCoord(new Match(r)));
120
if(changes.size() > 0){
121
ChangeEvent se = new ChangeEvent(changes, _region);
122
SikuliEventObserver ob = _changeOb.get(n);
123
ob.targetChanged(se);
128
protected int getMinChanges(){
129
int min = Integer.MAX_VALUE;
130
for(Integer n : _changeOb.keySet())
136
protected void checkChanges(ScreenImage img){
137
if(_lastImgMat == null){
138
_lastImgMat = OpenCV.convertBufferedImageToMat(img.getImage());
142
FindInput fin = new FindInput();
143
fin.setSource(_lastImgMat);
144
Mat target = OpenCV.convertBufferedImageToMat(img.getImage());
145
fin.setTarget(target);
146
fin.setSimilarity(_minChanges);
148
FindResults results = Vision.findChanges(fin);
150
callChangeObserver(results);
152
catch(AWTException e){
156
_lastImgMat = target;
98
159
public void update(ScreenImage img){
99
byte[] data = OpenCV.convertBufferedImageToByteArray(img.getImage());
100
SikuliEvent[] events = _update(_c_instance, data, img.w, img.h);
103
for(SikuliEvent e : events){
104
SikuliEventObserver ob = getObserverFromId(e.handler_id);
109
ob.targetAppeared(new AppearEvent(e, _region));
112
ob.targetVanished(new VanishEvent(e, _region));
115
ob.targetChanged(new ChangeEvent(e, _region));
161
if(_changeOb.size()>0)
121
165
protected void finalize() throws Throwable {
126
169
public void dispose(){
127
destroy(_c_instance);
130
private native long createEventManager();
131
private native void destroy(long sem_instance);
132
private native void addObserver(long sem_instance,
133
int evt_type, String target_image_filename,
135
int handler_id, int x, int y, int w, int h);
137
private native SikuliEvent[] _update(long sem_instance,
138
byte[] screenImage, int w, int h);