!7 cmodule PipelinedRecognizer > DynImageSurface { transient ChessOCR_Pipeline activePipeline; transient JTable tblBoardsFound; transient ChessPieceRecognizer pieceRecognizer; transient ReliableSingleThread rst = dm_rst(module(), r newRecognition); transient S status; start { if (!hasImage()) setImage(whiteImage(100)); onNewImage = rst; rst.trigger(); doEvery(1.0, r checkDone); } void checkDone { if (activePipeline == null || activePipeline.idle()) setField(status := "Idle"); } void newRecognition { setField(status := "Recognizing..."); dispose activePipeline; if (!hasImage()) ret; new ChessOCR_Pipeline pipeline; pipeline.inputImage = getImage(); if (pieceRecognizer == null) pieceRecognizer = chessOCR_pieceRecognizer(); pipeline.pieceRecognizer = pieceRecognizer; pipeline.boardsFound.onChange.add(r updateTable); activePipeline = pipeline; pipeline.addSegmenter(parameterizedSegmenterFromAGIBlue("GingerGM fullscreen find chess board #1")); } void updateTable { dataToTable(tblBoardsFound, sortedByMapElementDesc Score(map(activePipeline.boardsFound.byFEN, (fen, data) -> litorderedmap("Score" := formatDouble(data.bestScore, 2), "FEN" := fen, "Position" := strOrNull(data.bestPosition))))); } visual centerAndSouthWithMargins( jvsplit(super, jCenteredSection("Boards found", tblBoardsFound = sexyTable())), dm_label status()); }