X-Git-Url: http://git.nikiroo.be/?a=blobdiff_plain;f=src%2Fbe%2Fnikiroo%2Futils%2FProgress.java;h=dea6be3fa011c351e4990b39e396368a50174e9d;hb=5584adbbbf5444c0039fed2b35dc7d5bb57b71b1;hp=d722fc91c3289e9f0b0425cba4bfba87fdc1b88f;hpb=11f9e5f37c2570f0376a4c1898c6aea3a7f28fc7;p=nikiroo-utils.git diff --git a/src/be/nikiroo/utils/Progress.java b/src/be/nikiroo/utils/Progress.java index d722fc9..dea6be3 100644 --- a/src/be/nikiroo/utils/Progress.java +++ b/src/be/nikiroo/utils/Progress.java @@ -6,7 +6,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; -import java.util.Set; /** * Progress reporting system, possibly nested. @@ -14,6 +13,12 @@ import java.util.Set; * @author niki */ public class Progress { + /** + * This event listener is designed to report progress events from + * {@link Progress}. + * + * @author niki + */ public interface ProgressListener extends EventListener { /** * A progression event. @@ -125,17 +130,17 @@ public class Progress { * the min to set * * - * @throws Error + * @throws RuntimeException * if min < 0 or if min > max */ public void setMin(int min) { if (min < 0) { - throw new Error("negative values not supported"); + throw new RuntimeException("negative values not supported"); } - synchronized (getLock()) { + synchronized (lock) { if (min > max) { - throw new Error( + throw new RuntimeException( "The minimum progress value must be <= the maximum progress value"); } @@ -159,11 +164,11 @@ public class Progress { * the max to set * * - * @throws Error + * @throws RuntimeException * if max < min */ public void setMax(int max) { - synchronized (getLock()) { + synchronized (lock) { if (max < min) { throw new Error( "The maximum progress value must be >= the minimum progress value"); @@ -181,20 +186,20 @@ public class Progress { * @param max * the max * - * @throws Error + * @throws RuntimeException * if min < 0 or if min > max */ public void setMinMax(int min, int max) { if (min < 0) { - throw new Error("negative values not supported"); + throw new RuntimeException("negative values not supported"); } if (min > max) { - throw new Error( + throw new RuntimeException( "The minimum progress value must be <= the maximum progress value"); } - synchronized (getLock()) { + synchronized (lock) { this.min = min; this.max = max; } @@ -220,7 +225,7 @@ public class Progress { * the progress to set */ public void setProgress(int progress) { - synchronized (getLock()) { + synchronized (lock) { double childrenProgress = relativeProgress - relativeLocalProgress; relativeLocalProgress = ((double) progress) / (max - min); @@ -255,7 +260,7 @@ public class Progress { */ private void setRelativeProgress(Progress pg, String name, double relativeProgress) { - synchronized (getLock()) { + synchronized (lock) { relativeProgress = Math.max(0, relativeProgress); relativeProgress = Math.min(1, relativeProgress); this.relativeProgress = relativeProgress; @@ -281,7 +286,7 @@ public class Progress { * the amount to add */ public void add(int step) { - synchronized (getLock()) { + synchronized (lock) { setProgress(getLocalProgress() + step); } } @@ -293,14 +298,18 @@ public class Progress { * @return TRUE if it is */ public boolean isDone() { - return relativeProgress >= 1d; + return getProgress() == max; } /** * Mark the {@link Progress} as done by setting its value to max. */ public void done() { - setProgress(getMax()); + synchronized (lock) { + double childrenProgress = relativeProgress - relativeLocalProgress; + relativeLocalProgress = 1 - childrenProgress; + setRelativeProgress(this, name, 1d); + } } /** @@ -308,15 +317,18 @@ public class Progress { * * @return the children (Who will think of the children??) */ - public Set getChildren() { - return children.keySet(); + public List getChildren() { + synchronized (lock) { + return new ArrayList(children.keySet()); + } } /** * Notify the listeners that this {@link Progress} changed value. * * @param pg - * the emmiter + * the emmiter, that is, the (sub-){link Progress} that just + * reported some change, not always the same as this * @param name * the current name (if it is NULL, the first non-null name in * the hierarchy will overwrite it) of the {@link Progress} who @@ -331,7 +343,7 @@ public class Progress { name = this.name; } - synchronized (getLock()) { + synchronized (lock) { for (ProgressListener l : listeners) { l.progress(pg, name); } @@ -349,7 +361,9 @@ public class Progress { * the listener */ public void addProgressListener(ProgressListener l) { - this.listeners.add(l); + synchronized (lock) { + this.listeners.add(l); + } } /** @@ -361,7 +375,9 @@ public class Progress { * @return TRUE if it was found (and removed) */ public boolean removeProgressListener(ProgressListener l) { - return this.listeners.remove(l); + synchronized (lock) { + return this.listeners.remove(l); + } } /** @@ -374,29 +390,29 @@ public class Progress { * {@link Progress#getMax()} scale) of this child * {@link Progress} in relation to its parent * - * @throws Error + * @throws RuntimeException * if weight exceed {@link Progress#getMax()} or if progress * already has a parent */ public void addProgress(Progress progress, double weight) { if (weight < min || weight > max) { - throw new Error(String.format( + throw new RuntimeException(String.format( "Progress object %s cannot have a weight of %f, " - + "it is outside of its parent (%s) range (%f)", + + "it is outside of its parent (%s) range (%d)", progress.name, weight, name, max)); } if (progress.parent != null) { - throw new Error(String.format( + throw new RuntimeException(String.format( "Progress object %s cannot be added to %s, " + "as it already has a parent (%s)", progress.name, name, progress.parent.name)); } - progress.addProgressListener(new ProgressListener() { + ProgressListener progressListener = new ProgressListener() { @Override public void progress(Progress pg, String name) { - synchronized (getLock()) { + synchronized (lock) { double total = relativeLocalProgress; for (Entry entry : children.entrySet()) { total += (entry.getValue() / (max - min)) @@ -406,23 +422,12 @@ public class Progress { setRelativeProgress(pg, name, total); } } - }); + }; - this.children.put(progress, weight); - } - - /** - * The lock object to use (this one or the recursively-parent one). - * - * @return the lock object to use - */ - private Object getLock() { synchronized (lock) { - if (parent != null) { - return parent.getLock(); - } - - return lock; + progress.parent = this; + this.children.put(progress, weight); + progress.addProgressListener(progressListener); } } }