Feature: improve the application exit-button process (#214)
* Improve the application exit-button behaviour
This commit is contained in:
2
.idea/gradle.xml
generated
2
.idea/gradle.xml
generated
@@ -1,5 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
|
<component name="GradleMigrationSettings" migrationVersion="1" />
|
||||||
<component name="GradleSettings">
|
<component name="GradleSettings">
|
||||||
<option name="linkedExternalProjectsSettings">
|
<option name="linkedExternalProjectsSettings">
|
||||||
<GradleProjectSettings>
|
<GradleProjectSettings>
|
||||||
@@ -11,7 +12,6 @@
|
|||||||
</set>
|
</set>
|
||||||
</option>
|
</option>
|
||||||
<option name="resolveModulePerSourceSet" value="false" />
|
<option name="resolveModulePerSourceSet" value="false" />
|
||||||
<option name="useAutoImport" value="true" />
|
|
||||||
<option name="useQualifiedModuleNames" value="true" />
|
<option name="useQualifiedModuleNames" value="true" />
|
||||||
</GradleProjectSettings>
|
</GradleProjectSettings>
|
||||||
</option>
|
</option>
|
||||||
|
|||||||
@@ -135,247 +135,254 @@ public class Client {
|
|||||||
Thread thread_sender = new Thread(runnable_sender);
|
Thread thread_sender = new Thread(runnable_sender);
|
||||||
thread_sender.start();
|
thread_sender.start();
|
||||||
|
|
||||||
while (this.running == true) {
|
do {
|
||||||
this.renderingJob = null;
|
while (this.running == true) {
|
||||||
synchronized (this) {
|
this.renderingJob = null;
|
||||||
if (this.suspended) {
|
synchronized (this) {
|
||||||
this.gui.status("Client paused", true);
|
if (this.suspended) {
|
||||||
}
|
this.gui.status("Client paused", true);
|
||||||
while (this.suspended) {
|
|
||||||
wait();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
step = this.log.newCheckPoint();
|
|
||||||
try {
|
|
||||||
Calendar next_request = this.nextJobRequest();
|
|
||||||
if (next_request != null) {
|
|
||||||
// wait
|
|
||||||
Date now = new Date();
|
|
||||||
this.gui.status(String.format("Waiting until %tR before requesting job", next_request));
|
|
||||||
long wait = next_request.getTimeInMillis() - now.getTime();
|
|
||||||
if (wait < 0) {
|
|
||||||
// it means the client has to wait until the next day
|
|
||||||
wait += 24*3600*1000;
|
|
||||||
}
|
}
|
||||||
try {
|
while (this.suspended) {
|
||||||
Thread.sleep(wait);
|
wait();
|
||||||
}
|
|
||||||
catch (InterruptedException e3) {
|
|
||||||
|
|
||||||
}
|
|
||||||
catch (IllegalArgumentException e3) {
|
|
||||||
this.log.error("Client::run sleepA failed " + e3);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.gui.status("Requesting Job");
|
step = this.log.newCheckPoint();
|
||||||
this.renderingJob = this.server.requestJob();
|
try {
|
||||||
}
|
Calendar next_request = this.nextJobRequest();
|
||||||
catch (FermeExceptionNoRightToRender e) {
|
if (next_request != null) {
|
||||||
this.gui.error("User does not have enough right to render scene");
|
// wait
|
||||||
return -2;
|
Date now = new Date();
|
||||||
}
|
this.gui.status(String.format("Waiting until %tR before requesting job", next_request));
|
||||||
catch (FermeExceptionSessionDisabled e) {
|
long wait = next_request.getTimeInMillis() - now.getTime();
|
||||||
this.gui.error(Error.humanString(Error.Type.SESSION_DISABLED));
|
if (wait < 0) {
|
||||||
// should wait forever to actually display the message to the user
|
// it means the client has to wait until the next day
|
||||||
while (true) {
|
wait += 24 * 3600 * 1000;
|
||||||
try {
|
}
|
||||||
Thread.sleep(100000);
|
try {
|
||||||
}
|
Thread.sleep(wait);
|
||||||
catch (InterruptedException e1) {
|
}
|
||||||
}
|
catch (InterruptedException e3) {
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (FermeExceptionNoRendererAvailable e) {
|
catch (IllegalArgumentException e3) {
|
||||||
this.gui.error(Error.humanString(Error.Type.RENDERER_NOT_AVAILABLE));
|
this.log.error("Client::run sleepA failed " + e3);
|
||||||
// should wait forever to actually display the message to the user
|
|
||||||
while (true) {
|
|
||||||
try {
|
|
||||||
Thread.sleep(100000);
|
|
||||||
}
|
|
||||||
catch (InterruptedException e1) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (FermeExceptionNoSession e) {
|
|
||||||
this.log.debug("User has no session need to re-authenticate");
|
|
||||||
ret = this.server.getConfiguration();
|
|
||||||
if (ret != Error.Type.OK) {
|
|
||||||
this.renderingJob = null;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.startTime = new Date().getTime(); // reset start session time because the server did it
|
|
||||||
try {
|
|
||||||
Calendar next_request = this.nextJobRequest();
|
|
||||||
if (next_request != null) {
|
|
||||||
// wait
|
|
||||||
Date now = new Date();
|
|
||||||
this.gui.status(String.format("Waiting until %tR before requesting job", next_request));
|
|
||||||
try {
|
|
||||||
Thread.sleep(next_request.getTimeInMillis() - now.getTime());
|
|
||||||
}
|
|
||||||
catch (InterruptedException e3) {
|
|
||||||
|
|
||||||
}
|
|
||||||
catch (IllegalArgumentException e3) {
|
|
||||||
this.log.error("Client::run sleepB failed " + e3);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
this.gui.status("Requesting Job");
|
|
||||||
this.renderingJob = this.server.requestJob();
|
|
||||||
}
|
}
|
||||||
catch (FermeException e1) {
|
this.gui.status("Requesting Job");
|
||||||
|
this.renderingJob = this.server.requestJob();
|
||||||
|
}
|
||||||
|
catch (FermeExceptionNoRightToRender e) {
|
||||||
|
this.gui.error("User does not have enough right to render scene");
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
catch (FermeExceptionSessionDisabled e) {
|
||||||
|
this.gui.error(Error.humanString(Error.Type.SESSION_DISABLED));
|
||||||
|
// should wait forever to actually display the message to the user
|
||||||
|
while (true) {
|
||||||
|
try {
|
||||||
|
Thread.sleep(100000);
|
||||||
|
}
|
||||||
|
catch (InterruptedException e1) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (FermeExceptionNoRendererAvailable e) {
|
||||||
|
this.gui.error(Error.humanString(Error.Type.RENDERER_NOT_AVAILABLE));
|
||||||
|
// should wait forever to actually display the message to the user
|
||||||
|
while (true) {
|
||||||
|
try {
|
||||||
|
Thread.sleep(100000);
|
||||||
|
}
|
||||||
|
catch (InterruptedException e1) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (FermeExceptionNoSession e) {
|
||||||
|
this.log.debug("User has no session need to re-authenticate");
|
||||||
|
ret = this.server.getConfiguration();
|
||||||
|
if (ret != Error.Type.OK) {
|
||||||
this.renderingJob = null;
|
this.renderingJob = null;
|
||||||
}
|
}
|
||||||
}
|
else {
|
||||||
}
|
this.startTime = new Date().getTime(); // reset start session time because the server did it
|
||||||
catch (FermeServerDown e) {
|
try {
|
||||||
int wait = ThreadLocalRandom.current().nextInt(10, 30 + 1); // max is exclusive
|
Calendar next_request = this.nextJobRequest();
|
||||||
int time_sleep = 1000 * 60 * wait;
|
if (next_request != null) {
|
||||||
this.gui.status(String.format("Can not connect to server. Please check your connectivity. Will retry in %s minutes", wait));
|
// wait
|
||||||
try {
|
Date now = new Date();
|
||||||
Thread.sleep(time_sleep);
|
this.gui.status(String.format("Waiting until %tR before requesting job", next_request));
|
||||||
}
|
try {
|
||||||
catch (InterruptedException e1) {
|
Thread.sleep(next_request.getTimeInMillis() - now.getTime());
|
||||||
return -3;
|
}
|
||||||
}
|
catch (InterruptedException e3) {
|
||||||
continue; // go back to ask job
|
|
||||||
}
|
}
|
||||||
catch (FermeExceptionServerOverloaded e) {
|
catch (IllegalArgumentException e3) {
|
||||||
int wait = ThreadLocalRandom.current().nextInt(10, 30 + 1); // max is exclusive
|
this.log.error("Client::run sleepB failed " + e3);
|
||||||
int time_sleep = 1000 * 60 * wait;
|
}
|
||||||
this.gui.status(String.format("Server is overloaded and cannot give frame to render. Will retry in %s minutes", wait));
|
}
|
||||||
try {
|
this.gui.status("Requesting Job");
|
||||||
Thread.sleep(time_sleep);
|
this.renderingJob = this.server.requestJob();
|
||||||
}
|
}
|
||||||
catch (InterruptedException e1) {
|
catch (FermeException e1) {
|
||||||
return -3;
|
this.renderingJob = null;
|
||||||
}
|
}
|
||||||
continue; // go back to ask job
|
|
||||||
}
|
|
||||||
catch (FermeExceptionServerInMaintenance e) {
|
|
||||||
int wait = ThreadLocalRandom.current().nextInt(20, 30 + 1); // max is exclusive
|
|
||||||
int time_sleep = 1000 * 60 * wait;
|
|
||||||
this.gui.status(String.format("Server is in maintenance and cannot give frame to render. Will retry in %s minutes", wait));
|
|
||||||
try {
|
|
||||||
Thread.sleep(time_sleep);
|
|
||||||
}
|
|
||||||
catch (InterruptedException e1) {
|
|
||||||
return -3;
|
|
||||||
}
|
|
||||||
continue; // go back to ask job
|
|
||||||
}
|
|
||||||
catch (FermeExceptionBadResponseFromServer e) {
|
|
||||||
int wait = ThreadLocalRandom.current().nextInt(15, 30 + 1); // max is exclusive
|
|
||||||
int time_sleep = 1000 * 60 * wait;
|
|
||||||
this.gui.status(String.format("Bad answer from server. Will retry in %s minutes", wait));
|
|
||||||
try {
|
|
||||||
Thread.sleep(time_sleep);
|
|
||||||
}
|
|
||||||
catch (InterruptedException e1) {
|
|
||||||
return -3;
|
|
||||||
}
|
|
||||||
continue; // go back to ask job
|
|
||||||
}
|
|
||||||
catch (FermeException e) {
|
|
||||||
this.gui.error("Client::run exception requestJob (1) " + e.getMessage());
|
|
||||||
StringWriter sw = new StringWriter();
|
|
||||||
PrintWriter pw = new PrintWriter(sw);
|
|
||||||
e.printStackTrace(pw);
|
|
||||||
this.log.debug("Client::run exception " + e + " stacktrace: " + sw.toString());
|
|
||||||
this.sendError(step);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.renderingJob == null) { // no job
|
|
||||||
int wait = ThreadLocalRandom.current().nextInt(10, 30 + 1); // max is exclusive
|
|
||||||
int time_sleep = 1000 * 60 * wait;
|
|
||||||
Date wakeup_time = new Date(new Date().getTime() + time_sleep);
|
|
||||||
this.gui.status(String.format("No job available. Sleeping for %d minutes (will wake up at %tR)", wait, wakeup_time));
|
|
||||||
this.suspended = true;
|
|
||||||
int time_slept = 0;
|
|
||||||
while (time_slept < time_sleep && this.running == true) {
|
|
||||||
try {
|
|
||||||
Thread.sleep(250);
|
|
||||||
}
|
}
|
||||||
catch (InterruptedException e) {
|
}
|
||||||
|
catch (FermeServerDown e) {
|
||||||
|
int wait = ThreadLocalRandom.current().nextInt(10, 30 + 1); // max is exclusive
|
||||||
|
int time_sleep = 1000 * 60 * wait;
|
||||||
|
this.gui.status(String.format("Can not connect to server. Please check your connectivity. Will retry in %s minutes", wait));
|
||||||
|
try {
|
||||||
|
Thread.sleep(time_sleep);
|
||||||
|
}
|
||||||
|
catch (InterruptedException e1) {
|
||||||
return -3;
|
return -3;
|
||||||
}
|
}
|
||||||
time_slept += 250;
|
continue; // go back to ask job
|
||||||
|
}
|
||||||
|
catch (FermeExceptionServerOverloaded e) {
|
||||||
|
int wait = ThreadLocalRandom.current().nextInt(10, 30 + 1); // max is exclusive
|
||||||
|
int time_sleep = 1000 * 60 * wait;
|
||||||
|
this.gui.status(String.format("Server is overloaded and cannot give frame to render. Will retry in %s minutes", wait));
|
||||||
|
try {
|
||||||
|
Thread.sleep(time_sleep);
|
||||||
|
}
|
||||||
|
catch (InterruptedException e1) {
|
||||||
|
return -3;
|
||||||
|
}
|
||||||
|
continue; // go back to ask job
|
||||||
|
}
|
||||||
|
catch (FermeExceptionServerInMaintenance e) {
|
||||||
|
int wait = ThreadLocalRandom.current().nextInt(20, 30 + 1); // max is exclusive
|
||||||
|
int time_sleep = 1000 * 60 * wait;
|
||||||
|
this.gui.status(String.format("Server is in maintenance and cannot give frame to render. Will retry in %s minutes", wait));
|
||||||
|
try {
|
||||||
|
Thread.sleep(time_sleep);
|
||||||
|
}
|
||||||
|
catch (InterruptedException e1) {
|
||||||
|
return -3;
|
||||||
|
}
|
||||||
|
continue; // go back to ask job
|
||||||
|
}
|
||||||
|
catch (FermeExceptionBadResponseFromServer e) {
|
||||||
|
int wait = ThreadLocalRandom.current().nextInt(15, 30 + 1); // max is exclusive
|
||||||
|
int time_sleep = 1000 * 60 * wait;
|
||||||
|
this.gui.status(String.format("Bad answer from server. Will retry in %s minutes", wait));
|
||||||
|
try {
|
||||||
|
Thread.sleep(time_sleep);
|
||||||
|
}
|
||||||
|
catch (InterruptedException e1) {
|
||||||
|
return -3;
|
||||||
|
}
|
||||||
|
continue; // go back to ask job
|
||||||
|
}
|
||||||
|
catch (FermeException e) {
|
||||||
|
this.gui.error("Client::run exception requestJob (1) " + e.getMessage());
|
||||||
|
StringWriter sw = new StringWriter();
|
||||||
|
PrintWriter pw = new PrintWriter(sw);
|
||||||
|
e.printStackTrace(pw);
|
||||||
|
this.log.debug("Client::run exception " + e + " stacktrace: " + sw.toString());
|
||||||
|
this.sendError(step);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.renderingJob == null) { // no job
|
||||||
|
int wait = ThreadLocalRandom.current().nextInt(10, 30 + 1); // max is exclusive
|
||||||
|
int time_sleep = 1000 * 60 * wait;
|
||||||
|
Date wakeup_time = new Date(new Date().getTime() + time_sleep);
|
||||||
|
this.gui.status(String.format("No job available. Sleeping for %d minutes (will wake up at %tR)", wait, wakeup_time));
|
||||||
|
this.suspended = true;
|
||||||
|
int time_slept = 0;
|
||||||
|
while (time_slept < time_sleep && this.running == true) {
|
||||||
|
try {
|
||||||
|
Thread.sleep(250);
|
||||||
|
}
|
||||||
|
catch (InterruptedException e) {
|
||||||
|
return -3;
|
||||||
|
}
|
||||||
|
time_slept += 250;
|
||||||
|
}
|
||||||
|
this.suspended = false;
|
||||||
|
continue; // go back to ask job
|
||||||
|
}
|
||||||
|
|
||||||
|
this.log.debug("Got work to do id: " + this.renderingJob.getId() + " frame: " + this.renderingJob.getFrameNumber());
|
||||||
|
|
||||||
|
ret = this.work(this.renderingJob);
|
||||||
|
if (ret == Error.Type.RENDERER_KILLED) {
|
||||||
|
this.log.removeCheckPoint(step);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret == Error.Type.NO_SPACE_LEFT_ON_DEVICE) {
|
||||||
|
Job frame_to_reset = this.renderingJob; // copy it because the sendError will take ~5min to execute
|
||||||
|
this.renderingJob = null;
|
||||||
|
this.gui.error(Error.humanString(ret));
|
||||||
|
this.sendError(step, frame_to_reset, ret);
|
||||||
|
this.log.removeCheckPoint(step);
|
||||||
|
return -50;
|
||||||
}
|
}
|
||||||
this.suspended = false;
|
|
||||||
continue; // go back to ask job
|
|
||||||
}
|
|
||||||
|
|
||||||
this.log.debug("Got work to do id: " + this.renderingJob.getId() + " frame: " + this.renderingJob.getFrameNumber());
|
|
||||||
|
|
||||||
ret = this.work(this.renderingJob);
|
|
||||||
if (ret == Error.Type.RENDERER_KILLED) {
|
|
||||||
this.log.removeCheckPoint(step);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ret == Error.Type.NO_SPACE_LEFT_ON_DEVICE) {
|
|
||||||
Job frame_to_reset = this.renderingJob; // copy it because the sendError will take ~5min to execute
|
|
||||||
this.renderingJob = null;
|
|
||||||
this.gui.error(Error.humanString(ret));
|
|
||||||
this.sendError(step, frame_to_reset, ret);
|
|
||||||
this.log.removeCheckPoint(step);
|
|
||||||
return -50;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ret != Error.Type.OK) {
|
|
||||||
Job frame_to_reset = this.renderingJob; // copy it because the sendError will take ~5min to execute
|
|
||||||
this.renderingJob = null;
|
|
||||||
this.gui.error(Error.humanString(ret));
|
|
||||||
this.sendError(step, frame_to_reset, ret);
|
|
||||||
this.log.removeCheckPoint(step);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.renderingJob.isSynchronousUpload() == true) { // power or compute_method job, need to upload right away
|
|
||||||
this.gui.status(String.format("Uploading frame (%.2fMB)",
|
|
||||||
(this.renderingJob.getOutputImageSize() / 1024.0 / 1024.0)
|
|
||||||
));
|
|
||||||
|
|
||||||
ret = confirmJob(this.renderingJob);
|
|
||||||
if (ret != Error.Type.OK) {
|
if (ret != Error.Type.OK) {
|
||||||
gui.error("Client::run problem with confirmJob (returned " + ret + ")");
|
Job frame_to_reset = this.renderingJob; // copy it because the sendError will take ~5min to execute
|
||||||
sendError(step);
|
this.renderingJob = null;
|
||||||
|
this.gui.error(Error.humanString(ret));
|
||||||
|
this.sendError(step, frame_to_reset, ret);
|
||||||
|
this.log.removeCheckPoint(step);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.gui.status(String.format("Queuing frame for upload (%.2fMB)",
|
|
||||||
(this.renderingJob.getOutputImageSize() / 1024.0 / 1024.0)
|
|
||||||
));
|
|
||||||
|
|
||||||
this.jobsToValidate.add(this.renderingJob);
|
if (this.renderingJob.isSynchronousUpload() == true) { // power or compute_method job, need to upload right away
|
||||||
|
this.gui.status(String.format("Uploading frame (%.2fMB)",
|
||||||
|
(this.renderingJob.getOutputImageSize() / 1024.0 / 1024.0)
|
||||||
|
));
|
||||||
|
|
||||||
|
ret = confirmJob(this.renderingJob);
|
||||||
|
if (ret != Error.Type.OK) {
|
||||||
|
gui.error("Client::run problem with confirmJob (returned " + ret + ")");
|
||||||
|
sendError(step);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.gui.status(String.format("Queuing frame for upload (%.2fMB)",
|
||||||
|
(this.renderingJob.getOutputImageSize() / 1024.0 / 1024.0)
|
||||||
|
));
|
||||||
|
|
||||||
|
this.jobsToValidate.add(this.renderingJob);
|
||||||
|
|
||||||
|
this.uploadQueueSize++;
|
||||||
|
this.uploadQueueVolume += this.renderingJob.getOutputImageSize();
|
||||||
|
this.gui.displayUploadQueueStats(uploadQueueSize, uploadQueueVolume);
|
||||||
|
|
||||||
|
this.renderingJob = null;
|
||||||
|
}
|
||||||
|
|
||||||
this.uploadQueueSize++;
|
while (this.shouldWaitBeforeRender() == true) {
|
||||||
this.uploadQueueVolume += this.renderingJob.getOutputImageSize();
|
try {
|
||||||
this.gui.displayUploadQueueStats(uploadQueueSize, uploadQueueVolume);
|
Thread.sleep(4000); // wait a little bit
|
||||||
|
this.gui.status("Sending frames. Please wait");
|
||||||
this.renderingJob = null;
|
}
|
||||||
|
catch (InterruptedException e3) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.log.removeCheckPoint(step);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (this.shouldWaitBeforeRender() == true) {
|
// If we reach this point is bc the main loop (the one that controls all the workflow) has exited
|
||||||
try {
|
// due to user requesting to exit the App and we are just waiting for the upload queue to empty
|
||||||
Thread.sleep(4000); // wait a little bit
|
// If the user cancels the exit, then this.running will be true and the main loop will take
|
||||||
this.gui.status("Sending frames. Please wait");
|
// control again
|
||||||
}
|
|
||||||
catch (InterruptedException e3) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.log.removeCheckPoint(step);
|
|
||||||
}
|
|
||||||
|
|
||||||
// not running but maybe still sending frame
|
|
||||||
while (this.jobsToValidate.isEmpty() == false) {
|
|
||||||
try {
|
try {
|
||||||
Thread.sleep(2300); // wait a little bit
|
Thread.sleep(2300); // wait a little bit
|
||||||
|
this.gui.status("Uploading rendered frames before exiting. Please wait");
|
||||||
}
|
}
|
||||||
catch (InterruptedException e3) {
|
catch (InterruptedException e3) {
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
// This loop will remain valid until all the background uploads have
|
||||||
|
// finished (unless the stop() method has been triggered)
|
||||||
|
} while (this.uploadQueueSize > 0);
|
||||||
}
|
}
|
||||||
catch (Exception e1) {
|
catch (Exception e1) {
|
||||||
// no exception should be raised in the actual launcher (applet or standalone)
|
// no exception should be raised in the actual launcher (applet or standalone)
|
||||||
@@ -532,7 +539,6 @@ public class Client {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @return the date of the next request, or null if there is not delay (null <=> now)
|
* @return the date of the next request, or null if there is not delay (null <=> now)
|
||||||
*/
|
*/
|
||||||
public Calendar nextJobRequest() {
|
public Calendar nextJobRequest() {
|
||||||
@@ -615,7 +621,8 @@ public class Client {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Observer removeSceneDirectoryOnceRenderHasStartedObserver = new Observer() {
|
Observer removeSceneDirectoryOnceRenderHasStartedObserver = new Observer() {
|
||||||
@Override public void update(Observable observable, Object o) {
|
@Override
|
||||||
|
public void update(Observable observable, Object o) {
|
||||||
// only remove the .blend since it's most important data
|
// only remove the .blend since it's most important data
|
||||||
// and it's the only file we are sure will not be needed anymore
|
// and it's the only file we are sure will not be needed anymore
|
||||||
scene_file.delete();
|
scene_file.delete();
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ import javax.swing.BoxLayout;
|
|||||||
import javax.swing.ImageIcon;
|
import javax.swing.ImageIcon;
|
||||||
import javax.swing.JButton;
|
import javax.swing.JButton;
|
||||||
import javax.swing.JLabel;
|
import javax.swing.JLabel;
|
||||||
|
import javax.swing.JOptionPane;
|
||||||
import javax.swing.JPanel;
|
import javax.swing.JPanel;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
import javax.swing.Spring;
|
import javax.swing.Spring;
|
||||||
@@ -230,7 +231,7 @@ public class Working implements Activity {
|
|||||||
JButton blockJob = new JButton("Block this project");
|
JButton blockJob = new JButton("Block this project");
|
||||||
blockJob.addActionListener(new blockJobAction());
|
blockJob.addActionListener(new blockJobAction());
|
||||||
|
|
||||||
exitAfterFrame = new JButton("Exit after this frame");
|
exitAfterFrame = new JButton("Exit");
|
||||||
exitAfterFrame.addActionListener(new ExitAfterAction());
|
exitAfterFrame.addActionListener(new ExitAfterAction());
|
||||||
|
|
||||||
buttonsPanel.add(settingsButton);
|
buttonsPanel.add(settingsButton);
|
||||||
@@ -315,6 +316,22 @@ public class Working implements Activity {
|
|||||||
(queueSize > 0 ? String.format(" (%.2fMB) ", (queueVolume / 1024.0 / 1024.0)) : ""),
|
(queueSize > 0 ? String.format(" (%.2fMB) ", (queueVolume / 1024.0 / 1024.0)) : ""),
|
||||||
(queueSize == this.parent.getConfiguration().getMaxUploadingJob() ? "- Queue full!" : "")
|
(queueSize == this.parent.getConfiguration().getMaxUploadingJob() ? "- Queue full!" : "")
|
||||||
));
|
));
|
||||||
|
|
||||||
|
// If the user has requested to exit, then we need to update the JButton with the queue size
|
||||||
|
if (this.exitAfterFrame.getText().startsWith("Cancel")) {
|
||||||
|
Client client = parent.getClient();
|
||||||
|
|
||||||
|
if (client != null) {
|
||||||
|
if (client.isRunning()) {
|
||||||
|
queueSize++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
exitAfterFrame.setText(String.format("Cancel exit (%s frame%s to go)",
|
||||||
|
queueSize,
|
||||||
|
(queueSize > 1 ? "s" : ""))
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateTime() {
|
public void updateTime() {
|
||||||
@@ -475,11 +492,39 @@ public class Working implements Activity {
|
|||||||
Client client = parent.getClient();
|
Client client = parent.getClient();
|
||||||
if (client != null) {
|
if (client != null) {
|
||||||
if (client.isRunning()) {
|
if (client.isRunning()) {
|
||||||
exitAfterFrame.setText("Cancel exit");
|
String[] exitJobOptions = {"Exit after current Jobs", "Exit Immediately", "Do Nothing"};
|
||||||
client.askForStop();
|
int jobsQueueSize = client.getUploadQueueSize() + (client.isRunning() ? 1 : 0);
|
||||||
|
|
||||||
|
int userDecision = JOptionPane.showOptionDialog(
|
||||||
|
null,
|
||||||
|
String.format("<html>You have <strong>%d frame%s</strong> being uploaded or rendered. Do you want to finish the jobs or exit now?.\n\n",
|
||||||
|
jobsQueueSize , // Add the current frame to the total count ONLY if the client is running
|
||||||
|
(jobsQueueSize > 1 ? "s" : ""),
|
||||||
|
(jobsQueueSize > 1 ? (jobsQueueSize + " ") : ""),
|
||||||
|
(jobsQueueSize > 1 ? "s" : "")
|
||||||
|
),
|
||||||
|
"Exit Now or Later",
|
||||||
|
JOptionPane.DEFAULT_OPTION,
|
||||||
|
JOptionPane.QUESTION_MESSAGE,
|
||||||
|
null,
|
||||||
|
exitJobOptions,
|
||||||
|
exitJobOptions[2]); // Make the "Do nothing" button the default one to avoid mistakes
|
||||||
|
|
||||||
|
if (userDecision == 0) {
|
||||||
|
exitAfterFrame.setText(String.format("Cancel exit (%s frame%s to go)",
|
||||||
|
jobsQueueSize,
|
||||||
|
(jobsQueueSize > 1 ? "s" : ""))
|
||||||
|
);
|
||||||
|
|
||||||
|
client.askForStop();
|
||||||
|
}
|
||||||
|
else if (userDecision == 1) {
|
||||||
|
client.stop();
|
||||||
|
System.exit(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
exitAfterFrame.setText("Exit after this frame");
|
exitAfterFrame.setText("Exit");
|
||||||
client.cancelStop();
|
client.cancelStop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -498,5 +543,4 @@ public class Working implements Activity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user