MetaProgressObserver -> ProgressAggregator.
This changes the way progress is aggregated so that we can do the various progress accumulating steps in parallel if we like.
This commit is contained in:
@@ -1237,6 +1237,9 @@ public class Application
|
|||||||
* that do not exist or fail the verification process will be returned. If all resources are
|
* that do not exist or fail the verification process will be returned. If all resources are
|
||||||
* ready to go, null will be returned and the application is considered ready to run.
|
* ready to go, null will be returned and the application is considered ready to run.
|
||||||
*
|
*
|
||||||
|
* @param obs a progress observer that will be notified of verification progress. NOTE: this
|
||||||
|
* observer may be called from arbitrary threads, so if you update a UI based on calls to it,
|
||||||
|
* you have to take care to get back to your UI thread.
|
||||||
* @param alreadyValid if non-null a 1 element array that will have the number of "already
|
* @param alreadyValid if non-null a 1 element array that will have the number of "already
|
||||||
* validated" resources filled in.
|
* validated" resources filled in.
|
||||||
* @param unpacked a set to populate with unpacked resources.
|
* @param unpacked a set to populate with unpacked resources.
|
||||||
@@ -1247,30 +1250,31 @@ public class Application
|
|||||||
List<Resource> rsrcs = getAllActiveResources();
|
List<Resource> rsrcs = getAllActiveResources();
|
||||||
List<Resource> failures = new ArrayList<Resource>();
|
List<Resource> failures = new ArrayList<Resource>();
|
||||||
|
|
||||||
// total up the file size of the resources to validate
|
// obtain the sizes of the resources to validate
|
||||||
long totalSize = 0L;
|
long[] sizes = new long[rsrcs.size()];
|
||||||
for (Resource rsrc : rsrcs) {
|
for (int ii = 0; ii < sizes.length; ii++) {
|
||||||
totalSize += rsrc.getLocal().length();
|
sizes[ii] = rsrcs.get(ii).getLocal().length();
|
||||||
}
|
}
|
||||||
|
|
||||||
MetaProgressObserver mpobs = new MetaProgressObserver(obs, totalSize);
|
ProgressAggregator pagg = new ProgressAggregator(obs, sizes);
|
||||||
boolean noUnpack = SysProps.noUnpack();
|
boolean noUnpack = SysProps.noUnpack();
|
||||||
for (Resource rsrc : rsrcs) {
|
for (int ii = 0; ii < sizes.length; ii++) {
|
||||||
|
Resource rsrc = rsrcs.get(ii);
|
||||||
if (Thread.interrupted()) {
|
if (Thread.interrupted()) {
|
||||||
throw new InterruptedException("m.applet_stopped");
|
throw new InterruptedException("m.applet_stopped");
|
||||||
}
|
}
|
||||||
mpobs.startElement(rsrc.getLocal().length());
|
|
||||||
|
|
||||||
|
ProgressObserver robs = pagg.startElement(ii);
|
||||||
if (rsrc.isMarkedValid()) {
|
if (rsrc.isMarkedValid()) {
|
||||||
if (alreadyValid != null) {
|
if (alreadyValid != null) {
|
||||||
alreadyValid[0]++;
|
alreadyValid[0]++;
|
||||||
}
|
}
|
||||||
mpobs.progress(100);
|
robs.progress(100);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (_digest.validateResource(rsrc, mpobs)) {
|
if (_digest.validateResource(rsrc, robs)) {
|
||||||
// unpack this resource if appropriate
|
// unpack this resource if appropriate
|
||||||
if (noUnpack || !rsrc.shouldUnpack()) {
|
if (noUnpack || !rsrc.shouldUnpack()) {
|
||||||
// finally note that this resource is kosher
|
// finally note that this resource is kosher
|
||||||
@@ -1290,7 +1294,7 @@ public class Application
|
|||||||
"rsrc", rsrc, "error", e);
|
"rsrc", rsrc, "error", e);
|
||||||
|
|
||||||
} finally {
|
} finally {
|
||||||
mpobs.progress(100);
|
robs.progress(100);
|
||||||
}
|
}
|
||||||
failures.add(rsrc);
|
failures.add(rsrc);
|
||||||
}
|
}
|
||||||
@@ -1308,27 +1312,31 @@ public class Application
|
|||||||
{
|
{
|
||||||
List<Resource> rsrcs = getActiveResources();
|
List<Resource> rsrcs = getActiveResources();
|
||||||
|
|
||||||
// total up the file size of the resources to unpack
|
// remove resources that we don't want to unpack
|
||||||
long totalSize = 0L;
|
|
||||||
for (Iterator<Resource> it = rsrcs.iterator(); it.hasNext(); ) {
|
for (Iterator<Resource> it = rsrcs.iterator(); it.hasNext(); ) {
|
||||||
Resource rsrc = it.next();
|
Resource rsrc = it.next();
|
||||||
if (rsrc.shouldUnpack() && !unpacked.contains(rsrc)) {
|
if (!rsrc.shouldUnpack() || unpacked.contains(rsrc)) {
|
||||||
totalSize += rsrc.getLocal().length();
|
|
||||||
} else {
|
|
||||||
it.remove();
|
it.remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MetaProgressObserver mpobs = new MetaProgressObserver(obs, totalSize);
|
// obtain the sizes of the resources to unpack
|
||||||
for (Resource rsrc : rsrcs) {
|
long[] sizes = new long[rsrcs.size()];
|
||||||
|
for (int ii = 0; ii < sizes.length; ii++) {
|
||||||
|
sizes[ii] = rsrcs.get(ii).getLocal().length();
|
||||||
|
}
|
||||||
|
|
||||||
|
ProgressAggregator pagg = new ProgressAggregator(obs, sizes);
|
||||||
|
for (int ii = 0; ii < sizes.length; ii++) {
|
||||||
if (Thread.interrupted()) {
|
if (Thread.interrupted()) {
|
||||||
throw new InterruptedException("m.applet_stopped");
|
throw new InterruptedException("m.applet_stopped");
|
||||||
}
|
}
|
||||||
mpobs.startElement(rsrc.getLocal().length());
|
Resource rsrc = rsrcs.get(ii);
|
||||||
|
ProgressObserver pobs = pagg.startElement(ii);
|
||||||
if (!rsrc.unpack()) {
|
if (!rsrc.unpack()) {
|
||||||
log.info("Failure unpacking resource", "rsrc", rsrc);
|
log.info("Failure unpacking resource", "rsrc", rsrc);
|
||||||
}
|
}
|
||||||
mpobs.progress(100);
|
pobs.progress(100);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ import java.net.URLConnection;
|
|||||||
import java.security.cert.Certificate;
|
import java.security.cert.Certificate;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -68,7 +69,7 @@ import com.threerings.getdown.tools.Patcher;
|
|||||||
import com.threerings.getdown.util.ConfigUtil;
|
import com.threerings.getdown.util.ConfigUtil;
|
||||||
import com.threerings.getdown.util.ConnectionUtil;
|
import com.threerings.getdown.util.ConnectionUtil;
|
||||||
import com.threerings.getdown.util.LaunchUtil;
|
import com.threerings.getdown.util.LaunchUtil;
|
||||||
import com.threerings.getdown.util.MetaProgressObserver;
|
import com.threerings.getdown.util.ProgressAggregator;
|
||||||
import com.threerings.getdown.util.ProgressObserver;
|
import com.threerings.getdown.util.ProgressObserver;
|
||||||
import com.threerings.getdown.util.VersionUtil;
|
import com.threerings.getdown.util.VersionUtil;
|
||||||
|
|
||||||
@@ -665,13 +666,14 @@ public abstract class Getdown extends Thread
|
|||||||
setStep(Step.PATCH);
|
setStep(Step.PATCH);
|
||||||
updateStatus("m.patching");
|
updateStatus("m.patching");
|
||||||
|
|
||||||
// create a new ProgressObserver that divides the different patching phases
|
long[] sizes = new long[list.size()];
|
||||||
MetaProgressObserver mprog = new MetaProgressObserver(_progobs, list.size());
|
Arrays.fill(sizes, 1L);
|
||||||
for (Resource prsrc : list) {
|
ProgressAggregator pragg = new ProgressAggregator(_progobs, sizes);
|
||||||
mprog.startElement(1);
|
int ii = 0; for (Resource prsrc : list) {
|
||||||
|
ProgressObserver pobs = pragg.startElement(ii++);
|
||||||
try {
|
try {
|
||||||
Patcher patcher = new Patcher();
|
Patcher patcher = new Patcher();
|
||||||
patcher.patch(prsrc.getLocal().getParentFile(), prsrc.getLocal(), mprog);
|
patcher.patch(prsrc.getLocal().getParentFile(), prsrc.getLocal(), pobs);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.warning("Failed to apply patch", "prsrc", prsrc, e);
|
log.warning("Failed to apply patch", "prsrc", prsrc, e);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,38 +0,0 @@
|
|||||||
//
|
|
||||||
// Getdown - application installer, patcher and launcher
|
|
||||||
// Copyright (C) 2004-2014 Three Rings Design, Inc.
|
|
||||||
// https://raw.github.com/threerings/getdown/master/LICENSE
|
|
||||||
|
|
||||||
package com.threerings.getdown.util;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Accumulates the progress from a number of elements into a single
|
|
||||||
* smoothly progressing progress.
|
|
||||||
*/
|
|
||||||
public class MetaProgressObserver implements ProgressObserver
|
|
||||||
{
|
|
||||||
public MetaProgressObserver (ProgressObserver target, long totalSize)
|
|
||||||
{
|
|
||||||
_target = target;
|
|
||||||
_totalSize = totalSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void startElement (long elementSize)
|
|
||||||
{
|
|
||||||
// add the previous size
|
|
||||||
_accum += (_elementSize * 100);
|
|
||||||
// then set the new one
|
|
||||||
_elementSize = elementSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
// documentation inherited from interface
|
|
||||||
public void progress (int percent)
|
|
||||||
{
|
|
||||||
if (_totalSize > 0) {
|
|
||||||
_target.progress((int)((_accum + (percent * _elementSize)) / _totalSize));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected ProgressObserver _target;
|
|
||||||
protected long _totalSize, _accum, _elementSize;
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
//
|
||||||
|
// Getdown - application installer, patcher and launcher
|
||||||
|
// Copyright (C) 2004-2014 Three Rings Design, Inc.
|
||||||
|
// https://raw.github.com/threerings/getdown/master/LICENSE
|
||||||
|
|
||||||
|
package com.threerings.getdown.util;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Accumulates the progress from a number of (potentially parallel) elements into a single smoothly
|
||||||
|
* progressing progress.
|
||||||
|
*/
|
||||||
|
public class ProgressAggregator
|
||||||
|
{
|
||||||
|
public ProgressAggregator (ProgressObserver target, long[] sizes) {
|
||||||
|
_target = target;
|
||||||
|
_sizes = sizes;
|
||||||
|
_progress = new int[sizes.length];
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProgressObserver startElement (final int index) {
|
||||||
|
return new ProgressObserver() {
|
||||||
|
public void progress (int percent) {
|
||||||
|
_sizes[index] = percent;
|
||||||
|
updateAggProgress();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void updateAggProgress () {
|
||||||
|
long totalSize = 0L, currentSize = 0L;
|
||||||
|
synchronized (this) {
|
||||||
|
for (int ii = 0, ll = _sizes.length; ii < ll; ii++) {
|
||||||
|
long size = _sizes[ii];
|
||||||
|
totalSize += size;
|
||||||
|
currentSize += (int)((size * _progress[ii])/100.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_target.progress((int)(100.0*currentSize / totalSize));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static long sum (long[] sizes) {
|
||||||
|
long totalSize = 0L;
|
||||||
|
for (long size : sizes) totalSize += size;
|
||||||
|
return totalSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected ProgressObserver _target;
|
||||||
|
protected long[] _sizes;
|
||||||
|
protected int[] _progress;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user