Clean progress bar code and fix TextureMap patch (#5304)
This commit is contained in:
parent
b4cf6f7f36
commit
dc12cda505
15 changed files with 632 additions and 290 deletions
|
@ -24,7 +24,7 @@
|
||||||
|
|
||||||
this.field_110451_am.func_199006_a(new GrassColorReloadListener());
|
this.field_110451_am.func_199006_a(new GrassColorReloadListener());
|
||||||
this.field_110451_am.func_199006_a(new FoliageColorReloadListener());
|
this.field_110451_am.func_199006_a(new FoliageColorReloadListener());
|
||||||
+ net.minecraftforge.fml.common.ProgressManager.ProgressBar bar = net.minecraftforge.fml.common.ProgressManager.push("Rendering Setup", 5, true);
|
+ try (net.minecraftforge.fml.common.progress.ProgressBar bar = net.minecraftforge.fml.common.progress.StartupProgressManager.start("Rendering Setup", 5, true)) {
|
||||||
+ bar.step("GL Setup");
|
+ bar.step("GL Setup");
|
||||||
this.field_195558_d.func_198076_a("Startup");
|
this.field_195558_d.func_198076_a("Startup");
|
||||||
GlStateManager.func_179098_w();
|
GlStateManager.func_179098_w();
|
||||||
|
@ -60,7 +60,7 @@
|
||||||
this.field_71452_i = new ParticleManager(this.field_71441_e, this.field_71446_o);
|
this.field_71452_i = new ParticleManager(this.field_71441_e, this.field_71446_o);
|
||||||
- this.field_71456_v = new GuiIngame(this);
|
- this.field_71456_v = new GuiIngame(this);
|
||||||
+ //net.minecraftforge.fml.client.SplashProgress.resume();
|
+ //net.minecraftforge.fml.client.SplashProgress.resume();
|
||||||
+ net.minecraftforge.fml.common.ProgressManager.pop(bar);
|
+ }; // Forge: end progress bar
|
||||||
+ net.minecraftforge.fml.client.ClientModLoader.end();
|
+ net.minecraftforge.fml.client.ClientModLoader.end();
|
||||||
+ this.field_71456_v = new net.minecraftforge.client.GuiIngameForge(this);
|
+ this.field_71456_v = new net.minecraftforge.client.GuiIngameForge(this);
|
||||||
if (this.field_71475_ae != null) {
|
if (this.field_71475_ae != null) {
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
+ net.minecraftforge.fml.common.ProgressManager.ProgressBar resourcesBar = net.minecraftforge.fml.common.ProgressManager.push("Loading sounds", resources.size());
|
+ try (net.minecraftforge.fml.common.progress.ProgressBar resourcesBar = net.minecraftforge.fml.common.progress.StartupProgressManager.start("Loading sounds", resources.size())) {
|
||||||
+ resources.forEach(entry -> {
|
+ resources.forEach(entry -> {
|
||||||
+ resourcesBar.step(entry.func_76341_a().toString());
|
+ resourcesBar.step(entry.func_76341_a().toString());
|
||||||
+ try {
|
+ try {
|
||||||
|
@ -30,7 +30,7 @@
|
||||||
+ field_147698_b.warn("Invalid sounds.json", e);
|
+ field_147698_b.warn("Invalid sounds.json", e);
|
||||||
+ }
|
+ }
|
||||||
+ });
|
+ });
|
||||||
+ net.minecraftforge.fml.common.ProgressManager.pop(resourcesBar);
|
+ }; // Forge: end progress bar
|
||||||
+
|
+
|
||||||
for(ResourceLocation resourcelocation : this.field_147697_e.func_148742_b()) {
|
for(ResourceLocation resourcelocation : this.field_147697_e.func_148742_b()) {
|
||||||
SoundEventAccessor soundeventaccessor = (SoundEventAccessor)this.field_147697_e.func_82594_a(resourcelocation);
|
SoundEventAccessor soundeventaccessor = (SoundEventAccessor)this.field_147697_e.func_82594_a(resourcelocation);
|
||||||
|
|
|
@ -13,9 +13,8 @@
|
||||||
public void func_94305_f() {
|
public void func_94305_f() {
|
||||||
Stitcher.Holder[] astitcher$holder = (Stitcher.Holder[])this.field_94319_a.toArray(new Stitcher.Holder[this.field_94319_a.size()]);
|
Stitcher.Holder[] astitcher$holder = (Stitcher.Holder[])this.field_94319_a.toArray(new Stitcher.Holder[this.field_94319_a.size()]);
|
||||||
Arrays.sort((Object[])astitcher$holder);
|
Arrays.sort((Object[])astitcher$holder);
|
||||||
-
|
+ try(net.minecraftforge.fml.common.progress.ProgressBar bar = net.minecraftforge.fml.common.progress.StartupProgressManager.start("Texture stitching", astitcher$holder.length)) {
|
||||||
+ net.minecraftforge.fml.common.ProgressManager.ProgressBar bar = net.minecraftforge.fml.common.ProgressManager.push("Texture stitching", astitcher$holder.length);
|
|
||||||
+
|
|
||||||
for(Stitcher.Holder stitcher$holder : astitcher$holder) {
|
for(Stitcher.Holder stitcher$holder : astitcher$holder) {
|
||||||
+ bar.step(stitcher$holder.func_98150_a().func_195668_m().toString());
|
+ bar.step(stitcher$holder.func_98150_a().func_195668_m().toString());
|
||||||
if (!this.func_94310_b(stitcher$holder)) {
|
if (!this.func_94310_b(stitcher$holder)) {
|
||||||
|
@ -29,7 +28,7 @@
|
||||||
|
|
||||||
this.field_94318_c = MathHelper.func_151236_b(this.field_94318_c);
|
this.field_94318_c = MathHelper.func_151236_b(this.field_94318_c);
|
||||||
this.field_94315_d = MathHelper.func_151236_b(this.field_94315_d);
|
this.field_94315_d = MathHelper.func_151236_b(this.field_94315_d);
|
||||||
+ net.minecraftforge.fml.common.ProgressManager.pop(bar);
|
+ }; // Forge: end progress bar
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<TextureAtlasSprite> func_94309_g() {
|
public List<TextureAtlasSprite> func_94309_g() {
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
|
|
||||||
public void func_195410_a(IResourceManager p_195410_1_) {
|
public void func_195410_a(IResourceManager p_195410_1_) {
|
||||||
MissingTextureSprite.func_195676_d();
|
MissingTextureSprite.func_195676_d();
|
||||||
+ net.minecraftforge.fml.common.ProgressManager.ProgressBar bar = net.minecraftforge.fml.common.ProgressManager.push("Reloading Texture Manager", this.field_110585_a.entrySet().size(), true);
|
+ try (net.minecraftforge.fml.common.progress.ProgressBar bar = net.minecraftforge.fml.common.progress.StartupProgressManager.start("Reloading Texture Manager", this.field_110585_a.entrySet().size(), true)) {
|
||||||
Iterator<Entry<ResourceLocation, ITextureObject>> iterator = this.field_110585_a.entrySet().iterator();
|
Iterator<Entry<ResourceLocation, ITextureObject>> iterator = this.field_110585_a.entrySet().iterator();
|
||||||
|
|
||||||
while(iterator.hasNext()) {
|
while(iterator.hasNext()) {
|
||||||
|
@ -26,7 +26,7 @@
|
||||||
this.func_110579_a(entry.getKey(), itextureobject);
|
this.func_110579_a(entry.getKey(), itextureobject);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+ net.minecraftforge.fml.common.ProgressManager.pop(bar);
|
+ }; // Forge: end progress bar
|
||||||
+ }
|
+ }
|
||||||
|
|
||||||
+ @Override
|
+ @Override
|
||||||
|
|
|
@ -8,113 +8,40 @@
|
||||||
p_195426_2_.forEach((p_195423_2_) -> {
|
p_195426_2_.forEach((p_195423_2_) -> {
|
||||||
this.func_199362_a(p_195426_1_, p_195423_2_);
|
this.func_199362_a(p_195426_1_, p_195423_2_);
|
||||||
});
|
});
|
||||||
@@ -56,37 +57,76 @@
|
@@ -57,8 +58,14 @@
|
||||||
this.func_195419_g();
|
|
||||||
int j = Integer.MAX_VALUE;
|
int j = Integer.MAX_VALUE;
|
||||||
int k = 1 << this.field_147636_j;
|
int k = 1 << this.field_147636_j;
|
||||||
-
|
|
||||||
- for(ResourceLocation resourcelocation : this.field_195427_i) {
|
- for(ResourceLocation resourcelocation : this.field_195427_i) {
|
||||||
+ field_147635_d.info("Max texture size: {}", i);
|
+ field_147635_d.info("Max texture size: {}", i);
|
||||||
+ net.minecraftforge.fml.common.ProgressManager.ProgressBar bar = net.minecraftforge.fml.common.ProgressManager.push("Texture stitching", this.field_195427_i.size());
|
+ try (net.minecraftforge.fml.common.progress.ProgressBar textureLoadingBar = net.minecraftforge.fml.common.progress.StartupProgressManager.start("Texture loading", this.field_195427_i.size())) {
|
||||||
+ loadedSprites.clear();
|
+ loadedSprites.clear();
|
||||||
+
|
|
||||||
+ for(ResourceLocation resourcelocation : Sets.newHashSet(this.field_195427_i)) {
|
+ for(ResourceLocation resourcelocation : Sets.newHashSet(this.field_195427_i)) {
|
||||||
+ ResourceLocation resourcelocation1 = this.func_195420_b(resourcelocation);
|
+ textureLoadingBar.step(this.func_195420_b(resourcelocation).toString());
|
||||||
+ bar.step(resourcelocation1.toString());
|
|
||||||
if (!this.field_94249_f.func_195668_m().equals(resourcelocation)) {
|
if (!this.field_94249_f.func_195668_m().equals(resourcelocation)) {
|
||||||
- ResourceLocation resourcelocation1 = this.func_195420_b(resourcelocation);
|
+ j = loadTexture(stitcher, p_195421_1_, resourcelocation, j, k);
|
||||||
+ j = loadTexture(stitcher, p_195421_1_, resourcelocation, bar, j, k);
|
+ if (true) continue; // Forge: skip the rest of this if statement, we're using loadTexture instead
|
||||||
+ }
|
ResourceLocation resourcelocation1 = this.func_195420_b(resourcelocation);
|
||||||
+ }
|
|
||||||
+ finishLoading(stitcher, p_195421_1_, bar, j, k);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ private int loadTexture(Stitcher stitcher, IResourceManager manager, ResourceLocation resourcelocation, net.minecraftforge.fml.common.ProgressManager.ProgressBar bar, int j, int k) {
|
|
||||||
+ if (loadedSprites.contains(resourcelocation)) {
|
|
||||||
+ return j;
|
|
||||||
+ }
|
|
||||||
+ TextureAtlasSprite textureatlassprite;
|
|
||||||
+ ResourceLocation resourcelocation1 = this.func_195420_b(resourcelocation);
|
|
||||||
+ for(ResourceLocation loading : loadingSprites) {
|
|
||||||
+ if(resourcelocation1.equals(loading)) {
|
|
||||||
+ final String error = "circular model dependencies, stack: [" + com.google.common.base.Joiner.on(", ").join(loadingSprites) + "]";
|
|
||||||
+ net.minecraftforge.fml.client.ClientHooks.trackBrokenTexture(resourcelocation, error);
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ loadingSprites.addLast(resourcelocation1);
|
|
||||||
+ try (IResource iresource = manager.func_199002_a(resourcelocation1)) {
|
|
||||||
+ PngSizeInfo pngsizeinfo = new PngSizeInfo(iresource);
|
|
||||||
+ AnimationMetadataSection animationmetadatasection = (AnimationMetadataSection)iresource.func_199028_a(AnimationMetadataSection.field_195817_a);
|
|
||||||
+ textureatlassprite = new TextureAtlasSprite(resourcelocation, pngsizeinfo, animationmetadatasection);
|
|
||||||
|
|
||||||
- TextureAtlasSprite textureatlassprite;
|
TextureAtlasSprite textureatlassprite;
|
||||||
- try (IResource iresource = p_195421_1_.func_199002_a(resourcelocation1)) {
|
@@ -84,9 +91,11 @@
|
||||||
- PngSizeInfo pngsizeinfo = new PngSizeInfo(iresource);
|
stitcher.func_110934_a(textureatlassprite);
|
||||||
- AnimationMetadataSection animationmetadatasection = (AnimationMetadataSection)iresource.func_199028_a(AnimationMetadataSection.field_195817_a);
|
|
||||||
- textureatlassprite = new TextureAtlasSprite(resourcelocation, pngsizeinfo, animationmetadatasection);
|
|
||||||
- } catch (RuntimeException runtimeexception) {
|
|
||||||
- field_147635_d.error("Unable to parse metadata from {} : {}", resourcelocation1, runtimeexception);
|
|
||||||
- continue;
|
|
||||||
- } catch (IOException ioexception) {
|
|
||||||
- field_147635_d.error("Using missing texture, unable to load {} : {}", resourcelocation1, ioexception);
|
|
||||||
- continue;
|
|
||||||
+ for (ResourceLocation dependency : textureatlassprite.getDependencies()) {
|
|
||||||
+ if (!field_195427_i.contains(dependency.toString())) {
|
|
||||||
+ func_199362_a(manager, dependency);
|
|
||||||
}
|
}
|
||||||
-
|
|
||||||
- j = Math.min(j, Math.min(textureatlassprite.func_94211_a(), textureatlassprite.func_94216_b()));
|
|
||||||
- int j1 = Math.min(Integer.lowestOneBit(textureatlassprite.func_94211_a()), Integer.lowestOneBit(textureatlassprite.func_94216_b()));
|
|
||||||
- if (j1 < k) {
|
|
||||||
- field_147635_d.warn("Texture {} with size {}x{} limits mip level from {} to {}", resourcelocation1, textureatlassprite.func_94211_a(), textureatlassprite.func_94216_b(), MathHelper.func_151239_c(k), MathHelper.func_151239_c(j1));
|
|
||||||
- k = j1;
|
|
||||||
+ j = loadTexture(stitcher, manager, dependency, bar, j, k);
|
|
||||||
+ }
|
|
||||||
+ if (textureatlassprite.hasCustomLoader(manager, resourcelocation)) {
|
|
||||||
+ if (textureatlassprite.load(manager, resourcelocation, l -> field_94252_e.get(l.toString()))) {
|
|
||||||
+ return j;
|
|
||||||
}
|
}
|
||||||
-
|
+ } // Forge: end progress bar
|
||||||
- stitcher.func_110934_a(textureatlassprite);
|
|
||||||
}
|
|
||||||
+ j = Math.min(j, Math.min(textureatlassprite.func_94211_a(), textureatlassprite.func_94216_b()));
|
|
||||||
+ int j1 = Math.min(Integer.lowestOneBit(textureatlassprite.func_94211_a()), Integer.lowestOneBit(textureatlassprite.func_94216_b()));
|
|
||||||
+ if (j1 < k) {
|
|
||||||
+ // FORGE: do not lower the mipmap level, just log the problematic textures
|
|
||||||
+ field_147635_d.warn("Texture {} with size {}x{} will have visual artifacts at mip level {}, it can only support level {}. Please report to the mod author that the texture should be some multiple of 16x16.", resourcelocation1, textureatlassprite.func_94211_a(), textureatlassprite.func_94216_b(), MathHelper.func_151239_c(k), MathHelper.func_151239_c(j1));
|
|
||||||
+ }
|
|
||||||
+ if (func_195422_a(manager, textureatlassprite))
|
|
||||||
+ stitcher.func_110934_a(textureatlassprite);
|
|
||||||
+ return j;
|
|
||||||
+ } catch (RuntimeException runtimeexception) {
|
|
||||||
+ net.minecraftforge.fml.client.ClientHooks.trackBrokenTexture(resourcelocation, runtimeexception.getMessage());
|
|
||||||
+ return j;
|
|
||||||
+ } catch (IOException ioexception) {
|
|
||||||
+ net.minecraftforge.fml.client.ClientHooks.trackMissingTexture(resourcelocation);
|
|
||||||
+ return j;
|
|
||||||
+ } finally {
|
|
||||||
+ loadingSprites.removeLast();
|
|
||||||
+ field_195427_i.add(resourcelocation1);
|
|
||||||
}
|
|
||||||
-
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ private void finishLoading(Stitcher stitcher, IResourceManager manager, net.minecraftforge.fml.common.ProgressManager.ProgressBar bar, int j, int k)
|
|
||||||
+ {
|
|
||||||
+ net.minecraftforge.fml.common.ProgressManager.pop(bar);
|
|
||||||
int l = Math.min(j, k);
|
int l = Math.min(j, k);
|
||||||
int i1 = MathHelper.func_151239_c(l);
|
int i1 = MathHelper.func_151239_c(l);
|
||||||
+ if (false) // FORGE: do not lower the mipmap level
|
+ if (false) // FORGE: do not lower the mipmap level
|
||||||
if (i1 < this.field_147636_j) {
|
if (i1 < this.field_147636_j) {
|
||||||
field_147635_d.warn("{}: dropping miplevel from {} to {}, because of minimum power of two: {}", this.field_94254_c, this.field_147636_j, i1, l);
|
field_147635_d.warn("{}: dropping miplevel from {} to {}, because of minimum power of two: {}", this.field_94254_c, this.field_147636_j, i1, l);
|
||||||
this.field_147636_j = i1;
|
this.field_147636_j = i1;
|
||||||
@@ -94,18 +134,26 @@
|
@@ -94,18 +103,25 @@
|
||||||
|
|
||||||
this.field_94249_f.func_147963_d(this.field_147636_j);
|
this.field_94249_f.func_147963_d(this.field_147636_j);
|
||||||
stitcher.func_110934_a(this.field_94249_f);
|
stitcher.func_110934_a(this.field_94249_f);
|
||||||
-
|
+ try (net.minecraftforge.fml.common.progress.ProgressBar bar = net.minecraftforge.fml.common.progress.StartupProgressManager.start("Texture creation", 2)) {
|
||||||
+ bar = net.minecraftforge.fml.common.ProgressManager.push("Texture creation", 2);
|
|
||||||
+
|
|
||||||
try {
|
try {
|
||||||
+ bar.step("Stitching");
|
+ bar.step("Stitching");
|
||||||
stitcher.func_94305_f();
|
stitcher.func_94305_f();
|
||||||
|
@ -125,28 +52,27 @@
|
||||||
field_147635_d.info("Created: {}x{} {}-atlas", stitcher.func_110935_a(), stitcher.func_110936_b(), this.field_94254_c);
|
field_147635_d.info("Created: {}x{} {}-atlas", stitcher.func_110935_a(), stitcher.func_110936_b(), this.field_94254_c);
|
||||||
+ bar.step("Allocating GL texture");
|
+ bar.step("Allocating GL texture");
|
||||||
TextureUtil.func_180600_a(this.func_110552_b(), this.field_147636_j, stitcher.func_110935_a(), stitcher.func_110936_b());
|
TextureUtil.func_180600_a(this.func_110552_b(), this.field_147636_j, stitcher.func_110935_a(), stitcher.func_110936_b());
|
||||||
+
|
|
||||||
+ net.minecraftforge.fml.common.ProgressManager.pop(bar);
|
|
||||||
+ bar = net.minecraftforge.fml.common.ProgressManager.push("Texture mipmap and upload", stitcher.func_94309_g().size());
|
|
||||||
|
|
||||||
|
+ }; // Forge: end progress bar
|
||||||
|
+ try (net.minecraftforge.fml.common.progress.ProgressBar bar = net.minecraftforge.fml.common.progress.StartupProgressManager.start("Texture mipmap and upload", stitcher.func_94309_g().size())) {
|
||||||
for(TextureAtlasSprite textureatlassprite1 : stitcher.func_94309_g()) {
|
for(TextureAtlasSprite textureatlassprite1 : stitcher.func_94309_g()) {
|
||||||
- if (textureatlassprite1 == this.field_94249_f || this.func_195422_a(p_195421_1_, textureatlassprite1)) {
|
- if (textureatlassprite1 == this.field_94249_f || this.func_195422_a(p_195421_1_, textureatlassprite1)) {
|
||||||
+ bar.step(textureatlassprite1.func_195668_m().toString());
|
+ bar.step(textureatlassprite1.func_195668_m().toString());
|
||||||
+ // FORGE: Sprite loading is now done during stitching, short-circuit this check
|
+ // FORGE: Sprite loading is now done during stitching, short-circuit this check
|
||||||
+ if (true || textureatlassprite1 == this.field_94249_f || this.func_195422_a(manager, textureatlassprite1)) {
|
+ if (true || textureatlassprite1 == this.field_94249_f || this.func_195422_a(p_195421_1_, textureatlassprite1)) {
|
||||||
this.field_94252_e.put(textureatlassprite1.func_195668_m(), textureatlassprite1);
|
this.field_94252_e.put(textureatlassprite1.func_195668_m(), textureatlassprite1);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -124,6 +172,8 @@
|
@@ -124,6 +140,8 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
+ net.minecraftforge.client.ForgeHooksClient.onTextureStitchedPost(this);
|
+ net.minecraftforge.client.ForgeHooksClient.onTextureStitchedPost(this);
|
||||||
+ net.minecraftforge.fml.common.ProgressManager.pop(bar);
|
+ }; // Forge: end progress bar
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean func_195422_a(IResourceManager p_195422_1_, TextureAtlasSprite p_195422_2_) {
|
private boolean func_195422_a(IResourceManager p_195422_1_, TextureAtlasSprite p_195422_2_) {
|
||||||
@@ -132,6 +182,7 @@
|
@@ -132,6 +150,7 @@
|
||||||
|
|
||||||
label62: {
|
label62: {
|
||||||
boolean flag;
|
boolean flag;
|
||||||
|
@ -154,7 +80,7 @@
|
||||||
try {
|
try {
|
||||||
iresource = p_195422_1_.func_199002_a(resourcelocation);
|
iresource = p_195422_1_.func_199002_a(resourcelocation);
|
||||||
p_195422_2_.func_195664_a(iresource, this.field_147636_j + 1);
|
p_195422_2_.func_195664_a(iresource, this.field_147636_j + 1);
|
||||||
@@ -216,4 +267,21 @@
|
@@ -216,4 +235,91 @@
|
||||||
this.field_94252_e.clear();
|
this.field_94252_e.clear();
|
||||||
this.field_94258_i.clear();
|
this.field_94258_i.clear();
|
||||||
}
|
}
|
||||||
|
@ -174,5 +100,75 @@
|
||||||
+ public int getMipmapLevels()
|
+ public int getMipmapLevels()
|
||||||
+ {
|
+ {
|
||||||
+ return field_147636_j;
|
+ return field_147636_j;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ private int loadTexture(Stitcher stitcher, IResourceManager manager, ResourceLocation resourcelocation, int j, int k)
|
||||||
|
+ {
|
||||||
|
+ if (loadedSprites.contains(resourcelocation))
|
||||||
|
+ {
|
||||||
|
+ return j;
|
||||||
|
+ }
|
||||||
|
+ TextureAtlasSprite textureatlassprite;
|
||||||
|
+ ResourceLocation resourcelocation1 = this.func_195420_b(resourcelocation);
|
||||||
|
+ for (ResourceLocation loading : loadingSprites)
|
||||||
|
+ {
|
||||||
|
+ if (resourcelocation1.equals(loading))
|
||||||
|
+ {
|
||||||
|
+ final String error = "circular model dependencies, stack: [" + com.google.common.base.Joiner.on(", ").join(loadingSprites) + "]";
|
||||||
|
+ net.minecraftforge.fml.client.ClientHooks.trackBrokenTexture(resourcelocation, error);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ loadingSprites.addLast(resourcelocation1);
|
||||||
|
+ try (IResource iresource = manager.func_199002_a(resourcelocation1))
|
||||||
|
+ {
|
||||||
|
+ PngSizeInfo pngsizeinfo = new PngSizeInfo(iresource);
|
||||||
|
+ AnimationMetadataSection animationmetadatasection = iresource.func_199028_a(AnimationMetadataSection.field_195817_a);
|
||||||
|
+ textureatlassprite = new TextureAtlasSprite(resourcelocation, pngsizeinfo, animationmetadatasection);
|
||||||
|
+
|
||||||
|
+ for (ResourceLocation dependency : textureatlassprite.getDependencies())
|
||||||
|
+ {
|
||||||
|
+ if (!field_195427_i.contains(dependency))
|
||||||
|
+ {
|
||||||
|
+ func_199362_a(manager, dependency);
|
||||||
|
+ }
|
||||||
|
+ j = loadTexture(stitcher, manager, dependency, j, k);
|
||||||
|
+ }
|
||||||
|
+ if (textureatlassprite.hasCustomLoader(manager, resourcelocation))
|
||||||
|
+ {
|
||||||
|
+ if (textureatlassprite.load(manager, resourcelocation, field_94252_e::get))
|
||||||
|
+ {
|
||||||
|
+ return j;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ j = Math.min(j, Math.min(textureatlassprite.func_94211_a(), textureatlassprite.func_94216_b()));
|
||||||
|
+ int j1 = Math.min(Integer.lowestOneBit(textureatlassprite.func_94211_a()), Integer.lowestOneBit(textureatlassprite.func_94216_b()));
|
||||||
|
+ if (j1 < k)
|
||||||
|
+ {
|
||||||
|
+ // FORGE: do not lower the mipmap level, just log the problematic textures
|
||||||
|
+ field_147635_d.warn("Texture {} with size {}x{} will have visual artifacts at mip level {}, it can only support level {}." +
|
||||||
|
+ "Please report to the mod author that the texture should be some multiple of 16x16.",
|
||||||
|
+ resourcelocation1, textureatlassprite.func_94211_a(), textureatlassprite.func_94216_b(), MathHelper.func_151239_c(k), MathHelper.func_151239_c(j1));
|
||||||
|
+ }
|
||||||
|
+ if (func_195422_a(manager, textureatlassprite))
|
||||||
|
+ {
|
||||||
|
+ stitcher.func_110934_a(textureatlassprite);
|
||||||
|
+ }
|
||||||
|
+ return j;
|
||||||
|
+ }
|
||||||
|
+ catch (RuntimeException runtimeexception)
|
||||||
|
+ {
|
||||||
|
+ net.minecraftforge.fml.client.ClientHooks.trackBrokenTexture(resourcelocation, runtimeexception.getMessage());
|
||||||
|
+ return j;
|
||||||
|
+ }
|
||||||
|
+ catch (IOException ioexception)
|
||||||
|
+ {
|
||||||
|
+ net.minecraftforge.fml.client.ClientHooks.trackMissingTexture(resourcelocation);
|
||||||
|
+ return j;
|
||||||
|
+ }
|
||||||
|
+ finally
|
||||||
|
+ {
|
||||||
|
+ loadingSprites.removeLast();
|
||||||
|
+ field_195427_i.add(resourcelocation1);
|
||||||
|
+ }
|
||||||
+ }
|
+ }
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
public void func_199005_a(List<IResourcePack> p_199005_1_) {
|
public void func_199005_a(List<IResourcePack> p_199005_1_) {
|
||||||
+ net.minecraftforge.fml.common.ProgressManager.ProgressBar resReload = net.minecraftforge.fml.common.ProgressManager.push("Loading Resources", p_199005_1_.size() + 1, true);
|
+ try (net.minecraftforge.fml.common.progress.ProgressBar resReload = net.minecraftforge.fml.common.progress.StartupProgressManager.start("Loading Resources", p_199005_1_.size() + 1, true)) {
|
||||||
this.func_199008_b();
|
this.func_199008_b();
|
||||||
field_199012_a.info("Reloading ResourceManager: {}", p_199005_1_.stream().map(IResourcePack::func_195762_a).collect(Collectors.joining(", ")));
|
field_199012_a.info("Reloading ResourceManager: {}", p_199005_1_.stream().map(IResourcePack::func_195762_a).collect(Collectors.joining(", ")));
|
||||||
|
|
||||||
|
@ -27,12 +27,12 @@
|
||||||
} else {
|
} else {
|
||||||
this.func_199010_c();
|
this.func_199010_c();
|
||||||
}
|
}
|
||||||
+ net.minecraftforge.fml.common.ProgressManager.pop(resReload);
|
+ }; // Forge: end progress bar
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void func_199006_a(IResourceManagerReloadListener p_199006_1_) {
|
public void func_199006_a(IResourceManagerReloadListener p_199006_1_) {
|
||||||
+ net.minecraftforge.fml.common.ProgressManager.ProgressBar resReload = net.minecraftforge.fml.common.ProgressManager.push("Loading Resource", 1);
|
+ try (net.minecraftforge.fml.common.progress.ProgressBar resReload = net.minecraftforge.fml.common.progress.StartupProgressManager.start("Loading Resource", 1)) {
|
||||||
+ resReload.step(p_199006_1_.getClass());
|
+ resReload.step(p_199006_1_.getClass());
|
||||||
this.field_199015_d.add(p_199006_1_);
|
this.field_199015_d.add(p_199006_1_);
|
||||||
if (field_199012_a.isDebugEnabled()) {
|
if (field_199012_a.isDebugEnabled()) {
|
||||||
|
@ -40,18 +40,18 @@
|
||||||
} else {
|
} else {
|
||||||
p_199006_1_.func_195410_a(this);
|
p_199006_1_.func_195410_a(this);
|
||||||
}
|
}
|
||||||
+ net.minecraftforge.fml.common.ProgressManager.pop(resReload);
|
+ }; // Forge: end progress bar
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void func_199010_c() {
|
private void func_199010_c() {
|
||||||
+ net.minecraftforge.fml.common.ProgressManager.ProgressBar resReload = net.minecraftforge.fml.common.ProgressManager.push("Reloading", this.field_199015_d.size());
|
+ try (net.minecraftforge.fml.common.progress.ProgressBar resReload = net.minecraftforge.fml.common.progress.StartupProgressManager.start("Reloading", this.field_199015_d.size())) {
|
||||||
for(IResourceManagerReloadListener iresourcemanagerreloadlistener : this.field_199015_d) {
|
for(IResourceManagerReloadListener iresourcemanagerreloadlistener : this.field_199015_d) {
|
||||||
+ resReload.step(iresourcemanagerreloadlistener.getClass());
|
+ resReload.step(iresourcemanagerreloadlistener.getClass());
|
||||||
+ if (!net.minecraftforge.resource.SelectiveReloadStateHandler.INSTANCE.test(iresourcemanagerreloadlistener)) continue; // Forge: Selective reloading for vanilla listeners
|
+ if (!net.minecraftforge.resource.SelectiveReloadStateHandler.INSTANCE.test(iresourcemanagerreloadlistener)) continue; // Forge: Selective reloading for vanilla listeners
|
||||||
iresourcemanagerreloadlistener.func_195410_a(this);
|
iresourcemanagerreloadlistener.func_195410_a(this);
|
||||||
}
|
}
|
||||||
+ net.minecraftforge.fml.common.ProgressManager.pop(resReload);
|
+ }; // Forge: end progress bar
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -89,8 +89,6 @@ import net.minecraftforge.common.property.IExtendedBlockState;
|
||||||
import net.minecraftforge.common.property.Properties;
|
import net.minecraftforge.common.property.Properties;
|
||||||
import net.minecraftforge.fluids.FluidRegistry;
|
import net.minecraftforge.fluids.FluidRegistry;
|
||||||
import net.minecraftforge.fml.client.ClientModLoader;
|
import net.minecraftforge.fml.client.ClientModLoader;
|
||||||
import net.minecraftforge.fml.common.ProgressManager;
|
|
||||||
import net.minecraftforge.fml.common.ProgressManager.ProgressBar;
|
|
||||||
import net.minecraftforge.logging.ModelLoaderErrorMessage;
|
import net.minecraftforge.logging.ModelLoaderErrorMessage;
|
||||||
import net.minecraftforge.registries.IRegistryDelegate;
|
import net.minecraftforge.registries.IRegistryDelegate;
|
||||||
|
|
||||||
|
|
|
@ -34,13 +34,23 @@ import java.util.function.Supplier;
|
||||||
public enum SidedProvider
|
public enum SidedProvider
|
||||||
{
|
{
|
||||||
// All of these need to be careful not to directly dereference the client and server elements in their signatures
|
// All of these need to be careful not to directly dereference the client and server elements in their signatures
|
||||||
DATAFIXER(c->c.get().getDataFixer(), s->s.get().getDataFixer()),
|
DATAFIXER(
|
||||||
SIDEDINIT((Function<Supplier<Minecraft>, Function<ModContainer, Event>>)c-> mc->new FMLClientInitEvent(c, mc),
|
c->c.get().getDataFixer(),
|
||||||
(Function<Supplier<DedicatedServer>, Function<ModContainer, Event>>)s-> mc->new FMLServerInitEvent(s, mc)),
|
s->s.get().getDataFixer(),
|
||||||
STRIPCHARS((Function<Supplier<Minecraft>, Function<String, String>>)c-> ClientHooks::stripSpecialChars,
|
()-> { throw new UnsupportedOperationException(); }),
|
||||||
(Function<Supplier<DedicatedServer>, Function<String, String>>)s-> str->str),
|
SIDEDINIT(
|
||||||
|
(Function<Supplier<Minecraft>, Function<ModContainer, Event>>)c-> mc->new FMLClientInitEvent(c, mc),
|
||||||
|
s-> mc->new FMLServerInitEvent(s, mc),
|
||||||
|
()-> { throw new UnsupportedOperationException(); }),
|
||||||
|
STRIPCHARS(
|
||||||
|
(Function<Supplier<Minecraft>, Function<String, String>>)c-> ClientHooks::stripSpecialChars,
|
||||||
|
s-> str->str,
|
||||||
|
()-> str->str),
|
||||||
@SuppressWarnings("Convert2MethodRef") // need to not be methodrefs to avoid classloading all of StartupQuery's data (supplier is coming from StartupQuery)
|
@SuppressWarnings("Convert2MethodRef") // need to not be methodrefs to avoid classloading all of StartupQuery's data (supplier is coming from StartupQuery)
|
||||||
STARTUPQUERY(c->StartupQuery.QueryWrapper.clientQuery(c), s->StartupQuery.QueryWrapper.dedicatedServerQuery(s));
|
STARTUPQUERY(
|
||||||
|
c->StartupQuery.QueryWrapper.clientQuery(c),
|
||||||
|
s->StartupQuery.QueryWrapper.dedicatedServerQuery(s),
|
||||||
|
()-> { throw new UnsupportedOperationException(); });
|
||||||
|
|
||||||
private static Supplier<Minecraft> client;
|
private static Supplier<Minecraft> client;
|
||||||
private static Supplier<DedicatedServer> server;
|
private static Supplier<DedicatedServer> server;
|
||||||
|
@ -56,12 +66,13 @@ public enum SidedProvider
|
||||||
|
|
||||||
private final Function<Supplier<Minecraft>, ?> clientSide;
|
private final Function<Supplier<Minecraft>, ?> clientSide;
|
||||||
private final Function<Supplier<DedicatedServer>, ?> serverSide;
|
private final Function<Supplier<DedicatedServer>, ?> serverSide;
|
||||||
|
private final Supplier<?> testSide;
|
||||||
|
|
||||||
|
<T> SidedProvider(Function<Supplier<Minecraft>, T> clientSide, Function<Supplier<DedicatedServer>, T> serverSide, Supplier<T> testSide)
|
||||||
SidedProvider(Function<Supplier<Minecraft>,?> clientSide, Function<Supplier<DedicatedServer>,?> serverSide)
|
|
||||||
{
|
{
|
||||||
this.clientSide = clientSide;
|
this.clientSide = clientSide;
|
||||||
this.serverSide = serverSide;
|
this.serverSide = serverSide;
|
||||||
|
this.testSide = testSide;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
|
@ -73,7 +84,7 @@ public enum SidedProvider
|
||||||
return (T)this.serverSide.apply(server);
|
return (T)this.serverSide.apply(server);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throw new IllegalArgumentException("THREE SIDES? WUT?");
|
return (T)this.testSide.get();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -125,8 +125,10 @@ public class SplashProgress
|
||||||
private static final int TIMING_FRAME_THRESHOLD = TIMING_FRAME_COUNT * 5 * 1000000; // 5 ms per frame, scaled to nanos
|
private static final int TIMING_FRAME_THRESHOLD = TIMING_FRAME_COUNT * 5 * 1000000; // 5 ms per frame, scaled to nanos
|
||||||
|
|
||||||
private static final Semaphore mutex = new Semaphore(1);
|
private static final Semaphore mutex = new Semaphore(1);
|
||||||
|
*/
|
||||||
|
|
||||||
public static Void processMessages() {
|
public static void processMessages() {
|
||||||
|
/*
|
||||||
// workaround for windows requiring messages being processed on the main thread
|
// workaround for windows requiring messages being processed on the main thread
|
||||||
if (LWJGLUtil.getPlatform() != LWJGLUtil.PLATFORM_WINDOWS) return null;
|
if (LWJGLUtil.getPlatform() != LWJGLUtil.PLATFORM_WINDOWS) return null;
|
||||||
// If we can't grab the mutex, the update call is blocked, probably in native code, just skip it and carry on
|
// If we can't grab the mutex, the update call is blocked, probably in native code, just skip it and carry on
|
||||||
|
@ -134,9 +136,9 @@ public class SplashProgress
|
||||||
if (!SplashProgress.mutex.tryAcquire()) return null;
|
if (!SplashProgress.mutex.tryAcquire()) return null;
|
||||||
Display.processMessages();
|
Display.processMessages();
|
||||||
SplashProgress.mutex.release();
|
SplashProgress.mutex.release();
|
||||||
return null;
|
*/
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
private static String getString(String name, String def)
|
private static String getString(String name, String def)
|
||||||
{
|
{
|
||||||
String value = config.getProperty(name, def);
|
String value = config.getProperty(name, def);
|
||||||
|
@ -448,9 +450,10 @@ public class SplashProgress
|
||||||
drawBox(barWidth - 2, barHeight - 2);
|
drawBox(barWidth - 2, barHeight - 2);
|
||||||
// slidy part
|
// slidy part
|
||||||
setColor(barColor);
|
setColor(barColor);
|
||||||
drawBox((barWidth - 2) * (b.getStep() + 1) / (b.getSteps() + 1), barHeight - 2); // Step can sometimes be 0.
|
int step = b.getStep();
|
||||||
|
drawBox((barWidth - 2) * (step + 1) / (b.getTotalSteps() + 1), barHeight - 2); // Step can sometimes be 0.
|
||||||
// progress text
|
// progress text
|
||||||
String progress = "" + b.getStep() + "/" + b.getSteps();
|
String progress = "" + step + "/" + b.getTotalSteps();
|
||||||
glTranslatef(((float)barWidth - 2) / 2 - fontRenderer.getStringWidth(progress), 2, 0);
|
glTranslatef(((float)barWidth - 2) / 2 - fontRenderer.getStringWidth(progress), 2, 0);
|
||||||
setColor(fontColor);
|
setColor(fontColor);
|
||||||
glScalef(2, 2, 1);
|
glScalef(2, 2, 1);
|
||||||
|
|
|
@ -1,162 +0,0 @@
|
||||||
/*
|
|
||||||
* Minecraft Forge
|
|
||||||
* Copyright (c) 2016-2018.
|
|
||||||
*
|
|
||||||
* This library is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation version 2.1
|
|
||||||
* of the License.
|
|
||||||
*
|
|
||||||
* This library is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with this library; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
package net.minecraftforge.fml.common;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
|
||||||
import java.util.function.Function;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import net.minecraftforge.fml.SidedProvider;
|
|
||||||
import org.apache.logging.log4j.LogManager;
|
|
||||||
import org.apache.logging.log4j.Logger;
|
|
||||||
import org.apache.logging.log4j.message.MessageFormatMessage;
|
|
||||||
|
|
||||||
import static net.minecraftforge.fml.Logging.SPLASH;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Not a fully fleshed out API, may change in future MC versions.
|
|
||||||
* However feel free to use and suggest additions.
|
|
||||||
*/
|
|
||||||
public class ProgressManager
|
|
||||||
{
|
|
||||||
private static final Logger LOGGER = LogManager.getLogger();
|
|
||||||
private static final List<ProgressBar> bars = new CopyOnWriteArrayList<ProgressBar>();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Not a fully fleshed out API, may change in future MC versions.
|
|
||||||
* However feel free to use and suggest additions.
|
|
||||||
*/
|
|
||||||
public static ProgressBar push(String title, int steps)
|
|
||||||
{
|
|
||||||
return push(title, steps, false);
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Not a fully fleshed out API, may change in future MC versions.
|
|
||||||
* However feel free to use and suggest additions.
|
|
||||||
*/
|
|
||||||
public static ProgressBar push(String title, int steps, boolean timeEachStep)
|
|
||||||
{
|
|
||||||
ProgressBar bar = new ProgressBar(title, steps);
|
|
||||||
bars.add(bar);
|
|
||||||
if (timeEachStep)
|
|
||||||
{
|
|
||||||
bar.timeEachStep();
|
|
||||||
}
|
|
||||||
// DistExecutor.runWhenOn(Dist.CLIENT, ()->SplashProgress::processMessages);
|
|
||||||
return bar;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Not a fully fleshed out API, may change in future MC versions.
|
|
||||||
* However feel free to use and suggest additions.
|
|
||||||
*/
|
|
||||||
public static void pop(ProgressBar bar)
|
|
||||||
{
|
|
||||||
if(bar.getSteps() != bar.getStep()) throw new IllegalStateException("can't pop unfinished ProgressBar " + bar.getTitle());
|
|
||||||
bars.remove(bar);
|
|
||||||
if (bar.getSteps() != 0)
|
|
||||||
{
|
|
||||||
long newTime = System.nanoTime();
|
|
||||||
if (bar.timeEachStep)
|
|
||||||
LOGGER.debug(SPLASH, () -> new MessageFormatMessage("Bar Step: {0} - {1} took {2,number,0.000}ms", bar.getTitle(), bar.getMessage(), (newTime - bar.lastTime) / 1.0e6));
|
|
||||||
if (bar.getSteps() == 1)
|
|
||||||
LOGGER.debug(SPLASH, () -> new MessageFormatMessage("Bar Finished: {0} - {1} took {2,number,0.000}ms", bar.getTitle(), bar.getMessage(), (newTime - bar.lastTime) / 1.0e6));
|
|
||||||
else
|
|
||||||
LOGGER.debug(SPLASH, () -> new MessageFormatMessage("Bar Finished: {0} took {1,number,0.000}ms", bar.getTitle(), (newTime - bar.lastTime) / 1.0e6));
|
|
||||||
}
|
|
||||||
// DistExecutor.runWhenOn(Dist.CLIENT, ()->SplashProgress::processMessages);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Internal use only.
|
|
||||||
*/
|
|
||||||
public static Iterator<ProgressBar> barIterator()
|
|
||||||
{
|
|
||||||
return bars.iterator();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Not a fully fleshed out API, may change in future MC versions.
|
|
||||||
* However feel free to use and suggest additions.
|
|
||||||
*/
|
|
||||||
public static class ProgressBar
|
|
||||||
{
|
|
||||||
private final String title;
|
|
||||||
private final int steps;
|
|
||||||
private volatile int step = 0;
|
|
||||||
private volatile String message = "";
|
|
||||||
private boolean timeEachStep = false;
|
|
||||||
private long startTime = System.nanoTime();
|
|
||||||
private long lastTime = startTime;
|
|
||||||
|
|
||||||
private ProgressBar(String title, int steps)
|
|
||||||
{
|
|
||||||
this.title = title;
|
|
||||||
this.steps = steps;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void step(Class<?> classToName, String... extra)
|
|
||||||
{
|
|
||||||
step(ClassNameUtils.shortName(classToName)+ String.join(" ", extra));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void step(String message)
|
|
||||||
{
|
|
||||||
if(step >= steps) throw new IllegalStateException("too much steps for ProgressBar " + title);
|
|
||||||
if (timeEachStep && step != 0)
|
|
||||||
{
|
|
||||||
long newTime = System.nanoTime();
|
|
||||||
LOGGER.debug(SPLASH,new MessageFormatMessage("Bar Step: {0} - {1} took {2,number,0.000}ms", getTitle(), getMessage(), (newTime - lastTime) / 1.0e6));
|
|
||||||
lastTime = newTime;
|
|
||||||
}
|
|
||||||
step += 1;
|
|
||||||
this.message = SidedProvider.STRIPCHARS.<Function<String, String>>get().apply(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getTitle()
|
|
||||||
{
|
|
||||||
return title;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getSteps()
|
|
||||||
{
|
|
||||||
return steps;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getStep()
|
|
||||||
{
|
|
||||||
return step;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getMessage()
|
|
||||||
{
|
|
||||||
return message;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void timeEachStep()
|
|
||||||
{
|
|
||||||
this.timeEachStep = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
/*
|
||||||
|
* Minecraft Forge
|
||||||
|
* Copyright (c) 2016-2018.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation version 2.1
|
||||||
|
* of the License.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.minecraftforge.fml.common.progress;
|
||||||
|
|
||||||
|
public interface IProgressBarTracker
|
||||||
|
{
|
||||||
|
default void onBarCreated(ProgressBar bar) {}
|
||||||
|
|
||||||
|
default void onStepStarted(ProgressBar bar, int step, String message) {}
|
||||||
|
|
||||||
|
default void onStepFinished(ProgressBar bar, int step, String message) {}
|
||||||
|
|
||||||
|
default void onBarFinished(ProgressBar bar, int step, String message) {}
|
||||||
|
}
|
|
@ -0,0 +1,98 @@
|
||||||
|
/*
|
||||||
|
* Minecraft Forge
|
||||||
|
* Copyright (c) 2016-2018.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation version 2.1
|
||||||
|
* of the License.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.minecraftforge.fml.common.progress;
|
||||||
|
|
||||||
|
import net.minecraftforge.fml.common.ClassNameUtils;
|
||||||
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
|
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Not a fully fleshed out API, may change in future MC versions.
|
||||||
|
* However feel free to use and suggest additions.
|
||||||
|
*/
|
||||||
|
public final class ProgressBar implements AutoCloseable
|
||||||
|
{
|
||||||
|
private final String title;
|
||||||
|
private final int totalSteps;
|
||||||
|
private final Function<String, String> stripChars;
|
||||||
|
private final IProgressBarTracker tracker;
|
||||||
|
private volatile int step = 0;
|
||||||
|
private volatile String message = "";
|
||||||
|
|
||||||
|
public ProgressBar(String title, int totalSteps, Function<String, String> stripChars, IProgressBarTracker tracker)
|
||||||
|
{
|
||||||
|
this.title = title;
|
||||||
|
this.totalSteps = totalSteps;
|
||||||
|
this.stripChars = stripChars;
|
||||||
|
this.tracker = tracker;
|
||||||
|
this.tracker.onBarCreated(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void step(Class<?> classToName, String... extra)
|
||||||
|
{
|
||||||
|
step(ClassNameUtils.shortName(classToName) + String.join(" ", extra));
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void step(String newMessage)
|
||||||
|
{
|
||||||
|
if (step > 0)
|
||||||
|
{
|
||||||
|
tracker.onStepFinished(this, step, message);
|
||||||
|
}
|
||||||
|
step++;
|
||||||
|
message = stripChars.apply(newMessage);
|
||||||
|
tracker.onStepStarted(this, step, message);;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the current step and message.
|
||||||
|
*/
|
||||||
|
public synchronized Pair<Integer, String> getStepAndMessage()
|
||||||
|
{
|
||||||
|
return Pair.of(step, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the total number of steps.
|
||||||
|
*/
|
||||||
|
public int getTotalSteps()
|
||||||
|
{
|
||||||
|
return totalSteps;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the current title.
|
||||||
|
*/
|
||||||
|
public String getTitle()
|
||||||
|
{
|
||||||
|
return title;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized void close()
|
||||||
|
{
|
||||||
|
if (step > 0)
|
||||||
|
{
|
||||||
|
tracker.onStepFinished(this, step, message);
|
||||||
|
}
|
||||||
|
tracker.onBarFinished(this, step, message);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,129 @@
|
||||||
|
/*
|
||||||
|
* Minecraft Forge
|
||||||
|
* Copyright (c) 2016-2018.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation version 2.1
|
||||||
|
* of the License.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.minecraftforge.fml.common.progress;
|
||||||
|
|
||||||
|
import com.google.common.base.Stopwatch;
|
||||||
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
|
import net.minecraftforge.fml.DistExecutor;
|
||||||
|
import net.minecraftforge.fml.client.SplashProgress;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.apache.logging.log4j.message.MessageFormatMessage;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
|
||||||
|
import static net.minecraftforge.fml.Logging.SPLASH;
|
||||||
|
|
||||||
|
class StartupProgressBarTracker implements IProgressBarTracker
|
||||||
|
{
|
||||||
|
private static final Logger LOGGER = LogManager.getLogger();
|
||||||
|
private static final List<ProgressBar> bars = new CopyOnWriteArrayList<>();
|
||||||
|
|
||||||
|
private final boolean timeEachStep;
|
||||||
|
private final int steps;
|
||||||
|
private final Stopwatch stopwatch;
|
||||||
|
@Nullable
|
||||||
|
private Stopwatch stepStopwatch;
|
||||||
|
private String logPrefix = "";
|
||||||
|
|
||||||
|
StartupProgressBarTracker(boolean timeEachStep, int steps)
|
||||||
|
{
|
||||||
|
this.timeEachStep = timeEachStep;
|
||||||
|
this.steps = steps;
|
||||||
|
this.stopwatch = Stopwatch.createUnstarted();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBarCreated(ProgressBar bar)
|
||||||
|
{
|
||||||
|
int depth = bars.size();
|
||||||
|
logPrefix = StringUtils.repeat(" ", depth);
|
||||||
|
bars.add(bar);
|
||||||
|
DistExecutor.runWhenOn(Dist.CLIENT, ()-> SplashProgress::processMessages);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStepStarted(ProgressBar bar, int step, String message)
|
||||||
|
{
|
||||||
|
if (step == 1)
|
||||||
|
{
|
||||||
|
if (steps > 1)
|
||||||
|
{
|
||||||
|
LOGGER.debug(SPLASH, () -> new MessageFormatMessage("{0}Bar Starting: {1}", logPrefix, bar.getTitle()));
|
||||||
|
if (timeEachStep)
|
||||||
|
{
|
||||||
|
stepStopwatch = Stopwatch.createStarted();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LOGGER.debug(SPLASH, () -> new MessageFormatMessage("{0}Bar Starting: {1} - {2}", logPrefix, bar.getTitle(), message));
|
||||||
|
}
|
||||||
|
stopwatch.start();
|
||||||
|
}
|
||||||
|
if (stepStopwatch != null)
|
||||||
|
{
|
||||||
|
LOGGER.debug(SPLASH, () -> new MessageFormatMessage("{0} Bar Step: {1} - {2} - starting", logPrefix, bar.getTitle(), message));
|
||||||
|
stepStopwatch.reset();
|
||||||
|
stepStopwatch.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStepFinished(ProgressBar bar, int step, String message)
|
||||||
|
{
|
||||||
|
if (stepStopwatch != null)
|
||||||
|
{
|
||||||
|
stepStopwatch.stop();
|
||||||
|
LOGGER.debug(SPLASH, () -> new MessageFormatMessage("{0} Bar Step: {1} - {2} - took {3}", logPrefix, bar.getTitle(), message, stepStopwatch));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBarFinished(ProgressBar bar, int step, String message)
|
||||||
|
{
|
||||||
|
if (steps > 0)
|
||||||
|
{
|
||||||
|
stopwatch.stop();
|
||||||
|
bars.remove(bar);
|
||||||
|
if (steps > 1)
|
||||||
|
{
|
||||||
|
LOGGER.debug(SPLASH, () -> new MessageFormatMessage("{0}Bar Finished: {1} - took {2}", logPrefix, bar.getTitle(), stopwatch));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LOGGER.debug(SPLASH, () -> new MessageFormatMessage("{0}Bar Finished: {1} - {2} - took {3}", logPrefix, bar.getTitle(), message, stopwatch));
|
||||||
|
}
|
||||||
|
DistExecutor.runWhenOn(Dist.CLIENT, () -> SplashProgress::processMessages);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal use only.
|
||||||
|
*/
|
||||||
|
public static Iterator<ProgressBar> barIterator()
|
||||||
|
{
|
||||||
|
return bars.iterator();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
/*
|
||||||
|
* Minecraft Forge
|
||||||
|
* Copyright (c) 2016-2018.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation version 2.1
|
||||||
|
* of the License.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.minecraftforge.fml.common.progress;
|
||||||
|
|
||||||
|
import net.minecraftforge.fml.SidedProvider;
|
||||||
|
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
public class StartupProgressManager
|
||||||
|
{
|
||||||
|
private static final Function<String, String> stripChars = SidedProvider.STRIPCHARS.get();
|
||||||
|
|
||||||
|
public static void start(String title, int steps, Consumer<ProgressBar> task)
|
||||||
|
{
|
||||||
|
start(title, steps, false, task);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void start(String title, int steps, boolean timeEachStep, Consumer<ProgressBar> task)
|
||||||
|
{
|
||||||
|
try (ProgressBar bar = start(title, steps, timeEachStep))
|
||||||
|
{
|
||||||
|
task.accept(bar);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ProgressBar start(String title, int steps)
|
||||||
|
{
|
||||||
|
return start(title, steps, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ProgressBar start(String title, int steps, boolean timeEachStep)
|
||||||
|
{
|
||||||
|
StartupProgressBarTracker tracker = new StartupProgressBarTracker(timeEachStep, steps);
|
||||||
|
return new ProgressBar(title, steps, stripChars, tracker);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal use only.
|
||||||
|
*/
|
||||||
|
public static Iterator<ProgressBar> barIterator()
|
||||||
|
{
|
||||||
|
return StartupProgressBarTracker.barIterator();
|
||||||
|
}
|
||||||
|
}
|
176
src/test/java/net/minecraftforge/test/TestProgressBar.java
Normal file
176
src/test/java/net/minecraftforge/test/TestProgressBar.java
Normal file
|
@ -0,0 +1,176 @@
|
||||||
|
package net.minecraftforge.test;
|
||||||
|
|
||||||
|
import net.minecraftforge.fml.common.progress.IProgressBarTracker;
|
||||||
|
import net.minecraftforge.fml.common.progress.ProgressBar;
|
||||||
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
|
public class TestProgressBar
|
||||||
|
{
|
||||||
|
private static String getStepMessage(int step)
|
||||||
|
{
|
||||||
|
if (step == 0)
|
||||||
|
{
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return "testStep" + step;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void checkBarState(int step, String message, int expectedStepValue, int totalSteps)
|
||||||
|
{
|
||||||
|
if (step != expectedStepValue)
|
||||||
|
{
|
||||||
|
throw new IllegalStateException("Got step " + step + " but expected " + expectedStepValue);
|
||||||
|
}
|
||||||
|
if (step > totalSteps)
|
||||||
|
{
|
||||||
|
throw new IllegalStateException("ProgressBar stepped past the total: " + step + "/" + totalSteps);
|
||||||
|
}
|
||||||
|
String expectedMessage = getStepMessage(expectedStepValue);
|
||||||
|
if (!message.equals(expectedMessage))
|
||||||
|
{
|
||||||
|
throw new IllegalStateException("Got message '" + message + "' but expected '" + expectedMessage + "'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testProgressBar()
|
||||||
|
{
|
||||||
|
String title = "testTitle";
|
||||||
|
final int totalSteps = 20;
|
||||||
|
|
||||||
|
IProgressBarTracker tracker = new TestProgressBarTracker(totalSteps, title);
|
||||||
|
|
||||||
|
try (ProgressBar progressBar = new ProgressBar(title, totalSteps, s -> s, tracker))
|
||||||
|
{
|
||||||
|
String barTitle = progressBar.getTitle();
|
||||||
|
if (!title.equals(barTitle))
|
||||||
|
{
|
||||||
|
throw new IllegalStateException("Got title " + barTitle + " but expected " + title);
|
||||||
|
}
|
||||||
|
for (int i = 1; i <= totalSteps; i++) {
|
||||||
|
progressBar.step(getStepMessage(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testThreadedProgressBar()
|
||||||
|
{
|
||||||
|
String title = "testTitle";
|
||||||
|
final int totalSteps = 10;
|
||||||
|
|
||||||
|
TestProgressBarTracker tracker = new TestProgressBarTracker(totalSteps, title);
|
||||||
|
|
||||||
|
AtomicBoolean threadSawBar = new AtomicBoolean(false);
|
||||||
|
Thread thread = new Thread(() ->
|
||||||
|
{
|
||||||
|
List<ProgressBar> bars = TestProgressBarTracker.getBars();
|
||||||
|
while (bars.isEmpty())
|
||||||
|
{
|
||||||
|
Thread.yield();
|
||||||
|
bars = TestProgressBarTracker.getBars();
|
||||||
|
}
|
||||||
|
while (!bars.isEmpty())
|
||||||
|
{
|
||||||
|
for (ProgressBar bar : bars)
|
||||||
|
{
|
||||||
|
Pair<Integer, String> stepAndMessage = bar.getStepAndMessage();
|
||||||
|
int step = stepAndMessage.getLeft();
|
||||||
|
String message = stepAndMessage.getRight();
|
||||||
|
checkBarState(step, message, step, totalSteps);
|
||||||
|
threadSawBar.set(true);
|
||||||
|
}
|
||||||
|
Thread.yield();
|
||||||
|
bars = TestProgressBarTracker.getBars();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
thread.start();
|
||||||
|
|
||||||
|
try (ProgressBar progressBar = new ProgressBar(title, totalSteps, s -> s, tracker))
|
||||||
|
{
|
||||||
|
String barTitle = progressBar.getTitle();
|
||||||
|
if (!title.equals(barTitle))
|
||||||
|
{
|
||||||
|
throw new IllegalStateException("Got title " + barTitle + " but expected " + title);
|
||||||
|
}
|
||||||
|
for (int i = 1; i <= totalSteps; i++) {
|
||||||
|
progressBar.step(getStepMessage(i));
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Thread.sleep(1);
|
||||||
|
}
|
||||||
|
catch (InterruptedException ignored)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!threadSawBar.get())
|
||||||
|
{
|
||||||
|
throw new IllegalStateException("Thread never saw any progress bars");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class TestProgressBarTracker implements IProgressBarTracker
|
||||||
|
{
|
||||||
|
private static final List<ProgressBar> bars = new CopyOnWriteArrayList<>();
|
||||||
|
private final AtomicInteger stepped = new AtomicInteger(0);
|
||||||
|
private final int totalSteps;
|
||||||
|
private final String title;
|
||||||
|
|
||||||
|
public TestProgressBarTracker(int totalSteps, String title)
|
||||||
|
{
|
||||||
|
this.totalSteps = totalSteps;
|
||||||
|
this.title = title;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBarCreated(ProgressBar bar)
|
||||||
|
{
|
||||||
|
bars.add(bar);
|
||||||
|
int expectedStepCount = 0;
|
||||||
|
Pair<Integer, String> stepAndMessage = bar.getStepAndMessage();
|
||||||
|
Integer step = stepAndMessage.getLeft();
|
||||||
|
String message = stepAndMessage.getRight();
|
||||||
|
checkBarState(step, message, expectedStepCount, totalSteps);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStepStarted(ProgressBar bar, int step, String message)
|
||||||
|
{
|
||||||
|
int expectedStepCount = stepped.incrementAndGet();
|
||||||
|
checkBarState(step, message, expectedStepCount, totalSteps);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStepFinished(ProgressBar bar, int step, String message)
|
||||||
|
{
|
||||||
|
int expectedStepCount = stepped.get();
|
||||||
|
checkBarState(step, message, expectedStepCount, totalSteps);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBarFinished(ProgressBar bar, int step, String message)
|
||||||
|
{
|
||||||
|
bars.remove(bar);
|
||||||
|
int expectedStepCount = stepped.get();
|
||||||
|
checkBarState(step, message, expectedStepCount, totalSteps);
|
||||||
|
if (step != totalSteps)
|
||||||
|
{
|
||||||
|
throw new IllegalStateException("ProgressBar did not finish: " + title + ".\nSteps: " + step + "/" + totalSteps);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<ProgressBar> getBars()
|
||||||
|
{
|
||||||
|
return bars;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue