-
Notifications
You must be signed in to change notification settings - Fork 62
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(obfuscator): began works on custom renderer for progress bar + h…
…ard dependency requirement
- Loading branch information
1 parent
af42a90
commit 33581a4
Showing
8 changed files
with
546 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
172 changes: 172 additions & 0 deletions
172
...ator/src/main/java/dev/skidfuscator/obfuscator/util/progress/SkidProgressBarRenderer.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,172 @@ | ||
package dev.skidfuscator.obfuscator.util.progress; | ||
|
||
import me.tongfei.progressbar.ProgressBarRenderer; | ||
import me.tongfei.progressbar.ProgressBarStyle; | ||
|
||
import java.text.DecimalFormat; | ||
import java.time.Duration; | ||
import java.time.Instant; | ||
import java.time.temporal.ChronoUnit; | ||
|
||
import static dev.skidfuscator.obfuscator.util.progress.StringDisplayUtils.getStringDisplayLength; | ||
import static dev.skidfuscator.obfuscator.util.progress.StringDisplayUtils.trimDisplayLength; | ||
|
||
/** | ||
* Default progress bar renderer (see {@link ProgressBarRenderer}). | ||
* @author Tongfei Chen | ||
* @author Muhammet Sakarya | ||
* @since 0.8.0 | ||
*/ | ||
public class SkidProgressBarRenderer { | ||
|
||
private ProgressBarStyle style; | ||
private String unitName; | ||
private long unitSize; | ||
private boolean isSpeedShown; | ||
private DecimalFormat speedFormat; | ||
private ChronoUnit speedUnit; | ||
private Spinner<String> values = new Spinner<>( | ||
"⠋", | ||
"⠙", | ||
"⠹", | ||
"⠸", | ||
"⠼", | ||
"⠴", | ||
"⠦", | ||
"⠧", | ||
"⠇", | ||
"⠏" | ||
); | ||
|
||
protected SkidProgressBarRenderer( | ||
ProgressBarStyle style, | ||
String unitName, | ||
long unitSize, | ||
boolean isSpeedShown, | ||
DecimalFormat speedFormat, | ||
ChronoUnit speedUnit | ||
) { | ||
this.style = style; | ||
this.unitName = unitName; | ||
this.unitSize = unitSize; | ||
this.isSpeedShown = isSpeedShown; | ||
this.speedFormat = isSpeedShown && speedFormat == null ? new DecimalFormat() : speedFormat; | ||
this.speedUnit = speedUnit; | ||
} | ||
|
||
// Number of full blocks | ||
protected int progressIntegralPart(SkidProgressState progress, int length) { | ||
return (int)(progress.getNormalizedProgress() * length); | ||
} | ||
|
||
protected int progressFractionalPart(SkidProgressState progress, int length) { | ||
double p = progress.getNormalizedProgress() * length; | ||
double fraction = (p - Math.floor(p)) ;//* style.fractionSymbols.length(); | ||
return (int) Math.floor(fraction); | ||
} | ||
|
||
protected String eta(SkidProgressState progress, Duration elapsed) { | ||
if (progress.max <= 0 || progress.indefinite) return "?"; | ||
else if (progress.current - progress.start == 0) return "?"; | ||
else return Util.formatDuration( | ||
elapsed.dividedBy(progress.current - progress.start).multipliedBy(progress.max - progress.current) | ||
); | ||
} | ||
|
||
protected String percentage(SkidProgressState progress) { | ||
String res; | ||
if (progress.max <= 0 || progress.indefinite) res = "? %"; | ||
else res = String.valueOf((int) Math.floor(100.0 * progress.current / progress.max)) + "%"; | ||
return Util.repeat(' ', 4 - res.length()) + res; | ||
} | ||
|
||
protected String ratio(SkidProgressState progress) { | ||
String m = progress.indefinite ? "?" : String.valueOf(progress.max / unitSize); | ||
String c = String.valueOf(progress.current / unitSize); | ||
return Util.repeat(' ', m.length() - c.length()) + c + "/" + m + unitName; | ||
} | ||
|
||
protected String speed(SkidProgressState progress, Duration elapsed) { | ||
String suffix = "/s"; | ||
double elapsedSeconds = elapsed.getSeconds(); | ||
double elapsedInUnit = elapsedSeconds; | ||
if (null != speedUnit) | ||
switch (speedUnit) { | ||
case MINUTES: | ||
suffix = "/min"; | ||
elapsedInUnit /= 60; | ||
break; | ||
case HOURS: | ||
suffix = "/h"; | ||
elapsedInUnit /= (60 * 60); | ||
break; | ||
case DAYS: | ||
suffix = "/d"; | ||
elapsedInUnit /= (60 * 60 * 24); | ||
break; | ||
} | ||
|
||
if (elapsedSeconds == 0) | ||
return "?" + unitName + suffix; | ||
double speed = (double) (progress.current - progress.start) / elapsedInUnit; | ||
double speedWithUnit = speed / unitSize; | ||
return speedFormat.format(speedWithUnit) + unitName + suffix; | ||
} | ||
|
||
public String render(SkidProgressState progress, int maxLength) { | ||
if (maxLength <= 0) { | ||
return ""; | ||
} | ||
/* | ||
Instant currTime = Instant.now(); | ||
Duration elapsed = Duration.between(progress.startInstant, currTime); | ||
String prefix = progress.taskName + " (" + percentage(progress) + ") " + style.leftBracket; | ||
int prefixLength = getStringDisplayLength(prefix); | ||
if (prefixLength > maxLength) { | ||
prefix = trimDisplayLength(prefix, maxLength - 1); | ||
prefixLength = maxLength - 1; | ||
} | ||
// length of progress should be at least 1 | ||
int maxSuffixLength = Math.max(maxLength - prefixLength - 1, 0); | ||
String speedString = isSpeedShown ? speed(progress, elapsed) : ""; | ||
String suffix = style.rightBracket + " " + ratio(progress) + " (" | ||
+ Util.formatDuration(elapsed) + " / " + eta(progress, elapsed) + ") " | ||
+ speedString + progress.extraMessage; | ||
int suffixLength = getStringDisplayLength(suffix); | ||
// trim excessive suffix | ||
if (suffixLength > maxSuffixLength) { | ||
suffix = trimDisplayLength(suffix, maxSuffixLength); | ||
suffixLength = maxSuffixLength; | ||
} | ||
int length = maxLength - prefixLength - suffixLength; | ||
StringBuilder sb = new StringBuilder(maxLength); | ||
sb.append(prefix); | ||
// case of indefinite progress bars | ||
if (progress.indefinite) { | ||
int pos = (int)(progress.current % length); | ||
sb.append(Util.repeat(' ', pos)); | ||
sb.append(values.next()); | ||
sb.append(Util.repeat(' ', length - pos - 1)); | ||
} | ||
// case of definite progress bars | ||
else { | ||
sb.append(Util.repeat(style.block, progressIntegralPart(progress, length))); | ||
if (progress.current < progress.max) { | ||
sb.append(style.fractionSymbols.charAt(progressFractionalPart(progress, length))); | ||
sb.append(Util.repeat(style.space, length - progressIntegralPart(progress, length) - 1)); | ||
} | ||
} | ||
sb.append(suffix);*/ | ||
return null; //sb.toString(); | ||
} | ||
|
||
} |
111 changes: 111 additions & 0 deletions
111
obfuscator/src/main/java/dev/skidfuscator/obfuscator/util/progress/SkidProgressState.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
package dev.skidfuscator.obfuscator.util.progress; | ||
|
||
import java.time.Duration; | ||
import java.time.Instant; | ||
|
||
/** | ||
* Encapsulates the internal states of a progress bar. | ||
* @author Tongfei Chen | ||
* @since 0.5.0 | ||
*/ | ||
class SkidProgressState { | ||
|
||
String taskName; | ||
String extraMessage = ""; | ||
|
||
boolean indefinite = false; | ||
|
||
// 0 start current max | ||
// [===============|=========> ] | ||
long start; | ||
long current; | ||
long max; | ||
|
||
Instant startInstant = null; | ||
Duration elapsedBeforeStart = Duration.ZERO; | ||
|
||
volatile boolean alive = true; | ||
volatile boolean paused = false; | ||
|
||
SkidProgressState(String taskName, long initialMax, long startFrom, Duration elapsedBeforeStart) { | ||
this.taskName = taskName; | ||
this.max = initialMax; | ||
if (initialMax < 0) indefinite = true; | ||
this.start = startFrom; | ||
this.current = startFrom; | ||
this.elapsedBeforeStart = elapsedBeforeStart; | ||
this.startInstant = Instant.now(); | ||
} | ||
|
||
String getTaskName() { | ||
return taskName; | ||
} | ||
|
||
synchronized String getExtraMessage() { | ||
return extraMessage; | ||
} | ||
|
||
synchronized long getCurrent() { | ||
return current; | ||
} | ||
|
||
synchronized long getMax() { | ||
return max; | ||
} | ||
|
||
// The progress, normalized to range [0, 1]. | ||
synchronized double getNormalizedProgress() { | ||
if (max <= 0) return 0.0; | ||
else if (current > max) return 1.0; | ||
else return ((double)current) / max; | ||
} | ||
|
||
synchronized void setAsDefinite() { | ||
indefinite = false; | ||
} | ||
|
||
synchronized void setAsIndefinite() { | ||
indefinite = true; | ||
} | ||
|
||
synchronized void maxHint(long n) { | ||
max = n; | ||
} | ||
|
||
synchronized void stepBy(long n) { | ||
current += n; | ||
if (current > max) max = current; | ||
} | ||
|
||
synchronized void stepTo(long n) { | ||
current = n; | ||
if (current > max) max = current; | ||
} | ||
|
||
synchronized void setExtraMessage(String msg) { | ||
extraMessage = msg; | ||
} | ||
|
||
synchronized void pause() { | ||
paused = true; | ||
start = current; | ||
elapsedBeforeStart = elapsedBeforeStart.plus(Duration.between(startInstant, Instant.now())); | ||
} | ||
|
||
synchronized void resume() { | ||
paused = false; | ||
startInstant = Instant.now(); | ||
} | ||
|
||
synchronized void reset() { | ||
start = 0; | ||
current = 0; | ||
startInstant = Instant.now(); | ||
elapsedBeforeStart = Duration.ZERO; | ||
} | ||
|
||
synchronized void kill() { | ||
alive = false; | ||
} | ||
|
||
} |
20 changes: 20 additions & 0 deletions
20
obfuscator/src/main/java/dev/skidfuscator/obfuscator/util/progress/Spinner.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package dev.skidfuscator.obfuscator.util.progress; | ||
|
||
/** | ||
* @author Ghast | ||
* @since 07/02/2021 | ||
* Artemis © 2021 | ||
*/ | ||
public class Spinner<T> { | ||
private final T[] values; | ||
private int index; | ||
|
||
public Spinner(T... values) { | ||
this.values = values; | ||
this.index = 0; | ||
} | ||
|
||
public T next() { | ||
return values[index = (++index % values.length)]; | ||
} | ||
} |
Oops, something went wrong.