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

237
LINES

< > BotCompany Repo | #1033683 // Gazelle Screen Cam / Gazelle 22 Module

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

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

!7

!include early #1033506 // Compact Module Include Gazelle V

module GazelleScreenCam {
  !include early #1025212 // +Enabled without visualization
  
  int screenNr;
  int pixelRows = 128, colors = 8;
  S script, testScreenScript;
  bool animate = true;
  bool horizontalLayout; // flat layout
  
  transient ImageSurface isPosterized, isRegions, isTestScreen;
  transient new ScreenCamStream images;
  transient new BWIntegralImageStream integralImages;
  transient new SourceTriggeredStream<BWImage> scaledAndPosterizedImages;
  transient new DoubleFPSCounter fpsCounter;
  transient int fps;
  transient ScreenSelectorRadioButtons screenSelector;
  transient new RollingAverage remainingMSPerFrame;
  transient int remainingMS;
  
  transient new FunctionTimings<S> functionTimings;
  
  transient ReliableSingleThread rstRunScript = dm_rst(me(), r _runScript);
  
  transient JGazelleVScriptRunner scriptRunner;
  transient JGazelleVScriptRunner testScreenScriptRunner;
  
  transient Animation animation;
  
  transient BWImage_FastRegions mainScreenRegions;
  transient ImageSurface_HighlightRegion regionHighlighter;
  
  transient UIURLSystem uiURLs;
  S uiURL;

  start {
    dm_onFieldChange horizontalLayout(
      //r dm_revisualize // deh buggy
      r dm_reload
    );
    
    uiURLs = new UIURLSystem(me(), dm_fieldLiveValue uiURL());
    
    scriptRunner = new JGazelleVScriptRunner(dm_fieldLiveValue script(me()));
    testScreenScriptRunner = new JGazelleVScriptRunner(dm_fieldLiveValue testScreenScript(me()));

    images.directlyFeedInto(integralImages);
    
    integralImages.onNewElement(ii ->
      scaledAndPosterizedImages.newElement(
        posterizeBWImage_withMeta(colors,
          scaledBWImageFromBWIntegralImage_withMeta_height(pixelRows, ii))));
          
    integralImages.onNewElement(r {
      if (shouldRunScript()) rstRunScript.go();
    });
          
    scaledAndPosterizedImages.onNewElement(img -> {
      fpsCounter.inc();
      setField(fps := iround(fpsCounter!));
      isPosterized?.setImage_thisThread(img);
      floodFill(img);
    });
    
    // 20 Hz is enough for everyone
    dm_doEvery(1000/20, r {
      if (enabled) {
        screenSelector?.updateScreenCount();
        Timestamp deadline = tsNowPlusMS(1000/20);
        images.useScreen(screenNr);
        images.step();
        long remaining = deadline.minus(tsNow());
        remainingMSPerFrame.add(remaining);
        setField(remainingMS := iround(remainingMSPerFrame!));
      }
    });
  }
  
  ImageSurface stdImageSurface() {
    ret pixelatedImageSurface().setAutoZoomToDisplay(true).repaintInThread(false);
  }
  
  visualize {
    screenSelector = new ScreenSelectorRadioButtons(dm_fieldLiveValue screenNr());
    screenSelector.compactLayout(true);
    screenSelector.hideIfOnlyOne(true);
    screenSelector.screenLabel("");
    isPosterized = stdImageSurface();
    regionHighlighter = new ImageSurface_HighlightRegion(isPosterized);
    regionHighlighter.regionPainter(new RegionFillPainter);
    
    isRegions = stdImageSurface();
    isTestScreen = stdImageSurface();
    
    // when test screen is visible, do the animation
    awtEvery(isTestScreen, 1000/20, r stepAnimation);
    
    JTextArea taTimings = jTextArea_noUndo();
    awtEveryAndNow(taTimings, .5, r {
      setText(taTimings, renderFunctionTimings())
    });
    
    var jSpeedInfo = dm_transientCalculatedToolTip speedInfo_long(rightAlignLabel(dm_transientCalculatedLabel speedInfo()));
    
    // main visual
    
    var tabs = scrollingTabs(jTopOrLeftTabs(horizontalLayout,
      Posterized := withTools(isPosterized),
      Regions := jscroll_centered_borderless(isRegions),
      Script := scriptRunner.scriptAndResultPanel(),
      "Test Screen" := testScreenPanel(),
      Timings := withRightAlignedButtons(taTimings,
        "Reset" := r resetTimings)
    ));
    
    var vis = northAndCenter(
      withSideAndTopMargin(uiURLs.urlBar()),
      centerAndSouthOrEast(horizontalLayout,
        horizontalLayout ? withMargin(tabs) : withSideMargin(tabs),
        /*withMargin*/(borderlessScrollPane(jHigherScrollPane(
        jfullcenter(vstack(
          withLeftAndRightMargin(hstack(
            dm_rcheckBox enabled("Watch screen"),
            screenSelector.visualize(),
            jlabel(" in "),
            withLabelToTheRight("colors @ ", dm_spinner colors(2, 256)),
            //withLabelToTheRight("p", dm_spinner pixelRows(1, 500)),
            withLabelToTheRight("p", dm_powersOfTwoSpinner pixelRows(512)),
            , /* speed info can also go here */
          )),
          verticalStrut(2),
          withRightMargin(jSpeedInfo)
        ))))),
    ));
    setHorizontalMarginForAllButtons(vis, 4);
    ret vis;
  }
  
  S speedInfo() {
    ret "FPS " + fps + " idle " + remainingMS + " ms";
  }
  
  S speedInfo_long() {
    ret "Screen cam running at " + nFrames(fps) + "/second. " + n2(remainingMS) + " ms remaining per frame in first core.";
  }
  
  void floodFill(BWImage img) {
    BWImage_FastRegions ff = new(img);
    //ff.tolerance(0);
    ff.collectBounds();
    functionTimings.time("Regions", ff);
    mainScreenRegions = ff;
    regionHighlighter?.setRegions(ff);
    if (isRegions != null && isRegions.isShowing_quick()) {
      print("Showing regions image");
      isRegions.setImage_thisThread(ff.regionsImage());
    }
    setEnclosingTabTitle(isRegions, nRegions(ff.regionCount()));
  }
  
  bool useErrorHandling() { false; }
  
  S renderFunctionTimings() {
    ret lines(ciSorted(map(functionTimings!, (f, avg) ->
      firstToUpper(f) + ": " + n2(iround(nsToMicroseconds(avg!))) + " " + microSymbol() + "s (" + n2(iround(avg.n())) + ")")));
  }
  
  transient long _runScript_idx;

  void _runScript() {
    long n = integralImages.elementCount();
    if (n > _runScript_idx) {
      _runScript_idx = n;

      scriptRunner.parseAndRunOn(integralImages!);
    }
  }
  
  bool shouldRunScript() {
    ret isShowing(scriptRunner.scpScriptResult);
  }
  
  void stepAnimation {
    if (!animate) ret;
    if (animation == null) {
      animation = new AnimatedLine;
      animation.start();
    }
    animation.nextFrame();
    var img = whiteImage(animation.w, animation.h);
    animation.setGraphics(createGraphics(img));
    animation.paint();
    isTestScreen?.setImage(img);
    
    var ii = bwIntegralImage_withMeta(img);
    testScreenScriptRunner.parseAndRunOn(ii);
  }
  
  JComponent testScreenPanel() {
    ret centerAndSouthWithMargin(
      hsplit(
        northAndCenterWithMargin(centerAndEastWithMargin(
          jlabel("Input"), dm_fieldCheckBox animate()),
        jscroll_centered_borderless(isTestScreen)),
        
        northAndCenterWithMargin(centerAndEastWithMargin(
          jlabel("Output"), testScreenScriptRunner.lblScore),
        testScreenScriptRunner.scpScriptResult)
      ),
        
      testScreenScriptRunner.scriptInputField()
    );
  }
  
  L popDownItems() {
    ret ll(jCheckBoxMenuItem_dyn("Horizontal Layout",
      -> horizontalLayout,
      b -> setField(horizontalLayout := b)));
  }
  
  void unvisualize {} // don't zero transient component fields
  
  void resetTimings { functionTimings.reset(); }
  
  // add tool side bar to image surface
  JComponent withTools(ImageSurface is) {
    new ImageSurface_PositionToolTip(is);
    ret centerAndEastWithMargin(jscroll_centered_borderless(is), vstackWithSpacing(5,
      jbutton("A"),
      jbutton("B"),
      jbutton("C"),
    ));
  }
} // end of module

download  show line numbers  debug dex  old transpilations   

Travelled to 3 computer(s): bhatertpkbcr, mowyntqkapby, mqqgnosmbjvj

No comments. add comment

Snippet ID: #1033683
Snippet name: Gazelle Screen Cam / Gazelle 22 Module
Eternal ID of this version: #1033683/166
Text MD5: 6b008d8afc204c1d7348605ead6a093d
Transpilation MD5: 7bfcb690878f6f7c5551a6d2ec38b7ad
Author: stefan
Category: javax / gazelle v
Type: JavaX source code (Dynamic Module)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2022-01-07 04:50:18
Source code size: 7759 bytes / 237 lines
Pitched / IR pitched: No / No
Views / Downloads: 389 / 1936
Version history: 165 change(s)
Referenced in: [show references]