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
|
||||
* 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
|
||||
* validated" resources filled in.
|
||||
* @param unpacked a set to populate with unpacked resources.
|
||||
@@ -1247,30 +1250,31 @@ public class Application
|
||||
List<Resource> rsrcs = getAllActiveResources();
|
||||
List<Resource> failures = new ArrayList<Resource>();
|
||||
|
||||
// total up the file size of the resources to validate
|
||||
long totalSize = 0L;
|
||||
for (Resource rsrc : rsrcs) {
|
||||
totalSize += rsrc.getLocal().length();
|
||||
// obtain the sizes of the resources to validate
|
||||
long[] sizes = new long[rsrcs.size()];
|
||||
for (int ii = 0; ii < sizes.length; ii++) {
|
||||
sizes[ii] = rsrcs.get(ii).getLocal().length();
|
||||
}
|
||||
|
||||
MetaProgressObserver mpobs = new MetaProgressObserver(obs, totalSize);
|
||||
ProgressAggregator pagg = new ProgressAggregator(obs, sizes);
|
||||
boolean noUnpack = SysProps.noUnpack();
|
||||
for (Resource rsrc : rsrcs) {
|
||||
for (int ii = 0; ii < sizes.length; ii++) {
|
||||
Resource rsrc = rsrcs.get(ii);
|
||||
if (Thread.interrupted()) {
|
||||
throw new InterruptedException("m.applet_stopped");
|
||||
}
|
||||
mpobs.startElement(rsrc.getLocal().length());
|
||||
|
||||
ProgressObserver robs = pagg.startElement(ii);
|
||||
if (rsrc.isMarkedValid()) {
|
||||
if (alreadyValid != null) {
|
||||
alreadyValid[0]++;
|
||||
}
|
||||
mpobs.progress(100);
|
||||
robs.progress(100);
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
if (_digest.validateResource(rsrc, mpobs)) {
|
||||
if (_digest.validateResource(rsrc, robs)) {
|
||||
// unpack this resource if appropriate
|
||||
if (noUnpack || !rsrc.shouldUnpack()) {
|
||||
// finally note that this resource is kosher
|
||||
@@ -1290,7 +1294,7 @@ public class Application
|
||||
"rsrc", rsrc, "error", e);
|
||||
|
||||
} finally {
|
||||
mpobs.progress(100);
|
||||
robs.progress(100);
|
||||
}
|
||||
failures.add(rsrc);
|
||||
}
|
||||
@@ -1308,27 +1312,31 @@ public class Application
|
||||
{
|
||||
List<Resource> rsrcs = getActiveResources();
|
||||
|
||||
// total up the file size of the resources to unpack
|
||||
long totalSize = 0L;
|
||||
// remove resources that we don't want to unpack
|
||||
for (Iterator<Resource> it = rsrcs.iterator(); it.hasNext(); ) {
|
||||
Resource rsrc = it.next();
|
||||
if (rsrc.shouldUnpack() && !unpacked.contains(rsrc)) {
|
||||
totalSize += rsrc.getLocal().length();
|
||||
} else {
|
||||
if (!rsrc.shouldUnpack() || unpacked.contains(rsrc)) {
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
|
||||
MetaProgressObserver mpobs = new MetaProgressObserver(obs, totalSize);
|
||||
for (Resource rsrc : rsrcs) {
|
||||
// obtain the sizes of the resources to unpack
|
||||
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()) {
|
||||
throw new InterruptedException("m.applet_stopped");
|
||||
}
|
||||
mpobs.startElement(rsrc.getLocal().length());
|
||||
Resource rsrc = rsrcs.get(ii);
|
||||
ProgressObserver pobs = pagg.startElement(ii);
|
||||
if (!rsrc.unpack()) {
|
||||
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.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
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.ConnectionUtil;
|
||||
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.VersionUtil;
|
||||
|
||||
@@ -665,13 +666,14 @@ public abstract class Getdown extends Thread
|
||||
setStep(Step.PATCH);
|
||||
updateStatus("m.patching");
|
||||
|
||||
// create a new ProgressObserver that divides the different patching phases
|
||||
MetaProgressObserver mprog = new MetaProgressObserver(_progobs, list.size());
|
||||
for (Resource prsrc : list) {
|
||||
mprog.startElement(1);
|
||||
long[] sizes = new long[list.size()];
|
||||
Arrays.fill(sizes, 1L);
|
||||
ProgressAggregator pragg = new ProgressAggregator(_progobs, sizes);
|
||||
int ii = 0; for (Resource prsrc : list) {
|
||||
ProgressObserver pobs = pragg.startElement(ii++);
|
||||
try {
|
||||
Patcher patcher = new Patcher();
|
||||
patcher.patch(prsrc.getLocal().getParentFile(), prsrc.getLocal(), mprog);
|
||||
patcher.patch(prsrc.getLocal().getParentFile(), prsrc.getLocal(), pobs);
|
||||
} catch (Exception 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