Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

315
LINES

< > BotCompany Repo | #1033576 // Gazelle V, November Edition v1 [backup]

JavaX source code (Dynamic Module) [tags: use-pretranspiled] - run with: Stefan's OS

Uses 1482K of libraries. Click here for Pure Java version (11161L/59K).

1  
!7
2  
3  
!include early #1033506 // Compact Module Include Gazelle V
4  
5  
module GazelleV > DynPrintLogAndEnabled {
6  
  /*switchable int x1;
7  
  switchable int y1;
8  
  switchable int w = screenWidth();
9  
  switchable int h = screenHeight();*/
10  
  switchable double maxFPS = 10;
11  
  switchable int previewWidth = 200;
12  
  switchable double statsEvery = 5;
13  
  switchable volatile bool brokenMethod;
14  
  int lookAtScreen;
15  
  S previewMode;
16  
  int gridRows = 20;
17  
  bool scaleDownPreviewImage;
18  
  int previewPosterization = 256;
19  
20  
  PersistableThrowable lastProcessingError;
21  
  transient WithTimestamp<OKOrError<BufferedImage>> lastScreen;
22  
  transient new Average screenShotTime;
23  
  transient new Average iiTime;
24  
  transient Timestamp loopStarted;
25  
  transient Sleeping screenShotCountdown;
26  
  transient long screenShotCountdownTotalSleepTime;
27  
  //transient ImageSurface imageSurface;
28  
  transient IIImageSurface imageSurface;
29  
  transient Throwable currentProcessingError;
30  
  transient JButton popDownButton;
31  
  transient JComponent topControls;
32  
  transient long screenShotsTaken;
33  
  transient double fps;
34  
  transient Compression ongoingCompression, completedCompression;
35  
  transient S longTermCompressionProbability;
36  
  transient S longTermCompressionScore;
37  
  transient JComponent topControls2;
38  
  transient JTabbedPane tabs;
39  
  transient ThreadPool threadPool;
40  
  
41  
  // ping source for everything we do in the background, including
42  
  // analyzing current screen.
43  
  // normally limited to 50% of one core.
44  
  transient PingSource backgroundPingSource;
45  
  
46  
  transient OnOffOscillator onOffOscillator;
47  
48  
  Rect area() {
49  
    ret screenBounds(min(lookAtScreen, screenCount()-1));
50  
  }
51  
52  
  class Compression {
53  
    settable BufferedImage image;
54  
    settable BWIntegralImage ii;
55  
    CompressionSearch_AnyType search;
56  
    int baseLineLength; // length of trivial compression
57  
    GridCodec1 codec;
58  
    double compressionPercentage;
59  
60  
    S score() {
61  
      var submission = search?.bestSubmission();
62  
      Int compressedSize = or(submission.compressedSize(), baseLineLength);
63  
      compressionPercentage = doubleRatio(compressedSize, baseLineLength)*100;
64  
      ret formatDouble(compressionPercentage, 3) + "%";
65  
    }
66  
67  
    IProbabilisticScheduler scheduler() {
68  
      ret search?.scheduler();
69  
    }
70  
71  
    S probability() {
72  
      var scheduler = scheduler();
73  
      if (scheduler == null) ret "-";
74  
      var prob = scheduler.lastExecutedProbability();
75  
      ret formatDouble(prob, 3);
76  
    }
77  
78  
    event compressionDone;
79  
      
80  
    run {
81  
      int lHex = pixelCount(image)*8;
82  
      baseLineLength = calculateLengthOfFunctionCall imageFromHex(lHex+2);
83  
      print(+baseLineLength);
84  
85  
      codec = new GridCodec1(image);
86  
      codec.rows = gridRows;
87  
      search = codec.forward();
88  
      //showImage(codec.renderCellsLinearly());
89  
90  
      thread "Gazelle Visual" {
91  
        repeat 60 {
92  
          stepForNSeconds(1, search);
93  
          //print(stepCount := search.scheduler().stepCount());
94  
          setFields(
95  
            longTermCompressionProbability := probability(),
96  
            longTermCompressionScore := score());
97  
        }
98  
99  
        try {
100  
          compressionDone();
101  
          
102  
          L<IJavaExpr> cellCompressions = codec.strat.codeForElements();
103  
          //showText("Compression", lines(map shorten_str(cellCompressions)));
104  
105  
          /*S code = str(codec.winnerCode());
106  
          S name = "Screenshot " + ymdMinusHMS();
107  
          File f = makeFileNameUnique_beforeExtension(
108  
            javaxDataDir("Compressed Screenshots/" + name + ".javax"));
109  
          saveTextFile(f, code);
110  
          printFileInfo(f);          
111  
          saveGZTextFile(f = replaceExtension(f, ".jgz"), code);
112  
          printFileInfo(f);*/
113  
114  
          /*
115  
          print("Evaling " + nChars(code));
116  
          //LL<Int> lol = cast dm_javaEval(code);
117  
          BufferedImage restored = cast dm_javaEval(code);
118  
          assertImagesIdentical(restored, image);
119  
          print("Image restored!");
120  
121  
          dm_showImage("Restored from " + nChars(code), restored);
122  
          */
123  
        } catch e { printStackTrace(e); }
124  
      }
125  
    }
126  
    
127  
    void drawOverlay(ImageSurface is, Graphics2D g) pcall {
128  
      codec.drawOverlay(is, g);
129  
    }
130  
    
131  
    int gridCols() { ret widthForHeight(ii.getWidth(), ii.getHeight(), gridRows); }
132  
  }
133  
  
134  
  start {
135  
    if (threadPool == null) threadPool = maxThreadPool();
136  
    
137  
    backgroundPingSource = new PingSource(threadPool, "Background");
138  
    
139  
    onOffOscillator = new OnOffOscillator(backgroundPingSource);
140  
    ownResource(onOffOscillator);
141  
    onOffOscillator.start();
142  
    
143  
    componentFieldsToKeep = litset("tabs");
144  
    
145  
    dm_registerAs_direct gazelleV();
146  
    dm_watchField enabled(r { if (enabled) dm_reload(); });
147  
148  
    // TODO: react to event sent by OS
149  
    dm_doEvery(1.0, r {
150  
      if (dm_moduleIsPoppedOut()) adjustUIForPoppedOutWindow();
151  
    });
152  
    
153  
    print("Screen bounds: " + allScreenBounds());
154  
    
155  
    // We are making some UI elements even if the module is hidden
156  
    // because that's easier.
157  
    
158  
    tabs = jtabs(
159  
      "Log", super.visualize(),
160  
      "Local Data", jcenteredlabel("TODO"));
161  
162  
    dm_doEvery(min(statsEvery, 10.0), statsEvery, r { if (enabled) printStats(); });
163  
    
164  
    loopStarted = tsNow();
165  
    shootAndAnalyze();
166  
  }
167  
  
168  
  void shootAndAnalyze {
169  
    backgroundPingSource.do(r shootAndAnalyze_impl);
170  
  }
171  
172  
  void shootAndAnalyze_impl enter {
173  
    if (!enabled) ret;
174  
175  
    var targetTime = tsNow().plus(1.0/maxFPS);
176  
    long time = nanoTime();
177  
178  
    try {
179  
      lastScreen = withTimestamp(okOrError(-> screenshot(area())));
180  
      ++screenShotsTaken;
181  
      setField(fps := doubleRatio(screenShotsTaken, elapsedSeconds(loopStarted)));
182  
      screenShotTime.add(nanosToSeconds(nanoTime()-time));
183  
      time = nanoTime();
184  
      ping();
185  
      if (lastScreen->isOK()) {
186  
        var img = lastScreen!!;
187  
        var ii = BWIntegralImage(img);
188  
        //var ii = BWIntegralImage_luminosity(lastScreen!!);
189  
        iiTime.add(nanosToSeconds(nanoTime()-time));
190  
      
191  
        if (eq(previewMode, "showLatestGrabbed"))
192  
          imageSurface?.setImage(ii, img);
193  
194  
        if (ongoingCompression == null)
195  
          startCompression(ii);
196  
      }
197  
      
198  
      cpuTotal();
199  
      currentProcessingError = null;
200  
    } catch print e {
201  
      setField(lastProcessingError := currentProcessingError = e);
202  
      //sleepSeconds(60); // errors in processing are no good
203  
    }
204  
    
205  
    screenShotCountdown = sleeper().doLater(targetTime, r shootAndAnalyze);
206  
    screenShotCountdownTotalSleepTime += screenShotCountdown.remainingMS();
207  
  }
208  
209  
  void startCompression(BWIntegralImage ii) {
210  
    if (ongoingCompression == null) {
211  
      ping();
212  
      ongoingCompression = new Compression()
213  
        .image(lastScreen!!)
214  
        .ii(ii);
215  
      ongoingCompression.onCompressionDone(-> {
216  
        completedCompression = ongoingCompression;
217  
        ongoingCompression = null;
218  
        
219  
        IBWIntegralImage ii2 = completedCompression.ii;
220  
        if (scaleDownPreviewImage) {
221  
          ii2 = ScaledIBWIntegralImage(completedCompression.gridCols(), gridRows, ii2);
222  
          ii2 = TruncatedIBWIntegralImage(ii2);
223  
          
224  
          if (previewPosterization < 256)
225  
            imageSurface?.setImage(posterizeIBWImage(previewPosterization, ii2));
226  
          else
227  
            imageSurface?.setImage(ii2);
228  
            
229  
          imageSurface.setOverlay(null);
230  
        } else {
231  
          imageSurface?.setImage(completedCompression.ii, completedCompression.image);
232  
          imageSurface.setOverlay(g -> completedCompression.drawOverlay(imageSurface, g));
233  
        }
234  
      });
235  
      ongoingCompression.run();
236  
    }
237  
  }
238  
239  
  void printStats() { print(stats()); }
240  
241  
  S stats() {
242  
    var screen = lastScreen?!;
243  
    ret formatColonProperties_noNulls(
244  
      "Monitored area", area(),
245  
      "Error", screen?.getError(),
246  
      "Last screenshot taken", lastScreen?.timeStamp(),
247  
      "Average time to take a screenshot", screenShotTime,
248  
      "Average time to make integral image", iiTime,
249  
      "Capacity left in first core", percentRatioStrOneDigit(freeInCore()),
250  
      "Total CPU used", cpuTotal(),
251  
    );
252  
  }
253  
254  
  S cpuTotal() {
255  
    ret setFieldAndReturn(cpuTotal := percentRatioStrOneDigit((1-freeInCore())/numberOfCores()));
256  
  }
257  
258  
  double freeInCore() {
259  
    ret ratio(toSeconds(screenShotCountdownTotalSleepTime),
260  
      elapsedSeconds(loopStarted));
261  
  }
262  
263  
  replace jSection with jCenteredSection.  
264  
  {}
265  
  visualize {
266  
    imageSurface = new IIImageSurface;
267  
    setDoubleBuffered(imageSurface, true);
268  
    imageSurface.noAlpha = true;
269  
    
270  
    var screenSelectors = jRadioButtons(
271  
      countIteratorAsList(screenCount(),
272  
        i -> "Screen " + (i+1)));
273  
    selectRadioButton(screenSelectors, lookAtScreen);
274  
    onRadioButtonChange(screenSelectors, i -> { setField(lookAtScreen := i); });
275  
    
276  
    ret hsplit(northAndCenterWithMargin(
277  
      topControls = hgrid(
278  
        jSection("FPS", dm_calculatedCenteredLabel(() -> iround(fps))),
279  
        jSection("Compression", dm_centeredFieldLabel longTermCompressionScore()),
280  
        jSection("Probability", dm_centeredFieldLabel longTermCompressionProbability()),
281  
        jSection("CPU (" + numberOfCores() + ")", dm_centeredFieldLabel cpuTotal())
282  
      ),
283  
      tabs),
284  
      northAndCenterWithMargin(
285  
        topControls2 = /*jflowCenter*/ jPanel(new WrapLayout, listPlus(wideningListCast Component(buttonsInGroup(screenSelectors)),
286  
          dm_spinnerWithLabel gridRows("Rows", 1, 500),
287  
          dm_checkBox("Scale down", "scaleDownPreviewImage"),
288  
          dm_spinnerWithLabel previewPosterization("Posterize", 2, 256)
289  
        )),
290  
        jscroll_center(imageSurface)));
291  
  }
292  
  
293  
  BufferedImage lastScreenImage() { ret getVar(getVar(lastScreen)); }
294  
295  
  void adjustUIForPoppedOutWindow swing {
296  
    if (popDownButton == null) {
297  
      Window window = cast getWindow(dm_vis());
298  
299  
      var popBackInButton = findButton(window, "Pop Back In");
300  
      var parent = getParent(popBackInButton);
301  
      print(+parent);
302  
      
303  
      removeFromParent(parent); // hide controls
304  
      
305  
      popDownButton = jPopDownButton_noText(
306  
        "Pop Back In", r { dm_popInModule(me()) },
307  
        jCheckBoxMenuItem("Always On Top", isAlwaysOnTop(window),
308  
          rEnter dm_toggleAlwaysOnTop),
309  
      );
310  
      addControl(popDownButton);      
311  
    }
312  
  }
313  
  
314  
  public bool useErrorHandling() { false; }
315  
}

Author comment

Began life as a copy of #1033526

download  show line numbers  debug dex  old transpilations   

Travelled to 2 computer(s): bhatertpkbcr, mqqgnosmbjvj

No comments. add comment

Snippet ID: #1033576
Snippet name: Gazelle V, November Edition v1 [backup]
Eternal ID of this version: #1033576/1
Text MD5: 04269bda3866405fefd276d745379d46
Transpilation MD5: ca94348891839b8973794a9c26216301
Author: stefan
Category: javax / screen recognition
Type: JavaX source code (Dynamic Module)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2021-11-04 01:26:49
Source code size: 10570 bytes / 315 lines
Pitched / IR pitched: No / No
Views / Downloads: 132 / 199
Referenced in: [show references]