/*
Copyright (c) 2015 Wolfgang Imig
This file is part of the library "JOA Issue Tracker for Microsoft Outlook".
This file must be used according to the terms of
MIT License, http://opensource.org/licenses/MIT
*/
package com.wilutions.itol.db;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.util.Duration;
public class ProgressCallbackImpl implements ProgressCallback {
private final ProgressCallback parent;
protected final String name;
protected volatile String[] params;
protected volatile double total = 1.0;
protected volatile double ratio = 1.0;
protected volatile double current;
protected volatile Thread lastThread = Thread.currentThread();
protected volatile boolean cancelled = false;
protected volatile boolean finished = false;
protected Timeline fakeProgressTimer;
public ProgressCallbackImpl() {
this(null, "");
}
public ProgressCallbackImpl(String name) {
this(null, name);
}
public ProgressCallbackImpl(ProgressCallback parent, String name) {
// System.out.println(name + " start");
this.parent = parent;
this.name = name;
if (parent != null) {
parent.setParams(new String[0]);
}
}
@Override
public void setParams(String... params) {
this.params = params;
if (parent != null) {
List<String> paramList = new ArrayList<String>(Arrays.asList(params));
if (name != null && name.length() != 0) {
paramList.add(0, name);
}
String[] parentParams = paramList.toArray(new String[paramList.size()]);
parent.setParams(parentParams);
}
}
@Override
public void incrProgress(double amount) {
lastThread = Thread.currentThread();
if (fakeProgressTimer == null) {
internalIncrProgress(amount);
}
}
protected synchronized void internalIncrProgress(double amount) {
current += amount;
// System.out.println(name + " incr " + amount + ", current=" + current);
if (current >= total) {
internalSetFinished();
}
if (parent != null) {
double d = amount / total;
parent.incrProgress(d * ratio);
}
}
@Override
public double getProgress() {
return current;
}
@Override
public void setTotal(double total) {
this.total = total;
}
@Override
public double getTotal() {
return total;
}
@Override
public boolean isCancelled() {
boolean ret = cancelled;
if (!ret && parent != null) {
ret = parent.isCancelled();
}
return ret;
}
@Override
public void cancel() {
cancelled = true;
if (lastThread != null) {
lastThread.interrupt();
}
setFinished();
}
@Override
public ProgressCallback createChild(String name, double ratio) {
ProgressCallbackImpl cb = new ProgressCallbackImpl(this, name);
cb.ratio = ratio;
return cb;
}
@Override
public ProgressCallback createChild(String name, double childTotal, double parentTotal) {
return createChild(name, childTotal / parentTotal);
}
public ProgressCallback createChild(double ratio) {
StackTraceElement[] stack = new Exception().getStackTrace();
StackTraceElement elm = stack[1];
String name = elm.getFileName() + ":" + elm.getLineNumber();
return createChild(name, ratio);
}
public ProgressCallback createChild(double childTotal, double parentTotal) {
StackTraceElement[] stack = new Exception().getStackTrace();
StackTraceElement elm = stack[stack.length-2];
String name = elm.getFileName() + ":" + elm.getLineNumber();
return createChild(name, childTotal / parentTotal);
}
@Override
public void setFinished() {
// System.out.println(name + " finished");
double amount = total - current;
if (amount <= 0) return;
internalIncrProgress(amount);
}
private synchronized void internalSetFinished() {
finished = true;
if (fakeProgressTimer != null) {
fakeProgressTimer.stop();
}
}
@Override
public void setFakeProgress(boolean v) {
if (v) {
setTotal(1);
fakeProgressTimer = new Timeline(new KeyFrame(Duration.seconds(0.2), new EventHandler<ActionEvent>() {
double x = 0;
@Override
public void handle(ActionEvent event) {
if (finished) return;
x += .7;
double nextVal = (-1 / x + 1);
internalIncrProgress(nextVal - current);
}
}));
fakeProgressTimer.setCycleCount(Timeline.INDEFINITE);
fakeProgressTimer.play();
}
}
// public static void main(String[] args) {
// ProgressCallback p1 = new ProgressCallbackImpl("p1");
// p1.setTotal(100);
//
// ProgressCallback c1 = p1.createChild("c1");
// c1.setTotal(50);
//
// ProgressCallback c11 = c1.createChild("c11");
// c11.setTotal(10);
// ProgressCallback c12 = c1.createChild("c12");
// c12.setTotal(15);
// ProgressCallback c13 = c1.createChild("c13");
// c13.setTotal(25);
//
// ProgressCallback c2 = p1.createChild("c2");
// c2.setTotal(40);
//
// ProgressCallback c21 = c2.createChild("c21");
// c21.setTotal(10);
// ProgressCallback c22 = c2.createChild("c22");
// c22.setTotal(30);
//
// c1.setProgress(0); // 0
// c11.setProgress(0); // 0
// c11.setProgress(1); // 1
// c11.setProgress(2); // 2
// c11.setFinished(); // 10
// c12.setProgress(0); // 10
// c12.setProgress(10);// 20
// c12.setFinished(); // 25
// c13.setProgress(0); // 25
// c13.setProgress(20);// 45
// c13.setProgress(25);// 50
// c13.setFinished(); // 50
// c1.setFinished(); // 50
//
// c2.setProgress(0); // 50
// c21.setProgress(9); // 59
// c21.setFinished(); // 60
// c22.setProgress(0); // 60
// c22.setProgress(29);// 89
// c22.setFinished(); // 90
// c2.setFinished(); // 90
//
// }
}