srecord noeq G22ChallengePanel(G22Challenge challenge) extends HasChangeListeners is Swingable { settableWithChange long randomSeed = 1; //randomUnsignedInt(); //transient JPanel imagesPanel = jline(); transient DynamicHStack imagesPanel; transient L entries = syncL(); transient JComponent imagesSection; transient GazelleV_LeftArrowScript.Script parsedScript; settableWithChange Set solutionTypes = syncSet(); transient settable new G22Utils g22utils; settable double timeoutPerImage = 10.0; settable int imagesToPaint = 3; settable int interval = 100; settable int imageDisplaySize = 100; settable Color imageBorderColor1 = Color.green; settable Color imageBorderColor2 = Color.red; settable int imageBorderSize = 1; visualize { imagesPanel = (DynamicHStack) dynamicHStack().spacing(20); awtCalcEvery(imagesPanel, interval, r _paintAnImage); ret withCenteredBoldTitle(str(challenge), withTopMargin(jvsplit( northAndCenterWithMargin( centerAndEastWithMargin( centeredLiveValueLabel( liveValue_hasChangeListeners(this, -> "Looking for: " + solutionTypeDesc())), swing(-> JPopDownButton(menu -> menu.add(jMenuItem("Random seed: " + n2(randomSeed))))) ), imagesSection = jCenteredRaisedSection("Images", jBorderlessHigherScrollPane(jfullcenter(imagesPanel))), /*jRightAlignedLine( withLabel("Random seed:", liveValueLabel(liveValue_hasChangeListeners(this, -> randomSeed)))),*/ ), jCenteredSection("Analysis", jTodo() ) ))); } void _paintAnImage { if (l(entries) >= imagesToPaint) ret; int index = l(entries)+1; Entry entry = new(index, (int) (randomSeed+index-1)); entries.add(entry); try { if (parsedScript == null) { var parser = g22utils.leftArrowParser(); parsedScript = parser.parse(challenge.code); } new VarContext ctx; var result = evalWithTimeout(timeoutPerImage, -> { temp tempSetRandomSeed((int) entry.seed); ret parsedScript.get(ctx); }); if (result.isA()) { var returnedObject = result.a(); if (returnedObject instanceof MakesBufferedImage || returnedObject instanceof Image) returnedObject = toBufferedImage(returnedObject); if (returnedObject cast BufferedImage) { entry.solution(ctx.get("solution")); updateSolutionType(entry.solution); addImage(entry, returnedObject); } else { addImage(entry, null, jcenteredlabel("Script did not return an image but instead " + aOrAn(className(returnedObject)))); } } else { addImage(entry, null, jcenteredlabel("Script timed out after " + nSeconds(iceil(timeoutPerImage)))); } } catch print e { entry.error(e); addImage(entry, null, jError(e)); } finally { entry.calculating(false); } } void addImage(Entry entry, BufferedImage image, JComponent component) { entry.image(image).component(component); addAndRevalidate(imagesPanel, component); setSectionTitle(imagesSection, firstToUpper(nImages(entries)) + " calculated"); } void addImage(Entry entry, BufferedImage image) { entry.image(image); addImage(entry, image, imageToComponent(entry)); } JComponent imageToComponent(Entry entry) { var image = entry.image; // var is = g22utils.stdImageSurface(image); // jFixedSize(image.getWidth(), image.getHeight(), is); // ret is; double scale = calcFitScale(image, imageDisplaySize); var image2 = scaleImageWithOp(image, scale, AffineTransformOp.TYPE_NEAREST_NEIGHBOR); for (color : ll(imageBorderColor1, imageBorderColor2)) image2 = addBorderToImage(image2, color, imageBorderSize); S toolTip = "Image " + n2(entry.index) + " of " + challenge + " (seed " + n2(entry.seed) + ", " + image.getWidth() + "*" + image.getHeight() + " px)"; JButton b = withToolTip(toolTip, jimageButton(image2)); setMargin(10, b); ret b; } class Entry { int index; // index in sequence starting with 1 long seed; // seed for randomizer settable BufferedImage image; settable Throwable error; settable O solution; settable bool calculating = true; settable JComponent component; *(int *index, long *seed) {} } void updateSolutionType(O solution) { Class c = _getClass(solution); if (solutionTypes.add(c)) change(); } S solutionTypeDesc() { LS types = map solutionTypeDesc(solutionTypes); ret textOut_or(types, "Calculating..."); } S solutionTypeDesc(Class c) { if (c == null) ret "no solution given"; if (c == Rect) ret "a rectangular area in the image"; ret aOrAn(shortClassName(c)); } }