From 290cf3fd22f5845aefcefbd61238cc93a2f262df Mon Sep 17 00:00:00 2001 From: JFronny Date: Tue, 27 Jun 2023 23:31:57 +0200 Subject: [PATCH] Initial commit --- .gitignore | 118 ++++++++++++++++++ .woodpecker.yml | 1 + LICENSE | 21 ++++ README.md | 3 + build.gradle.kts | 14 +++ gradle.properties | 16 +++ settings.gradle.kts | 9 ++ .../mixin/ResourcePackOrganizerMixin.java | 53 ++++++++ .../resources/assets/async-pack-scan/icon.png | Bin 0 -> 10538 bytes .../async-pack-scan.client.mixins.json | 12 ++ .../jfronny/aps/AsyncResourcePackManager.java | 9 ++ .../gitlab/jfronny/aps/impl/VoidFuture.java | 34 +++++ .../aps/mixin/ResourcePackManagerMixin.java | 25 ++++ .../resources/async-pack-scan.mixins.json | 12 ++ src/main/resources/fabric.mod.json | 34 +++++ .../mixin/ResourcePackManagerMixin.java | 17 +++ .../async-pack-scan-testmod.mixins.json | 12 ++ src/testmod/resources/fabric.mod.json | 9 ++ 18 files changed, 399 insertions(+) create mode 100755 .gitignore create mode 100755 .woodpecker.yml create mode 100755 LICENSE create mode 100644 README.md create mode 100644 build.gradle.kts create mode 100644 gradle.properties create mode 100644 settings.gradle.kts create mode 100644 src/client/java/io/gitlab/jfronny/aps/client/mixin/ResourcePackOrganizerMixin.java create mode 100644 src/client/resources/assets/async-pack-scan/icon.png create mode 100644 src/client/resources/async-pack-scan.client.mixins.json create mode 100644 src/main/java/io/gitlab/jfronny/aps/AsyncResourcePackManager.java create mode 100644 src/main/java/io/gitlab/jfronny/aps/impl/VoidFuture.java create mode 100644 src/main/java/io/gitlab/jfronny/aps/mixin/ResourcePackManagerMixin.java create mode 100644 src/main/resources/async-pack-scan.mixins.json create mode 100644 src/main/resources/fabric.mod.json create mode 100644 src/testmod/java/io/gitlab/jfronny/aps/testmod/mixin/ResourcePackManagerMixin.java create mode 100644 src/testmod/resources/async-pack-scan-testmod.mixins.json create mode 100644 src/testmod/resources/fabric.mod.json diff --git a/.gitignore b/.gitignore new file mode 100755 index 0000000..3c37caf --- /dev/null +++ b/.gitignore @@ -0,0 +1,118 @@ +# User-specific stuff +.idea/ + +*.iml +*.ipr +*.iws + +# IntelliJ +out/ +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Compiled class file +*.class + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Package Files # +*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + +*~ + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# .nfs files are created when an open file is removed but is still being accessed +.nfs* + +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +# Windows thumbnail cache files +Thumbs.db +Thumbs.db:encryptable +ehthumbs.db +ehthumbs_vista.db + +# Dump file +*.stackdump + +# Folder config file +[Dd]esktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msix +*.msm +*.msp + +# Windows shortcuts +*.lnk + +.gradle +build/ + +# Ignore Gradle GUI config +gradle-app.setting + +# Cache of project +.gradletasknamecache + +**/build/ + +# Common working directory +run/ + +# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) +!gradle-wrapper.jar diff --git a/.woodpecker.yml b/.woodpecker.yml new file mode 100755 index 0000000..f2c1117 --- /dev/null +++ b/.woodpecker.yml @@ -0,0 +1 @@ +#link https://pages.frohnmeyer-wds.de/scripts/jfmod.yml \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100755 index 0000000..4dac429 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2023 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..7b8d37a --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +AsyncPackScan makes pack scanning in the resource pack organizer screen asynchronous. + +This has unintended consequences because no proper support for concurrency is in place, but massively speeds up the screen with some mod combinations. \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts new file mode 100644 index 0000000..0ce8d0b --- /dev/null +++ b/build.gradle.kts @@ -0,0 +1,14 @@ +import io.gitlab.jfronny.scripts.* + +plugins { + id("jfmod") version "1.3-SNAPSHOT" +} + +dependencies { + modImplementation("io.gitlab.jfronny.libjf:libjf-base:${prop("libjf_version")}") + + // For testing in dev environment + modLocalRuntime("net.fabricmc.fabric-api:fabric-api:0.83.0+1.20") + modLocalRuntime("io.gitlab.jfronny.libjf:libjf-devutil:${prop("libjf_version")}") + modLocalRuntime("com.terraformersmc:modmenu:7.0.1") +} diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000..1f74513 --- /dev/null +++ b/gradle.properties @@ -0,0 +1,16 @@ +# https://fabricmc.net/develop/ +minecraft_version=1.20 +yarn_mappings=build.1 +loader_version=0.14.21 + +maven_group=io.gitlab.jfronny +archives_base_name=async-pack-scan + +#modrinth_id=slyde +#modrinth_required_dependencies=libjf +#modrinth_optional_dependencies=modmenu +#curseforge_id=411386 +#curseforge_required_dependencies=libjf +#curseforge_optional_dependencies=modmenu + +libjf_version=3.8.0 diff --git a/settings.gradle.kts b/settings.gradle.kts new file mode 100644 index 0000000..381ab48 --- /dev/null +++ b/settings.gradle.kts @@ -0,0 +1,9 @@ +pluginManagement { + repositories { + maven("https://maven.fabricmc.net/") // FabricMC + maven("https://maven.frohnmeyer-wds.de/artifacts") // scripts + gradlePluginPortal() + } +} + +rootProject.name = "async-pack-scan" diff --git a/src/client/java/io/gitlab/jfronny/aps/client/mixin/ResourcePackOrganizerMixin.java b/src/client/java/io/gitlab/jfronny/aps/client/mixin/ResourcePackOrganizerMixin.java new file mode 100644 index 0000000..c4b7716 --- /dev/null +++ b/src/client/java/io/gitlab/jfronny/aps/client/mixin/ResourcePackOrganizerMixin.java @@ -0,0 +1,53 @@ +package io.gitlab.jfronny.aps.client.mixin; + +import io.gitlab.jfronny.libjf.LibJf; +import net.minecraft.client.gui.screen.pack.ResourcePackOrganizer; +import net.minecraft.resource.ResourcePackManager; +import net.minecraft.resource.ResourcePackProfile; +import org.spongepowered.asm.mixin.*; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import java.util.List; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; + +@Mixin(ResourcePackOrganizer.class) +public class ResourcePackOrganizerMixin { + @Shadow + @Final + private ResourcePackManager resourcePackManager; + @Shadow @Final private List enabledPacks; + @Shadow @Final private List disabledPacks; + + @Unique private Future aps$packScan = null; + + /** + * @author JFronny + * @reason Make reloading asynchronous + */ + @Overwrite + public void refresh() { + if (aps$packScan != null) aps$packScan.cancel(true); + Future[] task = new Future[1]; + aps$packScan = task[0] = resourcePackManager.scanPacksAsync(() -> { + enabledPacks.retainAll(resourcePackManager.getProfiles()); + disabledPacks.clear(); + disabledPacks.addAll(resourcePackManager.getProfiles()); + disabledPacks.removeAll(enabledPacks); + if (aps$packScan == task[0]) aps$packScan = null; + }); + } + + @Inject(method = "apply()V", at = @At("HEAD")) + void onApply(CallbackInfo ci) { + if (aps$packScan != null) { + try { + aps$packScan.get(); + } catch (InterruptedException | ExecutionException e) { + LibJf.LOGGER.error("Pack scan was interrupted", e); + } + } + } +} diff --git a/src/client/resources/assets/async-pack-scan/icon.png b/src/client/resources/assets/async-pack-scan/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..cda9b84ccc26ba051d40e74882ba7e483d301651 GIT binary patch literal 10538 zcmb7qby!qy)a}qHtw@(B2na)WcZhU5fHE{l4mC7Lmx4%1HwcJ;bV-TCkRn~u!l-oL z7k}Sfk22lHH1&VY&7w&`V2(kXn9GPEMq}%rT&}glt$M~_K@qX4tSZ+&OOSeZl*~97}MHSNAoM@uAFCHkBYea_$ z>^>4Zi7;(ffQG?npZ`o%#-XvCBDunAZ?3zYbk|IW4Fl0CGTg^TI)_6e*mo-B`M&qo zQXp>S!Mk=HJZmY{s=C@uvXOQo7_45vilku}eG{8+uFozX4Gt!S=H%@Cvo*W!t?0_5|}PuRV& z5%9__7Zqc72n71z=EU$Wl=cKK;vrO@D&lS6(%xf$V7xe60xwY`6paw_&M#kDIUykO zZdNZ4R+da&b_iQ0W!0xzhQY*?5C{`QRY6wIduG>EHQ}M*q~sfFQB?Azsi|oeo@Mh( z#}@-s-Ix?Ak@U|ll#Pz6WaKPRx9{_M2U9XRV!h+!dA=I%*-`#z9duat|8X9kw)&y=ziYne zc}$p(RdOAN8Z+nK*q++38~>o+L4)<7O7Q=2US~S&-je96JHoz7Fn7>gIy2$#_;;R3 z1a(~3k|0)liCV7Cc234p+Fq%%hBD#vWTRZS##mrY2)kB`Y(reCIHe!+^F5ENT0)rc ze-D^n-O1W`A(okE#JSS{C>zG#vGE3@X&!p@H>G{)>~IJCTg7UlZa*nyQf#)A0sJn~ zq<-wsPDoYD-`iQzdoaYw$xLHPeJ~ zN?70##7k4hopz*n^ypDTz@=E0?_MM7mwR9qoosgLy^)>6-%Ft+7JO;XtBsxuWq@13 zgn%$JyFy=h6j+mZOG(4;Gaxr}Q3ts`S(K+WLRf|^9Lcx$7Fr2V``|sDQu48_+TBm~ zbVH6p#Myc97wo}QjA2*j)6?0~Zega_lW0hl@yeGrBEibrtTnO1mhNKiW}V)fVkkALA$# z13tu2$bpGJQzPS>&-LYTb#rqJx8E{>tx$$-{cOpkeeY}Nd}pWZLwLgh618YZpEMZ9 zf2G_IvU4cbwx5Z94%TpU6JM6}IbRwRKIVkIAp8}$*JT&mRHjUgu4Df$GVq?47bU2N zgf|0gJQ+h;RZ}1%7?8^VMzDw(85yY>#VW<)ARIt@i5|zv?BbPme34Rqu%8s8suu-_ zoUGQfciOJs_t1Sc_F8+i!#VJL_GD(NEu7NK8$*_qDP^GZ*#FfFeAGSw>+-pj-=eUf z?5H$N98abOhy~*QS}uJH3bw)fPu}uveSW=1r+y5xv$OaiOX^L2QY5H-$J~U3gi)t@ zX}PN73;)TRh0i~($-ex>|MK4K76L$0t5olob5+|JN5JKd`GaiK>KkQ-&fZ?!8(@Wo zV)-&b-cd+r3^6D5r&|yB zOFnA7a{YpFyOyIF2au=F&7fL_CdI(wrl}9wJou);7C@(*+R^$+=>z9#>>-IeHnBcby`zVhBy2PNypx)G*Vt8c4%zq)DkWK^SKG5UW~YVh;gGf7O&cI7qQs*}tmDl0qPWP`FNP1^8+{ z8F8BYd^7ea8VV4WjiTlMThsi%1&NftK1E6EKVDLnK6~TyHTAN_h*KT2K!=?$LY|X? zfc!R&da*7z_OT5(?)jd~Et5~x4(y*wfR8VY0q|c001Wm)+m7ML2I-W(0*jkBdhDMh zqK(MZzym7@N_BjToR*dr667b@R^SxA6w0txZMed-h@5u({9a&r zg!ke67D9`SoQH~#(3|7ZTjH~?1+7JT13a%k2Xt3n{ze~cvcG<>Q4IJx{DAu21GsmVO;#6>Ixr}u zsxTEH;KLM(Y{G(rS}NO+L{~%V8|W9A2b`{HKE-*Tm9;WyXs!sFbgAB_j`$59iiZ0} z`RHsBnI18gPD?)HzrV=@%NvEVQCvm}3iCUMulp?>@0Z4JivAp4SX@jfco51beV9EMvI>DEOV|4SVyO>(twCK&dB8{pPgH5Lmm5WzL^$q^#LNsx>y{mr`3P{dAS8HWvb(X*e8nehdgzM5NKX$EpRdP3&4;qC!7V#6n;VV(a%->Qce2}uSM>vG(kCvXC&pB}`RuBY^|8yxy;{gt>8f%e&|Bc!=23pgrQ2a&`VyaL^4p2f zS%}c3dnMp!h^NRT#Hf&K#^mU6qzT7oiKt5{pR_vYoxC;3K{bNZg+^@u5oKX8MQhlue7i`j$Px35b#zC(!Oi_9x40PB^c zyP}m1fDEU@O(Cb_Fm0Y!YJ>^ZDfC9>38$1lf34qp)8MZvp4Dq{B*$VjY;tgHiHf5Y zi!83B-7zU*!g7((z9F(EcrbiSQ7ghWR#z-u4C<$=n+IY#nOZE>D{O@FZ`D|mC}>_F zKni0=ZEF>(_D^B@`aS<}e>PZ1o6xsD9&aK6@!lU2=2~)F^gq6wmGCk9Da1#vTX)h^ z;%tnaNB6DgJH2Lji}xR9vCQGb8s#LxMsXjqdH(C5J0XEyEU$3kZ{vg6Q+NedBZJ-@ z`)TR}wz#=;sl$16z_GZ*)ye9Q>FH|4)zAhnG=tN8lU39AeTf_JpP!$X7?l6^XC#rn z_?;N@wic$9=P|QVW(Imt0;Na!`ibkZ;FrE7LY7-S4_zTFSkej69%{_nE^Q3+^`N%` z4h9YQ4Ps9&iFa;l()X&;ZtK6;0bn(2rn@bwJ3t?$iR)GNbSa-S;TW@oGB8pxe*OOa zU8B5ySj*w}XP^1m^-E0He1KF3G7$)eFzLpe_wtKUk^$JN?sf}~ zLS4=Q`?RyI<69F7Y+j;I8-Upy=UlvtH7M86mHC{tteK(;O7#(n*&GmF(jjFSMunQdhW7VI@xD8|)vz>pwtI*?@`2s^(oW{pury}1 zEteaVl$4|*=9Sw|g(%vp8S9SUf8}^X{%4IaV&GUoVn~rx;hPAtuN(XC?1$z{8@h6hrw<@XOX zKnmZydrv0*UJ+>Z5tPiCMlt+&BW~-_jjjW_muo&ft?K7rHfc$ZJFXDP=QOpaptm^% z-(fYeeI0>8Y;ZPK3lETFA->$BS%WV?xJW9lA5+ADG70aPeEQ+aIpFBj&uOyjK;v(- z>jQ;RkLG!m-X*%R9Y3HRH9?~e7)w@L+Xk!w)a{M_SPJqK9~C`>)tS@{(wB3ekECdZ zi;9VTQiONB$`W}wkyAQb>xCDJ@onwXz2M(&zBoM3lpi=lIMa*QX@(|YP@9-y|EP&$ znaOT5ENxJ7Oi6rU>RX5Y6J1UJsqsflOT^l`2}tc{wWK3<_wo8jq)wjqBbO?3VnD0R zAKzL!IGD%_Aa5QdTau)XxC4Y_Mmw-Wpl76Q>T5qumMzkw>o{Ju8RuZK5^3@{^?@}l zyEN!w42F4a9hxn=-`I~p;iCHb`l`QAjp$^nyPgvzLF=}aF7e*tW@^~8 zlW$>b!ruEyIo}Buk0(&&W=;zk6lAzDTAU?a7yjFU(KgWdCS<9GEvsj<=}B9HSrw(K zvR$W*l72^IK5N8puc>AlubU2<>Liq5XdE_cU+1#F{uG#8U;Kk;yF_MfaY|i!ewfkv zHm~Qx7UIL&V*=@ksi!S6$_Z*L6<9eo>eTuVVh)k>3pN5Y#$m+%7_m}1VU{(w1-d4+IrIY41^Lp!wj%TxTt$ zghGH+&OQ2w^A9$4s3!vG?DMx{VRew(wV(|c-@c$Vr-kgzHNvY3`yX~K-!%6ij!V3@ z8{wEn@MB-%=e`g8ZO!IMnp-2?r|A#+0*_mVrO{9gKH+!RB~v?w`q{3dfd9bw1x$A& zQ1aDAu(3}2ELe*-nPDZY6R-@YW<2A2DTI_B*ICY1p_l=^^0wiI!yD>bYH9Qzg7jEA zZ3Vtq^6{1yF1EYlMc=~ZxYbo8e}&5Pn@JO|IV#XAXxKZ0I`(v z$$+alIy(ATUvCpn9(`4ug}lw(cESuU1-zl5p`pGwCZ2-YsOZ8CY@mu(OWVq?3;1bp zHqV}{k}_mnQ80LTOc|pHr<;2DRJ{|EoQNf93zY{aBY3Ly^rayX7|!1e{;Ahc5-IQG z6^+dMgd-oTF`Io-)L4K{EAO74n^Ta=?z_5bD<$633s*yfWz?X8Vp67wNo1qAS$s)v znyC9C08GtolM0I7)#_adu}?pgRs3lkMGDs+2HNN)+S~A@rJ_Uj>{2wI)&jYyl>b8U zgIX2q2W#k!K0kMU(j_D;T;w#7wmv;0&I14^4y^c+w1`Rt8C`f=4Tkx9z2R|@4S;R8de3-L6cGlF6Gg! z5H@&2RXG&F_bTs9DLa~_!rgDx;@nssh}iA*(a z^2=$24bzFoLUa%g%*v&DCS#Ltg$~+yrLqUsZYDLrS)QZY7xSWiVfOyi4Ir-L{5s8+V-vd|Z^8|C@^hoex{9ZTS_upF`V=2Z3W{%TOIdD9@n zf-lV@8ET@{AJKjM)2S#y_SqLL)8Acxox7G@O3Na12s^GRB?BV4faxn9H~zFND59wQ zHnUSeIAn3U@W!yZ3W%##V5)Wf^CC(Ecq6IpVx|E6VLluCqG0X@kmBOv64cr%d2sFz z66SY0U@nxYniNYC0@cm)SEIex%F$FlS+;h;e`?|2Fz~HwV2zI^Ee7%iSVvc-gr}JjhP`DHQRmvX8cjLXI9au%T3?-Uedv#E`1kQ>Q((> zz$}f(N9*{@{Y_#6G-Du}WJ66OgvN};oyWD-tcqKag4?v|RY1FQJT>&rgJ3_#3My+Q zKI*V{MD5%aZ`s7ugeWq!)j&KQ^;HML_bb_u*mdHbV~gsKc`Ci#?89If z!=95={bXV&mg?-_ zN#Py8Mdb>EXB-_rL$nm!d5yU>Gd0;eWC${3U9?Y@qV59GTzX#(h*!(uM@rWvPWTs8 z%{fmsJY--pA5}E7l>{kc!qS?6tdm(D8@(J*fB4cNAMmP`Q+e#o#KGT<&;1N|-+N{{ zgLZe73Lix@AG(+n^~9PAuN3F$>>snU=(V~O)P$!=3+#S{ZO7(*8;zg+pjJft>{<6; z*~k2o_H`;vpoe#){Q>UW<MOgRLHG< zRuQ=VO!c6Wd7&Q$ij)z}uPc5Cd|YA87)xIYWvv0Drc^`iyH5m#P`0I*^pA;SX;rFsE7&2J6U(yJ=nPT;DyVjOk%fjy__`vC4VMZC^K| zvx3i`n7{eMy~8SYe0-b*$ydU+Q>K~$QbaSIn2b#JaV4LhK*fHrYs<;n)8|NbS^k0} zKj&Dh;G$Qmck|?@o2a`JPruw_$4wQQgg!7l*z{~(e_Ak^Lt-VCx$^U8cb?ne&*i-W zd!|Y-IiDqY5lKlcM56G#gOohD(_H=X9 z)ukShLS{DxVZOaW#q2ILSRHIIR96Q#d!c78pY!l&^-sY`qq3dd-N(nie0A9_u*k!O zlV4QQjOK4g-c0de$W|N1W&I41hiSCsve>dI;bQl4N(WK`i%ULd?K4Khx7CHT^4M6~ za_ma}_&532=~8=ejDMusV2o4xJUc0kT4e96ozEiz+ogYZQkF;TL8EA6g#Tp)j`ocogCn%V=KGg3i`va%r4hFddVW9JUBJqM|o;0YFS>1?16WNsp_$DimV`%yOp@9XXjF~L4L#}798H*by{yeSdo7konA`5~=@oK) zE^NFhkTqQEee=t)AvjAgOkS zMi~N`sx;-dZUU18z#(9B#o^RnmUL;WIJ?)PIlu$DZq=F zhy?p5;!(Ef=Yrakv!zx#-TXB2k$LWvCe$ihbxoTsEOP)H93)fRsKv=HB`syvk?)lp z7;HMV_Xzy|IB7-9OV?h>coEsv#fW%0l}~=^V#-EtvjdyaaYpaKvD5J7)%r zxdhyYymC&DN90M2<1NTD9YkF$<%qVXlj>p6XIVXENU{DoBdR4l=@Z!>wgQB?Q#&3l z*H`CYP?Hq}&-&S8skt`+1nocy_iX%@XS0ENrw$hqkDbdX2k|Z^2lh^m@_i!L z+*`yQt-AX6eD46IFzqxmJuM4{TdG|VveICeC_IyqT=C|b?q>|G zfQv$c053i@UlTYCDcN^x^1D zl~BAIvDZS=-5cy&TY~p2R(j%Hp#W$-b?Q<8=&or3xO)YiSDL12- zP4K@=@P@NvgKruf-Fz27SSZjF#q74lk*xL*{!ufJ!H7)X<mfUq>^GrU^=Yd@aDM_=j+oBEE1T(0|VqmAEQaq!xzDUCLw6g7Dbk(sD#yNsrP?nueJ)yB!RB|vt~ zy2)N&$JVF8b9G5#+s2C6-@N`&ZWhU=(w{j4o(pvozp~hZt<7%*Vtp^SOSooWVnnH< zc10D26Yo8m-&W4_Josk})?+g+a&7QSRFy}o?98Hx1U^w%87LWJU~5NHBPiLdN6y5> zd~1o+$z?obKQ#GGesM_{jL944fBTkqGlEI-uKIjU+<#L5r1|yPlzf1(*fT`2J*}vJ z$2U&IPLpSSOrn0bjsXAs6UEQZ+KWVFz4)lV4l!!gyG&phY={*(B+?Y6>PIP@G8`rKs;1%f%^8smK@O(q+t7DQVS!+Bn|?Ce)IBZOwV z&ZA@t8Ypvl^uhUvyQ(W%NqU<5Yhn4M{gb*lOF|@*DoT&H7kdtu?!WnJ+h<|z)+&Nd zymITTZO5M5GxIvMWF^@_cJt|Od+GXqj8m$s7I%nrleDQE#}sv6m-c;ZfF$C{G)Abi z%^MT`JcArGvlAOnlDI51R$oBW-%nU-c=VKAt%d5+8lRt#f-h`@4(888Q*)NHVm6}1 zCdd7rT44%Xs_EYe&lPn!!1vK7>E@wH|2_jbg0^ zejm{&M-nxnF?&I)nE3h4_y^{fwFOQVlI}9A8)q(uwRh^&ZSUDK1e@GNn$+_V$YwAQ zm9sCJkd~hm7;)xJ+AEH^%7P@Nd(L(T(me|FODqmQ*|VcND{}n$p((jPi$-B=zGUwi z5f*>JK*U;;aGf(`qtRX=SbO4@5&7i>@gTF?U4a8hQ`K&iVn3B)pN_C3Of5-X1+}4| zB&s>4l-O9^n_`A!*X#bkW_Fk<6r{%=)vQY(a_|v%3aeNgrdTq&y67QV-dbh%3}$;t z{BHMeZfoVJ%5e>^m#i;=Ev`0srhy1Myg`F!-e^P8R}_%>#vQ5ai~Sc9FGerEq|5a@ z(9tip=f@SiKiM>r6CR>2m@@ak7Dked z;tD$#5^CiEfs%DFulgq&Pyt%ihJz+;*kKJ|)4ldOO#DG3>hdK;#nSDEd!$p9UQan+ z9&|HW(X@SLpy`?5Ry-hI-1g853|fEm(Q;66pCd}o#$ji|Pbwjxy`9`8I?o+T@9Z+! z?CFnv%sS0aJcw$e4n{&;M%7;~J(P+2?pRG+18FlynRvLy>lHTLa9R zS)+++Hz)0~bLv_W(qNABYdbxG=siwci?_NNwhhH;RgOh0slaAs1zw$My|kW0RjQ3} z?-kiAMp=KhTcwuLuC(x~o@`w0-Cy0711X&S{P!dKOS=t*&_16+9rnawNx63`{O2A7M$#KTRF}p-0C^K$NEItL-a5)6TE2Wyv_Mn)BCJp f0g3D{uJM>zp_syNKGTD*%t2HYH54l4o`?J&Zy&7j literal 0 HcmV?d00001 diff --git a/src/client/resources/async-pack-scan.client.mixins.json b/src/client/resources/async-pack-scan.client.mixins.json new file mode 100644 index 0000000..2640283 --- /dev/null +++ b/src/client/resources/async-pack-scan.client.mixins.json @@ -0,0 +1,12 @@ +{ + "required": true, + "minVersion": "0.8", + "package": "io.gitlab.jfronny.aps.client.mixin", + "compatibilityLevel": "JAVA_16", + "client": [ + "ResourcePackOrganizerMixin" + ], + "injectors": { + "defaultRequire": 1 + } +} diff --git a/src/main/java/io/gitlab/jfronny/aps/AsyncResourcePackManager.java b/src/main/java/io/gitlab/jfronny/aps/AsyncResourcePackManager.java new file mode 100644 index 0000000..4429242 --- /dev/null +++ b/src/main/java/io/gitlab/jfronny/aps/AsyncResourcePackManager.java @@ -0,0 +1,9 @@ +package io.gitlab.jfronny.aps; + +import java.util.concurrent.Future; + +public interface AsyncResourcePackManager { + default Future scanPacksAsync(Runnable callback) { + throw new IllegalStateException("Async pack scan not injected"); + } +} diff --git a/src/main/java/io/gitlab/jfronny/aps/impl/VoidFuture.java b/src/main/java/io/gitlab/jfronny/aps/impl/VoidFuture.java new file mode 100644 index 0000000..7d0a570 --- /dev/null +++ b/src/main/java/io/gitlab/jfronny/aps/impl/VoidFuture.java @@ -0,0 +1,34 @@ +package io.gitlab.jfronny.aps.impl; + +import org.jetbrains.annotations.NotNull; + +import java.util.concurrent.*; + +public record VoidFuture(Future future) implements Future { + @Override + public boolean cancel(boolean mayInterruptIfRunning) { + return future.cancel(mayInterruptIfRunning); + } + + @Override + public boolean isCancelled() { + return future.isCancelled(); + } + + @Override + public boolean isDone() { + return future.isDone(); + } + + @Override + public Void get() throws InterruptedException, ExecutionException { + future.get(); + return null; + } + + @Override + public Void get(long timeout, @NotNull TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { + future.get(timeout, unit); + return null; + } +} diff --git a/src/main/java/io/gitlab/jfronny/aps/mixin/ResourcePackManagerMixin.java b/src/main/java/io/gitlab/jfronny/aps/mixin/ResourcePackManagerMixin.java new file mode 100644 index 0000000..ddebf31 --- /dev/null +++ b/src/main/java/io/gitlab/jfronny/aps/mixin/ResourcePackManagerMixin.java @@ -0,0 +1,25 @@ +package io.gitlab.jfronny.aps.mixin; + +import io.gitlab.jfronny.aps.AsyncResourcePackManager; +import io.gitlab.jfronny.aps.impl.VoidFuture; +import net.minecraft.resource.ResourcePackManager; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +import java.util.concurrent.ForkJoinPool; +import java.util.concurrent.Future; + +@Mixin(ResourcePackManager.class) +public abstract class ResourcePackManagerMixin implements AsyncResourcePackManager { + private static final ForkJoinPool APS$POOL = ForkJoinPool.commonPool(); + @Shadow + public abstract void scanPacks(); + + @Override + public Future scanPacksAsync(Runnable callback) { + return new VoidFuture(APS$POOL.submit(() -> { + scanPacks(); + callback.run(); + })); + } +} diff --git a/src/main/resources/async-pack-scan.mixins.json b/src/main/resources/async-pack-scan.mixins.json new file mode 100644 index 0000000..5ce5911 --- /dev/null +++ b/src/main/resources/async-pack-scan.mixins.json @@ -0,0 +1,12 @@ +{ + "required": true, + "minVersion": "0.8", + "package": "io.gitlab.jfronny.aps.mixin", + "compatibilityLevel": "JAVA_16", + "mixins": [ + "ResourcePackManagerMixin" + ], + "injectors": { + "defaultRequire": 1 + } +} diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json new file mode 100644 index 0000000..2e4584f --- /dev/null +++ b/src/main/resources/fabric.mod.json @@ -0,0 +1,34 @@ +{ + "schemaVersion": 1, + "id": "async-pack-scan", + "version": "${version}", + "name": "Async Pack Scan", + "description": "Speeds up the resource pack organizer screen", + "authors": ["JFronny"], + "contact": { + "email": "projects.contact@frohnmeyer-wds.de", + "homepage": "https://jfronny.gitlab.io", + "issues": "https://git.frohnmeyer-wds.de/JfMods/Slyde/issues", + "sources": "https://git.frohnmeyer-wds.de/JfMods/Slyde" + }, + "license": "MIT", + "environment": "*", + "icon": "assets/async-pack-scan/icon.png", + "mixins": [ + "async-pack-scan.mixins.json", + { + "config": "async-pack-scan.client.mixins.json", + "environment": "client" + } + ], + "depends": { + "fabricloader": ">=0.12.0", + "minecraft": "*", + "libjf-base": ">=2.1.3" + }, + "custom": { + "loom:injected_interfaces": { + "net/minecraft/class_3283": ["io/gitlab/jfronny/aps/AsyncResourcePackManager"] + } + } +} diff --git a/src/testmod/java/io/gitlab/jfronny/aps/testmod/mixin/ResourcePackManagerMixin.java b/src/testmod/java/io/gitlab/jfronny/aps/testmod/mixin/ResourcePackManagerMixin.java new file mode 100644 index 0000000..dcd74fd --- /dev/null +++ b/src/testmod/java/io/gitlab/jfronny/aps/testmod/mixin/ResourcePackManagerMixin.java @@ -0,0 +1,17 @@ +package io.gitlab.jfronny.aps.testmod.mixin; + +import io.gitlab.jfronny.libjf.LibJf; +import net.minecraft.resource.ResourcePackManager; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(ResourcePackManager.class) +public class ResourcePackManagerMixin { + @Inject(at = @At("TAIL"), method = "scanPacks()V") + private void scanPacks(CallbackInfo info) throws InterruptedException { + Thread.sleep(100); + LibJf.LOGGER.info("Scanned Packs"); + } +} diff --git a/src/testmod/resources/async-pack-scan-testmod.mixins.json b/src/testmod/resources/async-pack-scan-testmod.mixins.json new file mode 100644 index 0000000..b10244b --- /dev/null +++ b/src/testmod/resources/async-pack-scan-testmod.mixins.json @@ -0,0 +1,12 @@ +{ + "required": true, + "minVersion": "0.8", + "package": "io.gitlab.jfronny.aps.testmod.mixin", + "compatibilityLevel": "JAVA_16", + "mixins": [ + "ResourcePackManagerMixin" + ], + "injectors": { + "defaultRequire": 1 + } +} diff --git a/src/testmod/resources/fabric.mod.json b/src/testmod/resources/fabric.mod.json new file mode 100644 index 0000000..231d9bd --- /dev/null +++ b/src/testmod/resources/fabric.mod.json @@ -0,0 +1,9 @@ +{ + "schemaVersion": 1, + "id": "async-pack-scan-testmod", + "name": "Async Pack Scan Testmod", + "version": "1.0", + "environment": "*", + "entrypoints": {}, + "mixins": ["async-pack-scan-testmod.mixins.json"] +} \ No newline at end of file