[sikuli] 303/385: ongoing: getting observe to work
Gilles Filippini
pini at moszumanska.debian.org
Sun Jun 29 19:26:26 UTC 2014
This is an automated email from the git hooks/post-receive script.
pini pushed a commit to tag upstream/1.1.0_beta1
in repository sikuli.
commit 4e442655aaaec5b59bc19d8292143221494f09fb
Author: Raimund Hocke <rmhdevelop at me.com>
Date: Wed Feb 26 19:20:16 2014 +0100
ongoing: getting observe to work
---
.../main/java/org/sikuli/script/ObserveChange.java | 3 +-
.../main/java/org/sikuli/script/ObserveEvent.java | 66 +++--
API/src/main/java/org/sikuli/script/Observer.java | 330 +++++++++++----------
API/src/main/java/org/sikuli/script/Observing.java | 105 +++++--
API/src/main/java/org/sikuli/script/Region.java | 93 +++---
API/src/main/java/org/sikuli/script/SikuliX.java | 1 +
Basics/src/main/resources/Lib/sikuli/Region.py | 16 +-
7 files changed, 384 insertions(+), 230 deletions(-)
diff --git a/API/src/main/java/org/sikuli/script/ObserveChange.java b/API/src/main/java/org/sikuli/script/ObserveChange.java
index 7d7ba39..0c2ca74 100755
--- a/API/src/main/java/org/sikuli/script/ObserveChange.java
+++ b/API/src/main/java/org/sikuli/script/ObserveChange.java
@@ -12,10 +12,11 @@ import java.util.List;
* INTERNAL USE
*/
public class ObserveChange extends ObserveEvent {
- public ObserveChange(List<Match> results, Region r){
+ public ObserveChange(List<Match> results, Region r, int eventIndex){
type = Type.CHANGE;
setChanges(results);
setRegion(r);
+ setIndex(eventIndex);
}
@Override
diff --git a/API/src/main/java/org/sikuli/script/ObserveEvent.java b/API/src/main/java/org/sikuli/script/ObserveEvent.java
index 2dd2361..1713b4b 100755
--- a/API/src/main/java/org/sikuli/script/ObserveEvent.java
+++ b/API/src/main/java/org/sikuli/script/ObserveEvent.java
@@ -21,9 +21,10 @@ public class ObserveEvent {
public Type type;
private Region region = null;
+ private Object pattern = null;
private Match match = null;
+ private int index = -1;
private List<Match> changes = null;
- private Object pattern = null;
public ObserveEvent() {
}
@@ -50,7 +51,7 @@ public class ObserveEvent {
}
protected void setRegion(Region r) {
- region = new Region(r);
+ region = r;
}
/**
@@ -62,7 +63,21 @@ public class ObserveEvent {
}
protected void setMatch(Match m) {
- match = new Match(m);
+ if (null != m) {
+ match = new Match(m);
+ }
+ }
+
+ /**
+ *
+ * @return the index in the observer map in Observer (CHANGE)
+ */
+ public int getIndex() {
+ return index;
+ }
+
+ public void setIndex(int index) {
+ this.index = index;
}
/**
@@ -74,8 +89,10 @@ public class ObserveEvent {
}
protected void setChanges(List<Match> c) {
- changes = new ArrayList<Match>();
- changes.addAll(c);
+ if (c != null) {
+ changes = new ArrayList<Match>();
+ changes.addAll(c);
+ }
}
/**
@@ -83,18 +100,23 @@ public class ObserveEvent {
* @return the used pattern for this event's observing
*/
public Pattern getPattern() {
- if (pattern.getClass().isInstance("")) {
- return (new Pattern((String) pattern));
- } else {
- return (new Pattern((Pattern) pattern));
+ if (null != pattern) {
+ if (pattern.getClass().isInstance("")) {
+ return (new Pattern((String) pattern));
+ } else {
+ return (new Pattern((Pattern) pattern));
+ }
}
+ return null;
}
protected void setPattern(Object p) {
- if (p.getClass().isInstance("")) {
- pattern = new Pattern((String) p);
- } else {
- pattern = new Pattern((Pattern) p);
+ if (null != p) {
+ if (p.getClass().isInstance("")) {
+ pattern = new Pattern((String) p);
+ } else {
+ pattern = new Pattern((Pattern) p);
+ }
}
}
@@ -112,16 +134,15 @@ public class ObserveEvent {
* @param secs
*/
public void repeat(long secs) {
- region.getEvtMgr().repeat(type, pattern, match, secs);
+ region.getObserver().repeat(type, pattern, match, secs);
}
/**
- * only for (APPEAR, VANISH)
* @return the number how often this event has already been triggered until now
*/
public int getCount() {
if (type == Type.CHANGE) {
- return 0;
+ return region.getObserver().getChangedCount(index);
} else {
return region.getEvtMgr().getCount(pattern);
}
@@ -134,9 +155,18 @@ public class ObserveEvent {
region.stopObserver();
}
+ public void stopObserver(String msg) {
+ region.stopObserver(msg);
+ }
+
@Override
public String toString() {
- return String.format("SikuliEvent(%s) on %s with %s having last match: %s",
- type, region, pattern, match);
+ if (type == Type.CHANGE) {
+ return String.format("Event(%s) on: %s with: %d count: %d",
+ type, region, index, getCount());
+ } else {
+ return String.format("Event(%s) on: %s with: %s match: %s count: %d",
+ type, region, pattern, match, getCount());
+ }
}
}
diff --git a/API/src/main/java/org/sikuli/script/Observer.java b/API/src/main/java/org/sikuli/script/Observer.java
index c2e1c88..ed907ad 100755
--- a/API/src/main/java/org/sikuli/script/Observer.java
+++ b/API/src/main/java/org/sikuli/script/Observer.java
@@ -17,68 +17,76 @@ import org.sikuli.natives.Mat;
import org.sikuli.natives.Vision;
/**
- * INTERNAL USE
- * implements the observe action for a region and calls the ObserverCallBacks
+ * INTERNAL USE implements the observe action for a region and calls the ObserverCallBacks
*/
public class Observer {
+ private static String me = "Observer";
+ private static int lvl = 3;
+
+ private static void log(int level, String message, Object... args) {
+ Debug.logx(level, "", me + ": " + message, args);
+ }
+
protected enum State {
+
FIRST, UNKNOWN, MISSING, APPEARED, VANISHED, REPEAT
}
- private Region _region;
- private Mat _lastImgMat = null;
- private org.opencv.core.Mat _lastImageMat = null;
- private Map<Object, State> _state;
- private Map<Object, Long> _wait;
- private Map<Object, Integer> _count;
- private Map<Object, Match> _lastMatch;
- private Map<Object, String> _names;
-// private Map<Object, SikuliEventObserver> _appearOb, _vanishOb;
- private Map<Object, Object> _appearOb, _vanishOb;
-// private Map<Integer, SikuliEventObserver> _changeOb;
- private Map<Integer, Object> _changeOb;
- private Map<Integer, Integer> _countc;
- private Map<Integer, String> _cnames;
- private int _minChanges;
+ private Region observedRegion;
+ private Mat lastImgMat = null;
+ private org.opencv.core.Mat lastImageMat = null;
+ private Map<Object, State> eventStates;
+ private Map<Object, Long> repeatWaitTimes;
+ private Map<Object, Integer> happenedCount;
+ private Map<Object, Match> lastMatches;
+ private Map<Object, String> eventNames;
+ private Map<Object, Object> appearCallBacks, vanishCallBacks;
+ private Map<Integer, Object> changeCallBacks;
+ private Map<Integer, Integer> changedCount;
+ private Map<Integer, String> onChangeNames;
+ private int minChanges;
private boolean sthgLeft;
+ private boolean shouldCheckChanges;
public Observer(Region region) {
- _region = region;
- _state = new HashMap<Object, State>();
- _wait = new HashMap<Object, Long>();
- _count = new HashMap<Object, Integer>();
- _lastMatch = new HashMap<Object, Match>();
- _names = new HashMap<Object, String>();
-// _appearOb = new HashMap<Object, SikuliEventObserver>();
-// _vanishOb = new HashMap<Object, SikuliEventObserver>();
-// _changeOb = new HashMap<Integer, SikuliEventObserver>();
- _appearOb = new HashMap<Object, Object>();
- _vanishOb = new HashMap<Object, Object>();
- _changeOb = new HashMap<Integer, Object>();
- _countc = new HashMap<Integer, Integer>();
- _cnames = new HashMap<Integer, String>();
+ observedRegion = region;
+ eventStates = new HashMap<Object, State>();
+ repeatWaitTimes = new HashMap<Object, Long>();
+ happenedCount = new HashMap<Object, Integer>();
+ lastMatches = new HashMap<Object, Match>();
+ eventNames = new HashMap<Object, String>();
+ appearCallBacks = new HashMap<Object, Object>();
+ vanishCallBacks = new HashMap<Object, Object>();
+ changeCallBacks = new HashMap<Integer, Object>();
+ changedCount = new HashMap<Integer, Integer>();
+ onChangeNames = new HashMap<Integer, String>();
}
public void initialize() {
- Debug.log(2, "SikuliEventManager: resetting observe states for " + _region.toStringShort());
+ log(3, "resetting observe states for " + observedRegion.toStringShort());
sthgLeft = true;
- for (Object ptn : _state.keySet()) {
- _state.put(ptn, State.FIRST);
- _count.put(ptn, 0);
+ shouldCheckChanges = true;
+ for (Object ptn : eventStates.keySet()) {
+ eventStates.put(ptn, State.FIRST);
+ happenedCount.put(ptn, 0);
}
- for (int n : _changeOb.keySet()) {
- _countc.put(n, 0);
+ for (int n : changeCallBacks.keySet()) {
+ changedCount.put(n, 0);
}
}
public void setRegion(Region reg) {
- _region = reg;
+ observedRegion = reg;
}
public int getCount(Object ptn) {
- return _count.get(ptn);
+ return happenedCount.get(ptn);
}
+ public int getChangedCount(int index) {
+ return changedCount.get(index);
+ }
+
private <PSC> float getSimiliarity(PSC ptn) {
float similarity = -1f;
if (ptn instanceof Pattern) {
@@ -91,64 +99,67 @@ public class Observer {
}
public <PSC> void addAppearObserver(PSC ptn, ObserverCallBack ob, String name) {
- _appearOb.put(ptn, ob);
- _state.put(ptn, State.FIRST);
- _names.put(ptn, name);
+ appearCallBacks.put(ptn, ob);
+ eventStates.put(ptn, State.FIRST);
+ eventNames.put(ptn, name);
}
public <PSC> void removeAppearObserver(PSC ptn) {
- Observing.remove(_names.get(ptn));
- _names.remove(ptn);
- _appearOb.remove(ptn);
- _state.remove(ptn);
+ Observing.remove(eventNames.get(ptn));
+ eventNames.remove(ptn);
+ appearCallBacks.remove(ptn);
+ eventStates.remove(ptn);
}
public <PSC> void addVanishObserver(PSC ptn, ObserverCallBack ob, String name) {
- _vanishOb.put(ptn, ob);
- _state.put(ptn, State.FIRST);
- _names.put(ptn, name);
+ vanishCallBacks.put(ptn, ob);
+ eventStates.put(ptn, State.FIRST);
+ eventNames.put(ptn, name);
}
public <PSC> void removeVanishObserver(PSC ptn) {
- Observing.remove(_names.get(ptn));
- _names.remove(ptn);
- _vanishOb.remove(ptn);
- _state.remove(ptn);
+ Observing.remove(eventNames.get(ptn));
+ eventNames.remove(ptn);
+ vanishCallBacks.remove(ptn);
+ eventStates.remove(ptn);
}
private void callAppearObserver(Object ptn, Match m) {
- ObserveAppear se = new ObserveAppear(ptn, m, _region);
- Object ao = _appearOb.get(ptn);
- Observing.addEvent(_names.get(ptn), se);
- if (ao != null && ao instanceof ObserverCallBack) {
- ((ObserverCallBack)_appearOb.get(ptn)).appeared(se);
+ log(lvl, "appeared: %s with: %s\nat: %s", eventNames.get(ptn), ptn, m);
+ ObserveAppear observeEvent = new ObserveAppear(ptn, m, observedRegion);
+ Object callBack = appearCallBacks.get(ptn);
+ Observing.addEvent(eventNames.get(ptn), observeEvent);
+ if (callBack != null && callBack instanceof ObserverCallBack) {
+ log(lvl, "running call back");
+ ((ObserverCallBack) appearCallBacks.get(ptn)).appeared(observeEvent);
}
}
private void callVanishObserver(Object ptn, Match m) {
- ObserveVanish se = new ObserveVanish(ptn, m, _region);
- Object ao = _vanishOb.get(ptn);
- Observing.addEvent(_names.get(ptn), se);
- if (ao != null && ao instanceof ObserverCallBack) {
- ((ObserverCallBack)_vanishOb.get(ptn)).vanished(se);
+ log(lvl, "vanished: %s with: %s\nat: %s", eventNames.get(ptn), ptn, m);
+ ObserveVanish observeEvent = new ObserveVanish(ptn, m, observedRegion);
+ Object callBack = vanishCallBacks.get(ptn);
+ Observing.addEvent(eventNames.get(ptn), observeEvent);
+ if (callBack != null && callBack instanceof ObserverCallBack) {
+ log(lvl, "running call back");
+ ((ObserverCallBack) vanishCallBacks.get(ptn)).vanished(observeEvent);
}
}
private void checkPatterns(ScreenImage simg) {
Finder finder = null;
if (Settings.UseImageFinder) {
- finder = new ImageFinder(_region);
+ finder = new ImageFinder(observedRegion);
((ImageFinder) finder).setIsMultiFinder();
- }
- else {
- finder = new Finder(simg, _region);
+ } else {
+ finder = new Finder(simg, observedRegion);
}
String imgOK;
- Debug.log(3, "observe: checkPatterns entry: sthgLeft: %s isObserving: %s", sthgLeft, _region.isObserving());
- for (Object ptn : _state.keySet()) {
- if (_state.get(ptn) != State.FIRST &&
- _state.get(ptn) != State.UNKNOWN &&
- _state.get(ptn) != State.REPEAT) {
+ log(lvl + 1, "checkPatterns entry: sthgLeft: %s isObserving: %s", sthgLeft, observedRegion.isObserving());
+ for (Object ptn : eventStates.keySet()) {
+ if (eventStates.get(ptn) != State.FIRST
+ && eventStates.get(ptn) != State.UNKNOWN
+ && eventStates.get(ptn) != State.REPEAT) {
continue;
}
imgOK = null;
@@ -157,7 +168,7 @@ public class Observer {
Image img = Image.create((String) ptn);
if (img.isValid()) {
imgOK = finder.find(img);
- } else if (img.isText()){
+ } else if (img.isText()) {
imgOK = finder.findText((String) ptn);
}
} else if (ptn instanceof Pattern) {
@@ -167,24 +178,24 @@ public class Observer {
}
if (null == imgOK) {
Debug.error("EventMgr: checkPatterns: Image not valid", ptn);
- _state.put(ptn, State.MISSING);
+ eventStates.put(ptn, State.MISSING);
continue;
}
- if (_state.get(ptn) == State.REPEAT) {
- Debug.log(3, "repeat: checking");
- if (_lastMatch.get(ptn).exists(ptn) != null) {
- if ((new Date()).getTime() > _wait.get(ptn)) {
- _state.put(ptn, State.APPEARED);
- Debug.log(3, "repeat: vanish timeout");
+ if (eventStates.get(ptn) == State.REPEAT) {
+ log(lvl, "repeat: checking");
+ if (lastMatches.get(ptn).exists(ptn) != null) {
+ if ((new Date()).getTime() > repeatWaitTimes.get(ptn)) {
+ eventStates.put(ptn, State.APPEARED);
+ log(lvl, "repeat: vanish timeout");
// time out
} else {
sthgLeft = true;
}
continue; // not vanished within given time or still there
} else {
- _state.put(ptn, State.UNKNOWN);
+ eventStates.put(ptn, State.UNKNOWN);
sthgLeft = true;
- Debug.log(3, "repeat: has vanished");
+ log(lvl, "repeat: has vanished");
continue; // has vanished, repeat
}
}
@@ -194,43 +205,43 @@ public class Observer {
m = finder.next();
if (m.getScore() >= getSimiliarity(ptn)) {
hasMatch = true;
- _lastMatch.put(ptn, m);
+ lastMatches.put(ptn, m);
}
}
if (hasMatch) {
- Debug.log(2, "EventMgr: checkPatterns: " + ptn.toString() + " match: " +
- m.toStringShort() + " in " + _region.toStringShort());
- } else if (_state.get(ptn) == State.FIRST) {
- Debug.log(2, "EventMgr: checkPatterns: " + ptn.toString() + " match: " +
- "NO" + " in " + _region.toStringShort());
- _state.put(ptn, State.UNKNOWN);
+ log(lvl + 1, "checkPatterns: " + ptn.toString() + " match: "
+ + m.toStringShort() + " in " + observedRegion.toStringShort());
+ } else if (eventStates.get(ptn) == State.FIRST) {
+ log(lvl + 1, "checkPatterns: " + ptn.toString() + " match: "
+ + "NO" + " in " + observedRegion.toStringShort());
+ eventStates.put(ptn, State.UNKNOWN);
}
- if (_appearOb.containsKey(ptn)) {
- if (_state.get(ptn) != State.APPEARED) {
+ if (appearCallBacks.containsKey(ptn)) {
+ if (eventStates.get(ptn) != State.APPEARED) {
if (hasMatch) {
- _state.put(ptn, State.APPEARED);
- _count.put(ptn, _count.get(ptn) + 1);
+ eventStates.put(ptn, State.APPEARED);
+ happenedCount.put(ptn, happenedCount.get(ptn) + 1);
callAppearObserver(ptn, m);
} else {
sthgLeft = true;
}
}
- } else if (_vanishOb.containsKey(ptn)) {
- if (_state.get(ptn) != State.VANISHED) {
+ } else if (vanishCallBacks.containsKey(ptn)) {
+ if (eventStates.get(ptn) != State.VANISHED) {
if (!hasMatch) {
- _state.put(ptn, State.VANISHED);
- _count.put(ptn, _count.get(ptn) + 1);
- callVanishObserver(ptn, _lastMatch.get(ptn));
+ eventStates.put(ptn, State.VANISHED);
+ happenedCount.put(ptn, happenedCount.get(ptn) + 1);
+ callVanishObserver(ptn, lastMatches.get(ptn));
} else {
sthgLeft = true;
}
}
}
- if (!_region.isObserving()) {
+ if (!observedRegion.isObserving()) {
break;
}
}
- Debug.log(3, "observe: checkPatterns exit: sthgLeft: %s isObserving: %s", sthgLeft, _region.isObserving());
+ log(lvl + 1, "checkPatterns exit: sthgLeft: %s isObserving: %s", sthgLeft, observedRegion.isObserving());
}
public void repeat(ObserveEvent.Type type, Object pattern, Match match, long secs) {
@@ -239,33 +250,33 @@ public class Observer {
} else if (type == ObserveEvent.Type.VANISH) {
Debug.error("EventMgr: repeat: not supported for VANISH");
} else if (type == ObserveEvent.Type.APPEAR) {
- _state.put(pattern, State.REPEAT);
+ eventStates.put(pattern, State.REPEAT);
if (secs <= 0) {
- secs = (long) _region.getWaitForVanish();
+ secs = (long) observedRegion.getWaitForVanish();
}
- _wait.put(pattern, (new Date()).getTime() + 1000 * secs);
- Debug.log(2, "EventMgr: repeat: requested for APPEAR: " +
- pattern.toString() + " at " + match.toStringShort() + " after " + secs + " seconds");
+ repeatWaitTimes.put(pattern, (new Date()).getTime() + 1000 * secs);
+ log(lvl, "repeat: requested for APPEAR: "
+ + pattern.toString() + " at " + match.toStringShort() + " after " + secs + " seconds");
sthgLeft = true;
}
}
public void addChangeObserver(int threshold, ObserverCallBack ob, String name) {
- _changeOb.put(new Integer(threshold), ob);
- _minChanges = getMinChanges();
- _cnames.put(threshold, name);
+ changeCallBacks.put(new Integer(threshold), ob);
+ minChanges = getMinChanges();
+ onChangeNames.put(threshold, name);
}
public void removeChangeObserver(int threshold) {
- Observing.remove(_cnames.get(threshold));
- _names.remove(threshold);
- _changeOb.remove(new Integer(threshold));
- _minChanges = getMinChanges();
+ Observing.remove(onChangeNames.get(threshold));
+ eventNames.remove(threshold);
+ changeCallBacks.remove(new Integer(threshold));
+ minChanges = getMinChanges();
}
private int getMinChanges() {
int min = Integer.MAX_VALUE;
- for (Integer n : _changeOb.keySet()) {
+ for (Integer n : changeCallBacks.keySet()) {
if (n < min) {
min = n;
}
@@ -273,88 +284,101 @@ public class Observer {
return min;
}
- private void callChangeObserver(FindResults results) throws AWTException {
- for (Integer n : _changeOb.keySet()) {
+ private int callChangeObserver(FindResults results) {
+ int activeChangeCallBacks = 0;
+ log(lvl, "changes: %d in: %s", results.size(), observedRegion);
+ for (Integer n : changeCallBacks.keySet()) {
+ if (changedCount.get(n) == -1) {
+ continue;
+ }
+ activeChangeCallBacks++;
List<Match> changes = new ArrayList<Match>();
for (int i = 0; i < results.size(); i++) {
FindResult r = results.get(i);
if (r.getW() * r.getH() >= n) {
- changes.add(_region.toGlobalCoord(new Match(r, _region.getScreen())));
+ changes.add(observedRegion.toGlobalCoord(new Match(r, observedRegion.getScreen())));
}
}
if (changes.size() > 0) {
- _countc.put(n, _countc.get(n) + 1);
- ObserveChange se = new ObserveChange(changes, _region);
- Object ao = _changeOb.get(n);
- Observing.addEvent(_cnames.get(n), se);
- if (ao instanceof ObserverCallBack) {
- ((ObserverCallBack)_changeOb.get(n)).changed(se);
+ changedCount.put(n, changedCount.get(n) + 1);
+ ObserveChange observeEvent = new ObserveChange(changes, observedRegion, n);
+ Object callBack = changeCallBacks.get(n);
+ Observing.addEvent(onChangeNames.get(n), observeEvent);
+ if (callBack != null && callBack instanceof ObserverCallBack) {
+ log(lvl, "running call back");
+ ((ObserverCallBack) changeCallBacks.get(n)).changed(observeEvent);
+ } else {
+ // onChange only repeated if CallBack given
+ changedCount.put(n, -1);
+ activeChangeCallBacks--;
}
}
}
+ return activeChangeCallBacks;
}
- private void checkChanges(ScreenImage img) {
+ private boolean checkChanges(ScreenImage img) {
+ boolean changesObserved = true;
if (Settings.UseImageFinder) {
//TODO hack to hide the native call - should be at the top
- if (_lastImageMat == null) {
- _lastImageMat = new org.opencv.core.Mat();
+ if (lastImageMat == null) {
+ lastImageMat = new org.opencv.core.Mat();
}
- if (_lastImageMat.empty()) {
- _lastImageMat = Image.createMat(img.getImage());
- return;
+ if (lastImageMat.empty()) {
+ lastImageMat = Image.createMat(img.getImage());
+ return true;
}
- ImageFinder f = new ImageFinder(_lastImageMat);
- f.setMinChanges(_minChanges);
+ ImageFinder f = new ImageFinder(lastImageMat);
+ f.setMinChanges(minChanges);
org.opencv.core.Mat current = Image.createMat(img.getImage());
if (f.hasChanges(current)) {
//TODO implement ChangeObserver: processing changes
- Debug.log(3, "ChangeObserver: processing changes");
+ log(lvl, "TODO: processing changes");
}
- _lastImageMat = current;
- }
- else {
- if (_lastImgMat == null) {
- _lastImgMat = Image.convertBufferedImageToMat(img.getImage());
- return;
+ lastImageMat = current;
+ } else {
+ if (lastImgMat == null) {
+ lastImgMat = Image.convertBufferedImageToMat(img.getImage());
+ return true;
}
FindInput fin = new FindInput();
- fin.setSource(_lastImgMat);
+ fin.setSource(lastImgMat);
Mat target = Image.convertBufferedImageToMat(img.getImage());
fin.setTarget(target);
- fin.setSimilarity(_minChanges);
+ fin.setSimilarity(minChanges);
FindResults results = Vision.findChanges(fin);
- try {
- callChangeObserver(results);
- } catch (AWTException e) {
- Debug.error("EventMgr: checkChanges: ", e.getMessage());
+ if (results.size() > 0) {
+ if (0 == callChangeObserver(results)) changesObserved = false;
}
- _lastImgMat = target;
+ lastImgMat = target;
}
+ return changesObserved;
}
public boolean update(ScreenImage simg) {
- Debug.log(3, "observe: update entry: sthgLeft: %s obs? %s", sthgLeft, _region.isObserving());
+ log(lvl + 1, "update entry: sthgLeft: %s obs? %s", sthgLeft, observedRegion.isObserving());
boolean ret;
+ boolean changesObserved;
ret = sthgLeft;
if (sthgLeft) {
sthgLeft = false;
checkPatterns(simg);
- if (!_region.isObserving()) {
+ if (!observedRegion.isObserving()) {
return false;
}
}
- if (_region.isObserving()) {
+ if (observedRegion.isObserving()) {
ret = sthgLeft;
- if (_changeOb.size() > 0) {
- checkChanges(simg);
- if (!_region.isObserving()) {
+ if (shouldCheckChanges && changeCallBacks.size() > 0) {
+ changesObserved = checkChanges(simg);
+ shouldCheckChanges = changesObserved;
+ if (!observedRegion.isObserving()) {
return false;
}
- ret = true;
+ ret = changesObserved;
}
}
- Debug.log(3, "observe: update exit: ret: %s", ret);
+ log(lvl + 1, "update exit: ret: %s", ret);
return ret;
}
-}
\ No newline at end of file
+}
diff --git a/API/src/main/java/org/sikuli/script/Observing.java b/API/src/main/java/org/sikuli/script/Observing.java
index 37bd0dd..8023a77 100644
--- a/API/src/main/java/org/sikuli/script/Observing.java
+++ b/API/src/main/java/org/sikuli/script/Observing.java
@@ -9,7 +9,9 @@ package org.sikuli.script;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
+import java.util.Iterator;
import java.util.List;
+import org.sikuli.basics.Debug;
/**
* This class implements a container that globally collects
@@ -17,13 +19,20 @@ import java.util.List;
*/
public class Observing {
+ private static String me = "Observing";
+ private static int lvl = 3;
+
+ private static void log(int level, String message, Object... args) {
+ Debug.logx(level, "", me + ": " + message, args);
+ }
+
private static class Entry {
- private final Region region;
- private final String name;
- private final ObserveEvent.Type type;
- private final boolean isActive = true;
- private final ObserverCallBack obs;
+ private Region region;
+ private String name;
+ private ObserveEvent.Type type;
+ private boolean isActive = true;
+ private ObserverCallBack obs;
protected Entry(String name, Region reg, ObserverCallBack obs, ObserveEvent.Type type) {
this.name = name;
@@ -31,15 +40,40 @@ public class Observing {
this.obs = obs;
this.type = type;
}
+
+ protected void destroy() {
+ region = null;
+ name = null;
+ type = null;
+ obs = null;
+ }
}
public static class Event extends ObserveEvent {
- private Entry observer;
- private long time;
+ private Entry observer = null;
+ private long time = 0;
+
+ protected Event() {
+ }
+
+ protected Event(Event evt) {
+ observer = evt.observer;
+ time = evt.time;
+ setRegion(evt.getRegion());
+ setMatch(evt.getMatch());
+ setChanges(evt.getChanges());
+ setPattern(evt.getPattern());
+ setIndex(evt.getIndex());
+ }
public long getTime() {
return time;
}
+
+ protected void destroy() {
+ observer = null;
+ time = 0;
+ }
}
private static List<Entry> observers = Collections.synchronizedList(new ArrayList<Entry>());
@@ -93,6 +127,12 @@ public class Observing {
if (hasName(name, reg)) {
return false;
}
+ Iterator<Entry> iter = observers.iterator();
+ while (iter.hasNext()) {
+ if (iter.next() == null) {
+ iter.remove();
+ }
+ }
return observers.add(new Entry(name, reg, obs, type));
}
@@ -114,6 +154,9 @@ public class Observing {
private static boolean hasName(String name, Region reg) {
for (Entry obs : observers) {
+ if (obs.name == null) {
+ continue;
+ }
if (name.equals(obs.name)) {
if (reg != null && reg == obs.region) {
return true;
@@ -167,16 +210,16 @@ public class Observing {
return true;
}
- private static void remove(Entry obs) {
+ private static synchronized void remove(Entry obs) {
if (obs.region != null) {
obs.region.stopObserver();
}
- observers.remove(obs);
for (Event ev:events) {
if (ev.observer == obs) {
- events.remove(ev);
+ ev.destroy();
}
}
+ obs.destroy();
}
private static Entry get(Region reg, String name) {
@@ -200,9 +243,23 @@ public class Observing {
* @return success
*/
public static synchronized boolean clear() {
+ log(lvl, "*** requested ***: remove all observers");
for (Entry e : observers) {
remove(e);
}
+ Iterator<Entry> itero = observers.iterator();
+ while (itero.hasNext()) {
+ if (itero.next() == null) {
+ itero.remove();
+ }
+ }
+ Iterator<Event> itere = events.iterator();
+ while (itere.hasNext()) {
+ if (itere.next() == null) {
+ itere.remove();
+ }
+ }
+ log(lvl, "as requested: removed all observers");
return true;
}
@@ -259,6 +316,7 @@ public class Observing {
* @return the time of creation
*/
public static synchronized long addEvent(String name, Object pev) {
+ long t = 0;
if (pev instanceof ObserveEvent) {
ObserveEvent evt = (ObserveEvent) new Event();
ObserveEvent event = (ObserveEvent) pev;
@@ -273,9 +331,15 @@ public class Observing {
ev.observer = get(null, name);
ev.time = new Date().getTime();
if (events.add(ev)) {
- return ev.time;
+ t = ev.time;
}
- return 0;
+ Iterator<Event> iter = events.iterator();
+ while (iter.hasNext()) {
+ if (iter.next() == null) {
+ iter.remove();
+ }
+ }
+ return t;
}
/**
@@ -294,27 +358,32 @@ public class Observing {
Event event = null;
if (obs != null) {
for (Event ev:events) {
- if (ev.observer == obs) {
+ if (ev.observer == null) {
+ continue;
+ }
+ if (ev.observer.name.equals(obs.name)) {
if (event == null) {
event = ev;
continue;
}
if (ev.time > event.time) {
- events.remove(event);
+ event.destroy();
event = ev;
}
}
}
}
if (null != event && remove) {
- events.remove(event);
+ Event ev = new Event(event);
+ event.destroy();
+ event = ev;
}
return event;
}
/**
* remove and return the latest events for that region <br>
- * earlier events are removed
+ * earlier events are removed as well
*
* @return the array of events or size 0 array if none
*/
@@ -335,7 +404,9 @@ public class Observing {
public static synchronized Event[] getEvents() {
List<Event> evts = new ArrayList<Event>();
for (Entry obs:observers) {
- evts.add(getEvent(obs.name, false));
+ if (obs.name != null) {
+ evts.add(getEvent(obs.name, false));
+ }
}
return evts.toArray(new Event[0]);
}
diff --git a/API/src/main/java/org/sikuli/script/Region.java b/API/src/main/java/org/sikuli/script/Region.java
index 83f5b93..9343f0e 100755
--- a/API/src/main/java/org/sikuli/script/Region.java
+++ b/API/src/main/java/org/sikuli/script/Region.java
@@ -25,12 +25,12 @@ import org.sikuli.basics.Settings;
public class Region {
private static String me = "Region";
- private static String mem = "";
private static int lvl = 3;
private static void log(int level, String message, Object... args) {
Debug.logx(level, "", me + ": " + message, args);
}
+
/**
* The Screen containing the Region
*/
@@ -79,14 +79,14 @@ public class Region {
/**
* The {@link Observer} Singleton instance
*/
- private Observer evtMgr = null;
+ private Observer regionObserver = null;
public Observer getEvtMgr() {
- return evtMgr;
+ return regionObserver;
}
public void setEvtMgr(Observer em) {
- evtMgr = em;
+ regionObserver = em;
}
/**
* The last found {@link Match} in the Region
@@ -328,7 +328,7 @@ public class Region {
public Region(int X, int Y, int W, int H) {
this(X, Y, W, H, null);
this.rows = 0;
- Debug.log(3, "Region: init: (%d, %d, %d, %d)", X, Y, W, H);
+ log(lvl, "Region: init: (%d, %d, %d, %d)", X, Y, W, H);
}
/**
@@ -706,6 +706,7 @@ public class Region {
}
//</editor-fold>
+
//<editor-fold defaultstate="collapsed" desc="getters / setters / modificators">
/**
*
@@ -1744,7 +1745,7 @@ public class Region {
if (isOtherScreen()) {
return this;
}
- Debug.history("toggle highlight " + toString() + ": " + toEnable);
+ Debug.action("toggle highlight " + toString() + ": " + toEnable);
if (toEnable) {
overlay = new ScreenHighlighter(getScreen());
overlay.highlight(this);
@@ -1771,7 +1772,7 @@ public class Region {
if (secs < 0.1) {
return highlight((int) secs);
}
- Debug.history("highlight " + toString() + " for " + secs + " secs");
+ Debug.action("highlight " + toString() + " for " + secs + " secs");
ScreenHighlighter _overlay = new ScreenHighlighter(getScreen());
_overlay.highlight(this, secs);
return this;
@@ -2126,13 +2127,13 @@ public class Region {
public <PSI> boolean waitVanish(PSI target, double timeout) {
while (true) {
try {
- Debug.log(2, "waiting for " + target + " to vanish");
+ log(lvl, "waiting for " + target + " to vanish");
RepeatableVanish r = new RepeatableVanish(target);
if (r.repeat(timeout)) {
- Debug.log(2, "" + target + " has vanished");
+ log(lvl, "" + target + " has vanished");
return true;
}
- Debug.log(2, "" + target + " has not vanished before timeout");
+ log(lvl, "" + target + " has not vanished before timeout");
return false;
} catch (Exception ex) {
if (ex instanceof IOException) {
@@ -2236,10 +2237,10 @@ public class Region {
Finder f = new Finder(new Screen().capture(r), r);
f.find(new Pattern(img).similar(Settings.CheckLastSeenSimilar));
if (f.hasNext()) {
- Debug.log(3, "Region: checkLastSeen: still there");
+ log(lvl, "Region: checkLastSeen: still there");
return f;
}
- Debug.log(3, "Region: checkLastSeen: not there");
+ log(lvl, "Region: checkLastSeen: not there");
}
}
if (Settings.UseImageFinder) {
@@ -2459,11 +2460,11 @@ public class Region {
//</editor-fold>
//<editor-fold defaultstate="collapsed" desc="Observing">
- private Observer getEventManager() {
- if (evtMgr == null) {
- evtMgr = new Observer(this);
+ public Observer getObserver() {
+ if (regionObserver == null) {
+ regionObserver = new Observer(this);
}
- return evtMgr;
+ return regionObserver;
}
/**
@@ -2501,7 +2502,8 @@ public class Region {
private <PSI> String onAppearDo(PSI target, Object observer) {
String name = Observing.add(this, (ObserverCallBack) observer, ObserveEvent.Type.APPEAR);
- getEventManager().addAppearObserver(target, (ObserverCallBack) observer, name);
+ getObserver().addAppearObserver(target, (ObserverCallBack) observer, name);
+ log(lvl, "%s: onAppear: %s with: %s", toStringShort(), name, target);
return name;
}
@@ -2532,7 +2534,8 @@ public class Region {
private <PSI> String onVanishDo(PSI target, Object observer) {
String name = Observing.add(this, (ObserverCallBack) observer, ObserveEvent.Type.VANISH);
- getEventManager().addVanishObserver(target, (ObserverCallBack) observer, name);
+ getObserver().addVanishObserver(target, (ObserverCallBack) observer, name);
+ log(lvl, "%s: onVanish: %s with: %s", toStringShort(), name, target);
return name;
}
@@ -2559,7 +2562,7 @@ public class Region {
* @return the event's name
*/
public String onChange(Object observer) {
- return onChangeDo(rows, observer);
+ return onChangeDo(0, observer);
}
/**
@@ -2578,7 +2581,8 @@ public class Region {
public String onChangeDo(int threshold, Object observer) {
String name = Observing.add(this, (ObserverCallBack) observer, ObserveEvent.Type.CHANGE);
- getEventManager().addChangeObserver(threshold, (ObserverCallBack) observer, name);
+ getObserver().addChangeObserver(threshold, (ObserverCallBack) observer, name);
+ log(lvl, "%s: onChange: %s minSize: %d", toStringShort(), name, threshold);
return name;
}
@@ -2618,7 +2622,7 @@ public class Region {
}
private boolean observeDo(double secs) {
- if (evtMgr == null) {
+ if (regionObserver == null) {
Debug.error("Region: observe: Nothing to observe (Region might be invalid): " + this.toStringShort());
return false;
}
@@ -2627,17 +2631,22 @@ public class Region {
Debug.error("Region: observe: already running for this region. Only one allowed!");
return false;
}
- Debug.log(2, "Region: observe: starting in " + this.toStringShort() + " for " + secs + " seconds");
+ log(lvl, "observe: starting in " + this.toStringShort() + " for " + secs + " seconds");
int MaxTimePerScan = (int) (1000.0 / observeScanRate);
long begin_t = (new Date()).getTime();
- long stop_t = begin_t + (long) (secs * 1000);
- evtMgr.initialize();
+ long stop_t;
+ if (secs > Long.MAX_VALUE) {
+ stop_t = Long.MAX_VALUE;
+ } else {
+ stop_t = begin_t + (long) (secs * 1000);
+ }
+ regionObserver.initialize();
observing = true;
SikuliX.addRunningObserver(this);
while (observing && stop_t > (new Date()).getTime()) {
long before_find = (new Date()).getTime();
ScreenImage simg = getScreen().capture(x, y, w, h);
- if (!evtMgr.update(simg)) {
+ if (!regionObserver.update(simg)) {
observing = false;
break;
}
@@ -2651,16 +2660,19 @@ public class Region {
}
} catch (Exception e) {
}
+ log(lvl, "observe: checking again in %s", toStringShort());
}
+ boolean observeSuccess = false;
if (observing) {
observing = false;
- Debug.log(2, "Region: observe: stopped due to timeout in "
+ log(lvl, "observe: stopped due to timeout in "
+ this.toStringShort() + " for " + secs + " seconds");
} else {
- Debug.log(2, "Region: observe: observing has ended for " + this.toStringShort());
+ log(lvl, "observe: ended successfully: " + this.toStringShort());
+ observeSuccess = Observing.hasEvents(this);
}
SikuliX.removeRunningObserver(this);
- return Observing.hasEvents(this);
+ return observeSuccess;
}
/**
@@ -2675,10 +2687,10 @@ public class Region {
Debug.error("Region: observeInBackground: already running for this region. Only one allowed!");
return false;
}
- Debug.log(3, "entering observeInBackground for %f secs", secs);
+ log(lvl, "entering observeInBackground for %f secs", secs);
Thread observeThread = new Thread(new ObserverThread(secs));
observeThread.start();
- Debug.log(3, "observeInBackground now running");
+ log(lvl, "observeInBackground now running");
return true;
}
@@ -2700,9 +2712,18 @@ public class Region {
* stops a running observer
*/
public void stopObserver() {
- Debug.log(2, "Region: observe: request to stop observer for " + this.toStringShort());
+ log(lvl, "Region: observe: request to stop observer for " + this.toStringShort());
observing = false;
}
+
+ /**
+ * stops a running observer printing an info message
+ * @param msg
+ */
+ public void stopObserver(String msg) {
+ Debug.info(msg);
+ stopObserver();
+ }
//</editor-fold>
//<editor-fold defaultstate="collapsed" desc="Mouse actions - clicking">
@@ -2740,7 +2761,7 @@ public class Region {
*/
public <PatternFilenameRegionMatchLocation> int hover(PatternFilenameRegionMatchLocation target)
throws FindFailed {
- Debug.log(3, "hover: " + target);
+ log(lvl, "hover: " + target);
return mouseMove(target);
}
@@ -3402,7 +3423,7 @@ public class Region {
if ((modifiers & KeyModifier.WIN) != 0) {
modifiers -= KeyModifier.WIN;
modifiers |= KeyModifier.META;
- Debug.log(2, "Key.WIN as modifier");
+ log(lvl, "Key.WIN as modifier");
modWindows = "Windows";
}
if (modifiers != 0) {
@@ -3411,7 +3432,7 @@ public class Region {
modText = modText.replace("Meta", modWindows);
}
}
- Debug.history(modText + "TYPE \"" + showText + "\"");
+ Debug.action(modText + "TYPE \"" + showText + "\"");
log(lvl, modText + "TYPE \"" + showText + "\"");
IRobot r = getRobotForRegion();
int pause = 20 + (Settings.TypeDelay > 1 ? 1000 : (int) (Settings.TypeDelay * 1000));
@@ -3498,7 +3519,7 @@ public class Region {
return "--- no text ---";
}
String textRead = tr.recognize(simg);
- Debug.log(2, "Region.text: #(" + textRead + ")#");
+ log(lvl, "Region.text: #(" + textRead + ")#");
return textRead;
}
Debug.error("Region.text: text recognition is currently switched off");
@@ -3521,7 +3542,7 @@ public class Region {
Debug.error("Region.text: text recognition is now switched off");
return null;
}
- Debug.log(2, "Region.listText");
+ log(lvl, "Region.listText");
return tr.listText(simg, this);
}
Debug.error("Region.text: text recognition is currently switched off");
diff --git a/API/src/main/java/org/sikuli/script/SikuliX.java b/API/src/main/java/org/sikuli/script/SikuliX.java
index 84c34b9..25c0bcf 100644
--- a/API/src/main/java/org/sikuli/script/SikuliX.java
+++ b/API/src/main/java/org/sikuli/script/SikuliX.java
@@ -39,6 +39,7 @@ public class SikuliX {
}
runningObservers.clear();
}
+ Observing.clear();
}
public static void endNormal(int n) {
diff --git a/Basics/src/main/resources/Lib/sikuli/Region.py b/Basics/src/main/resources/Lib/sikuli/Region.py
index 18ac074..860571f 100755
--- a/Basics/src/main/resources/Lib/sikuli/Region.py
+++ b/Basics/src/main/resources/Lib/sikuli/Region.py
@@ -63,19 +63,23 @@ class Region(JRegion):
# observe(): Special setup for Jython
# assures, that in any case the same region object is used
- def onAppear(self, target, handler):
+ def onAppear(self, target, handler = None):
+ if not handler:
+ return self.onAppearJ(target, None)
class AnonyObserver(ObserverCallBack):
def appeared(self, event):
handler(event)
return self.onAppearJ(target, AnonyObserver())
- def onVanish(self, target, handler):
+ def onVanish(self, target, handler = None):
+ if not handler:
+ return self.onVanishJ(target, None)
class AnonyObserver(ObserverCallBack):
def vanished(self, event):
handler(event)
- return self.onVanishJ(self, target, AnonyObserver())
+ return self.onVanishJ(target, AnonyObserver())
- def onChange(self, arg1, arg2=None):
+ def onChange(self, arg1=0, arg2=None):
if isinstance(arg1, int):
min_size = arg1
handler = arg2
@@ -84,10 +88,12 @@ class Region(JRegion):
raise Exception("onChange: Invalid parameters set")
min_size = 0
handler = arg1
+ if not handler:
+ return self.onChangeJ(min_size, None)
class AnonyObserver(ObserverCallBack):
def changed(self, event):
handler(event)
return self.onChangeJ(min_size, AnonyObserver())
def observe(self, time=FOREVER, background=False):
- self.observeJ(time, background)
\ No newline at end of file
+ return self.observeJ(time, background)
\ No newline at end of file
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-java/sikuli.git
More information about the pkg-java-commits
mailing list