The text UI gets quite messy during the render process, as it takes at least one extra line of the screen per second. This PR fixes that issue and also shows an ASCII bar to show the render progress.
212 lines
6.5 KiB
Java
212 lines
6.5 KiB
Java
/*
|
|
* Copyright (C) 2010-2014 Laurent CLOUET
|
|
* Author Laurent CLOUET <laurent.clouet@nopnop.net>
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; version 2
|
|
* of the License.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*/
|
|
|
|
package com.sheepit.client.standalone;
|
|
|
|
import com.sheepit.client.Client;
|
|
import com.sheepit.client.Gui;
|
|
import com.sheepit.client.Log;
|
|
import com.sheepit.client.Stats;
|
|
import com.sheepit.client.standalone.text.CLIInputActionHandler;
|
|
import com.sheepit.client.standalone.text.CLIInputObserver;
|
|
|
|
import sun.misc.Signal;
|
|
import sun.misc.SignalHandler;
|
|
|
|
import java.text.DateFormat;
|
|
import java.text.SimpleDateFormat;
|
|
import java.util.Collections;
|
|
import java.util.Date;
|
|
|
|
public class GuiText implements Gui {
|
|
public static final String type = "text";
|
|
|
|
private int framesRendered;
|
|
|
|
private int sigIntCount = 0;
|
|
private Log log;
|
|
private DateFormat df;
|
|
private String eta;
|
|
|
|
private Client client;
|
|
|
|
public GuiText() {
|
|
this.framesRendered = 0;
|
|
this.log = Log.getInstance(null);
|
|
this.df = new SimpleDateFormat("MMM dd HH:mm:ss");
|
|
this.eta = "";
|
|
}
|
|
|
|
@Override public void start() {
|
|
if (client != null) {
|
|
|
|
CLIInputObserver cli_input_observer = new CLIInputObserver(client);
|
|
cli_input_observer.addListener(new CLIInputActionHandler());
|
|
Thread cli_input_observer_thread = new Thread(cli_input_observer);
|
|
cli_input_observer_thread.start();
|
|
|
|
Signal.handle(new Signal("INT"), new SignalHandler() {
|
|
@Override public void handle(Signal signal) {
|
|
sigIntCount++;
|
|
|
|
if (sigIntCount == 4) {
|
|
// This is only for ugly issues that might occur
|
|
System.out.println("WARNING: Hitting Ctrl-C again will force close the application.");
|
|
}
|
|
else if (sigIntCount == 5) {
|
|
Signal.raise(new Signal("INT"));
|
|
Runtime.getRuntime().halt(0);
|
|
}
|
|
else if (client.isRunning() && client.isSuspended() == false) {
|
|
client.askForStop();
|
|
System.out.println("Will exit after current frame... Press Ctrl+C again to exit now.");
|
|
}
|
|
else {
|
|
client.stop();
|
|
GuiText.this.stop();
|
|
}
|
|
}
|
|
});
|
|
|
|
client.run();
|
|
client.stop();
|
|
}
|
|
}
|
|
|
|
@Override public void stop() {
|
|
Runtime.getRuntime().halt(0);
|
|
}
|
|
|
|
@Override public void updateTrayIcon(Integer percentage) {
|
|
}
|
|
|
|
@Override public void status(String msg_) {
|
|
status(msg_, false);
|
|
}
|
|
|
|
@Override public void status(String msg_, boolean overwriteSuspendedMsg) {
|
|
log.debug("GUI " + msg_);
|
|
|
|
if (client != null && client.isSuspended()) {
|
|
if (overwriteSuspendedMsg) {
|
|
System.out.println(String.format("%s %s", this.df.format(new Date()), msg_));
|
|
}
|
|
}
|
|
else {
|
|
System.out.println(String.format("%s %s", this.df.format(new Date()), msg_));
|
|
}
|
|
}
|
|
|
|
@Override public void status(String msg, int progress) {
|
|
this.status(msg, progress, 0);
|
|
}
|
|
|
|
@Override public void status(String msg, int progress, long size) {
|
|
System.out.print("\r");
|
|
System.out.print(String.format("%s %s", this.df.format(new Date()), showProgress(msg, progress, size)));
|
|
}
|
|
|
|
@Override public void error(String err_) {
|
|
System.out.println(String.format("ERROR: %s %s", this.df.format(new Date()), err_));
|
|
log.error("Error " + err_);
|
|
}
|
|
|
|
@Override public void AddFrameRendered() {
|
|
this.framesRendered += 1;
|
|
System.out.println(String.format("%s Frames rendered: %d", this.df.format(new Date()), this.framesRendered));
|
|
}
|
|
|
|
@Override public void displayStats(Stats stats) {
|
|
System.out.println(String.format("%s Frames remaining: %d", this.df.format(new Date()), stats.getRemainingFrame()));
|
|
System.out.println(String.format("%s Credits earned: %d", this.df.format(new Date()), stats.getCreditsEarnedDuringSession()));
|
|
}
|
|
|
|
@Override public void displayUploadQueueStats(int queueSize, long queueVolume) {
|
|
// No need to check if the queue is not empty to show the volume bc this line is always shown at the end
|
|
// of the render process in text GUI (unless an error occurred, where the file is uploaded synchronously)
|
|
System.out.println(String.format("%s Queued uploads: %d (%.2fMB)", this.df.format(new Date()), queueSize, (queueVolume / 1024.0 / 1024.0)));
|
|
}
|
|
|
|
@Override public void setRenderingProjectName(String name_) {
|
|
if (name_ != null && name_.isEmpty() == false) {
|
|
System.out.println(String.format("%s Rendering project \"%s\"", this.df.format(new Date()), name_));
|
|
}
|
|
}
|
|
|
|
@Override public void setRemainingTime(String time_) {
|
|
this.eta = time_;
|
|
}
|
|
|
|
@Override public void setRenderingTime(String time_) {
|
|
System.out.println(String.format("%s Rendering %s", this.df.format(new Date()), time_));
|
|
}
|
|
|
|
@Override public void setClient(Client cli) {
|
|
client = cli;
|
|
}
|
|
|
|
@Override public void setComputeMethod(String computeMethod) {
|
|
System.out.println(String.format("%s Compute method: %s", this.df.format(new Date()), computeMethod));
|
|
}
|
|
|
|
@Override public Client getClient() {
|
|
return client;
|
|
}
|
|
|
|
@Override public void successfulAuthenticationEvent(String publickey) {
|
|
|
|
}
|
|
|
|
private String showProgress(String message, int progress, long size) {
|
|
StringBuilder progressBar = new StringBuilder(140);
|
|
|
|
if (progress < 100) {
|
|
progressBar
|
|
.append(message)
|
|
.append(" ")
|
|
.append(String.join("", Collections.nCopies(progress == 0 ? 2 : 2 - (int) (Math.log10(progress)), " ")))
|
|
.append(String.format("%d%% [", progress))
|
|
.append(String.join("", Collections.nCopies((int)(progress/5), "=")))
|
|
.append('>')
|
|
.append(String.join("", Collections.nCopies(20 - (int)(progress / 5), " ")))
|
|
.append(']');
|
|
|
|
if (size > 0) {
|
|
progressBar.append(String.format(" %dMB", (size / 1024 / 1024)));
|
|
}
|
|
|
|
if (!this.eta.equals("")) {
|
|
progressBar.append(String.format(" ETA %s", this.eta));
|
|
}
|
|
|
|
progressBar.append(String.join("", Collections.nCopies(60 - progressBar.length(), " ")));
|
|
}
|
|
// If progress has reached 100%
|
|
else {
|
|
progressBar
|
|
.append(message)
|
|
.append(" done")
|
|
.append(String.join("", Collections.nCopies(60 - progressBar.length(), " ")))
|
|
.append("\n");
|
|
}
|
|
|
|
return progressBar.toString();
|
|
}
|
|
}
|