ParticleResources.java

net.minecraft.client.particle.ParticleResources

信息

  • 全限定名:net.minecraft.client.particle.ParticleResources
  • 类型:public class
  • 包:net.minecraft.client.particle
  • 源码路径:src/main/java/net/minecraft/client/particle/ParticleResources.java
  • 起始行号:L43
  • 实现:PreparableReloadListener
  • 职责:

    TODO

字段/常量

  • LOGGER

    • 类型: Logger
    • 修饰符: private static final
    • 源码定位: L44
    • 说明:

      TODO

  • PARTICLE_LISTER

    • 类型: FileToIdConverter
    • 修饰符: private static final
    • 源码定位: L45
    • 说明:

      TODO

  • spriteSets

    • 类型: Map<Identifier,ParticleResources.MutableSpriteSet>
    • 修饰符: private final
    • 源码定位: L46
    • 说明:

      TODO

  • providers

    • 类型: Int2ObjectMap<ParticleProvider<?>>
    • 修饰符: private final
    • 源码定位: L47
    • 说明:

      TODO

  • onReload

    • 类型: Runnable
    • 修饰符: private
    • 源码定位: L48
    • 说明:

      TODO

内部类/嵌套类型

  • net.minecraft.client.particle.ParticleResources.ParticleDefinition

    • 类型: record
    • 修饰符: package-private
    • 源码定位: L198
    • 说明:

      TODO

  • net.minecraft.client.particle.ParticleResources.MutableSpriteSet

    • 类型: class
    • 修饰符: private static
    • 源码定位: L286
    • 说明:

      TODO

  • net.minecraft.client.particle.ParticleResources.SpriteParticleRegistration

    • 类型: interface
    • 修饰符: private
    • 源码定位: L311
    • 说明:

      TODO

构造器

public ParticleResources() @ L50

  • 构造器名:ParticleResources
  • 源码定位:L50
  • 修饰符:public

参数:

说明:

TODO

方法

下面的方法块按源码顺序生成。

public void onReload(Runnable onReload) @ L54

  • 方法名:onReload
  • 源码定位:L54
  • 返回类型:void
  • 修饰符:public

参数:

  • onReload: Runnable

说明:

TODO

private void registerProviders() @ L58

  • 方法名:registerProviders
  • 源码定位:L58
  • 返回类型:void
  • 修饰符:private

参数:

说明:

TODO

private <T extends ParticleOptions> void register(ParticleType<T> type, ParticleProvider<T> provider) @ L178

  • 方法名:register
  • 源码定位:L178
  • 返回类型: void
  • 修饰符:private

参数:

  • type: ParticleType
  • provider: ParticleProvider

说明:

TODO

private <T extends ParticleOptions> void register(ParticleType<T> type, ParticleResources.SpriteParticleRegistration<T> provider) @ L182

  • 方法名:register
  • 源码定位:L182
  • 返回类型: void
  • 修饰符:private

参数:

  • type: ParticleType
  • provider: ParticleResources.SpriteParticleRegistration

说明:

TODO

public CompletableFuture<Void> reload(PreparableReloadListener.SharedState currentReload, Executor taskExecutor, PreparableReloadListener.PreparationBarrier preparationBarrier, Executor reloadExecutor) @ L188

  • 方法名:reload
  • 源码定位:L188
  • 返回类型:CompletableFuture
  • 修饰符:public

参数:

  • currentReload: PreparableReloadListener.SharedState
  • taskExecutor: Executor
  • preparationBarrier: PreparableReloadListener.PreparationBarrier
  • reloadExecutor: Executor

说明:

TODO

private Optional<List<Identifier>> loadParticleDescription(Identifier id, Resource resource) @ L262

  • 方法名:loadParticleDescription
  • 源码定位:L262
  • 返回类型:Optional<List>
  • 修饰符:private

参数:

  • id: Identifier
  • resource: Resource

说明:

TODO

public Int2ObjectMap<ParticleProvider<?>> getProviders() @ L281

  • 方法名:getProviders
  • 源码定位:L281
  • 返回类型:Int2ObjectMap<ParticleProvider<?>>
  • 修饰符:public

参数:

说明:

TODO

代码

@OnlyIn(Dist.CLIENT)
public class ParticleResources implements PreparableReloadListener {
    private static final Logger LOGGER = LogUtils.getLogger();
    private static final FileToIdConverter PARTICLE_LISTER = FileToIdConverter.json("particles");
    private final Map<Identifier, ParticleResources.MutableSpriteSet> spriteSets = Maps.newHashMap();
    private final Int2ObjectMap<ParticleProvider<?>> providers = new Int2ObjectOpenHashMap<>();
    private @Nullable Runnable onReload;
 
    public ParticleResources() {
        this.registerProviders();
    }
 
    public void onReload(Runnable onReload) {
        this.onReload = onReload;
    }
 
    private void registerProviders() {
        this.register(ParticleTypes.ANGRY_VILLAGER, HeartParticle.AngryVillagerProvider::new);
        this.register(ParticleTypes.BLOCK_MARKER, new BlockMarker.Provider());
        this.register(ParticleTypes.BLOCK, new TerrainParticle.Provider());
        this.register(ParticleTypes.BUBBLE, BubbleParticle.Provider::new);
        this.register(ParticleTypes.BUBBLE_COLUMN_UP, BubbleColumnUpParticle.Provider::new);
        this.register(ParticleTypes.BUBBLE_POP, BubblePopParticle.Provider::new);
        this.register(ParticleTypes.CAMPFIRE_COSY_SMOKE, CampfireSmokeParticle.CosyProvider::new);
        this.register(ParticleTypes.CAMPFIRE_SIGNAL_SMOKE, CampfireSmokeParticle.SignalProvider::new);
        this.register(ParticleTypes.CLOUD, PlayerCloudParticle.Provider::new);
        this.register(ParticleTypes.COMPOSTER, SuspendedTownParticle.ComposterFillProvider::new);
        this.register(ParticleTypes.COPPER_FIRE_FLAME, FlameParticle.Provider::new);
        this.register(ParticleTypes.CRIT, CritParticle.Provider::new);
        this.register(ParticleTypes.CURRENT_DOWN, WaterCurrentDownParticle.Provider::new);
        this.register(ParticleTypes.DAMAGE_INDICATOR, CritParticle.DamageIndicatorProvider::new);
        this.register(ParticleTypes.DRAGON_BREATH, DragonBreathParticle.Provider::new);
        this.register(ParticleTypes.DOLPHIN, SuspendedTownParticle.DolphinSpeedProvider::new);
        this.register(ParticleTypes.DRIPPING_LAVA, DripParticle.LavaHangProvider::new);
        this.register(ParticleTypes.FALLING_LAVA, DripParticle.LavaFallProvider::new);
        this.register(ParticleTypes.LANDING_LAVA, DripParticle.LavaLandProvider::new);
        this.register(ParticleTypes.DRIPPING_WATER, DripParticle.WaterHangProvider::new);
        this.register(ParticleTypes.FALLING_WATER, DripParticle.WaterFallProvider::new);
        this.register(ParticleTypes.DUST, DustParticle.Provider::new);
        this.register(ParticleTypes.DUST_COLOR_TRANSITION, DustColorTransitionParticle.Provider::new);
        this.register(ParticleTypes.EFFECT, SpellParticle.InstantProvider::new);
        this.register(ParticleTypes.ELDER_GUARDIAN, new ElderGuardianParticle.Provider());
        this.register(ParticleTypes.ENCHANTED_HIT, CritParticle.MagicProvider::new);
        this.register(ParticleTypes.ENCHANT, FlyTowardsPositionParticle.EnchantProvider::new);
        this.register(ParticleTypes.END_ROD, EndRodParticle.Provider::new);
        this.register(ParticleTypes.ENTITY_EFFECT, SpellParticle.MobEffectProvider::new);
        this.register(ParticleTypes.EXPLOSION_EMITTER, new HugeExplosionSeedParticle.Provider());
        this.register(ParticleTypes.EXPLOSION, HugeExplosionParticle.Provider::new);
        this.register(ParticleTypes.SONIC_BOOM, SonicBoomParticle.Provider::new);
        this.register(ParticleTypes.FALLING_DUST, FallingDustParticle.Provider::new);
        this.register(ParticleTypes.GUST, GustParticle.Provider::new);
        this.register(ParticleTypes.SMALL_GUST, GustParticle.SmallProvider::new);
        this.register(ParticleTypes.GUST_EMITTER_LARGE, new GustSeedParticle.Provider(3.0, 7, 0));
        this.register(ParticleTypes.GUST_EMITTER_SMALL, new GustSeedParticle.Provider(1.0, 3, 2));
        this.register(ParticleTypes.FIREWORK, FireworkParticles.SparkProvider::new);
        this.register(ParticleTypes.FISHING, WakeParticle.Provider::new);
        this.register(ParticleTypes.FLAME, FlameParticle.Provider::new);
        this.register(ParticleTypes.INFESTED, SpellParticle.Provider::new);
        this.register(ParticleTypes.SCULK_SOUL, SoulParticle.EmissiveProvider::new);
        this.register(ParticleTypes.SCULK_CHARGE, SculkChargeParticle.Provider::new);
        this.register(ParticleTypes.SCULK_CHARGE_POP, SculkChargePopParticle.Provider::new);
        this.register(ParticleTypes.SOUL, SoulParticle.Provider::new);
        this.register(ParticleTypes.SOUL_FIRE_FLAME, FlameParticle.Provider::new);
        this.register(ParticleTypes.FLASH, FireworkParticles.FlashProvider::new);
        this.register(ParticleTypes.HAPPY_VILLAGER, SuspendedTownParticle.HappyVillagerProvider::new);
        this.register(ParticleTypes.HEART, HeartParticle.Provider::new);
        this.register(ParticleTypes.INSTANT_EFFECT, SpellParticle.InstantProvider::new);
        this.register(ParticleTypes.ITEM, new BreakingItemParticle.Provider());
        this.register(ParticleTypes.ITEM_SLIME, new BreakingItemParticle.SlimeProvider());
        this.register(ParticleTypes.ITEM_COBWEB, new BreakingItemParticle.CobwebProvider());
        this.register(ParticleTypes.ITEM_SNOWBALL, new BreakingItemParticle.SnowballProvider());
        this.register(ParticleTypes.LARGE_SMOKE, LargeSmokeParticle.Provider::new);
        this.register(ParticleTypes.LAVA, LavaParticle.Provider::new);
        this.register(ParticleTypes.MYCELIUM, SuspendedTownParticle.Provider::new);
        this.register(ParticleTypes.NAUTILUS, FlyTowardsPositionParticle.NautilusProvider::new);
        this.register(ParticleTypes.NOTE, NoteParticle.Provider::new);
        this.register(ParticleTypes.POOF, ExplodeParticle.Provider::new);
        this.register(ParticleTypes.PORTAL, PortalParticle.Provider::new);
        this.register(ParticleTypes.RAIN, WaterDropParticle.Provider::new);
        this.register(ParticleTypes.SMOKE, SmokeParticle.Provider::new);
        this.register(ParticleTypes.WHITE_SMOKE, WhiteSmokeParticle.Provider::new);
        this.register(ParticleTypes.SNEEZE, PlayerCloudParticle.SneezeProvider::new);
        this.register(ParticleTypes.SNOWFLAKE, SnowflakeParticle.Provider::new);
        this.register(ParticleTypes.SPIT, SpitParticle.Provider::new);
        this.register(ParticleTypes.SWEEP_ATTACK, AttackSweepParticle.Provider::new);
        this.register(ParticleTypes.TOTEM_OF_UNDYING, TotemParticle.Provider::new);
        this.register(ParticleTypes.SQUID_INK, SquidInkParticle.Provider::new);
        this.register(ParticleTypes.UNDERWATER, SuspendedParticle.UnderwaterProvider::new);
        this.register(ParticleTypes.SPLASH, SplashParticle.Provider::new);
        this.register(ParticleTypes.WITCH, SpellParticle.WitchProvider::new);
        this.register(ParticleTypes.DRIPPING_HONEY, DripParticle.HoneyHangProvider::new);
        this.register(ParticleTypes.FALLING_HONEY, DripParticle.HoneyFallProvider::new);
        this.register(ParticleTypes.LANDING_HONEY, DripParticle.HoneyLandProvider::new);
        this.register(ParticleTypes.FALLING_NECTAR, DripParticle.NectarFallProvider::new);
        this.register(ParticleTypes.FALLING_SPORE_BLOSSOM, DripParticle.SporeBlossomFallProvider::new);
        this.register(ParticleTypes.SPORE_BLOSSOM_AIR, SuspendedParticle.SporeBlossomAirProvider::new);
        this.register(ParticleTypes.ASH, AshParticle.Provider::new);
        this.register(ParticleTypes.CRIMSON_SPORE, SuspendedParticle.CrimsonSporeProvider::new);
        this.register(ParticleTypes.WARPED_SPORE, SuspendedParticle.WarpedSporeProvider::new);
        this.register(ParticleTypes.DRIPPING_OBSIDIAN_TEAR, DripParticle.ObsidianTearHangProvider::new);
        this.register(ParticleTypes.FALLING_OBSIDIAN_TEAR, DripParticle.ObsidianTearFallProvider::new);
        this.register(ParticleTypes.LANDING_OBSIDIAN_TEAR, DripParticle.ObsidianTearLandProvider::new);
        this.register(ParticleTypes.REVERSE_PORTAL, ReversePortalParticle.ReversePortalProvider::new);
        this.register(ParticleTypes.WHITE_ASH, WhiteAshParticle.Provider::new);
        this.register(ParticleTypes.SMALL_FLAME, FlameParticle.SmallFlameProvider::new);
        this.register(ParticleTypes.DRIPPING_DRIPSTONE_WATER, DripParticle.DripstoneWaterHangProvider::new);
        this.register(ParticleTypes.FALLING_DRIPSTONE_WATER, DripParticle.DripstoneWaterFallProvider::new);
        this.register(ParticleTypes.CHERRY_LEAVES, FallingLeavesParticle.CherryProvider::new);
        this.register(ParticleTypes.PALE_OAK_LEAVES, FallingLeavesParticle.PaleOakProvider::new);
        this.register(ParticleTypes.TINTED_LEAVES, FallingLeavesParticle.TintedLeavesProvider::new);
        this.register(ParticleTypes.DRIPPING_DRIPSTONE_LAVA, DripParticle.DripstoneLavaHangProvider::new);
        this.register(ParticleTypes.FALLING_DRIPSTONE_LAVA, DripParticle.DripstoneLavaFallProvider::new);
        this.register(ParticleTypes.VIBRATION, VibrationSignalParticle.Provider::new);
        this.register(ParticleTypes.TRAIL, TrailParticle.Provider::new);
        this.register(ParticleTypes.PAUSE_MOB_GROWTH, SimpleVerticalParticle.PauseMobGrowthProvider::new);
        this.register(ParticleTypes.RESET_MOB_GROWTH, SimpleVerticalParticle.ResetMobGrowthProvider::new);
        this.register(ParticleTypes.GLOW_SQUID_INK, SquidInkParticle.GlowInkProvider::new);
        this.register(ParticleTypes.GLOW, GlowParticle.GlowSquidProvider::new);
        this.register(ParticleTypes.WAX_ON, GlowParticle.WaxOnProvider::new);
        this.register(ParticleTypes.WAX_OFF, GlowParticle.WaxOffProvider::new);
        this.register(ParticleTypes.ELECTRIC_SPARK, GlowParticle.ElectricSparkProvider::new);
        this.register(ParticleTypes.SCRAPE, GlowParticle.ScrapeProvider::new);
        this.register(ParticleTypes.SHRIEK, ShriekParticle.Provider::new);
        this.register(ParticleTypes.EGG_CRACK, SuspendedTownParticle.EggCrackProvider::new);
        this.register(ParticleTypes.DUST_PLUME, DustPlumeParticle.Provider::new);
        this.register(ParticleTypes.TRIAL_SPAWNER_DETECTED_PLAYER, TrialSpawnerDetectionParticle.Provider::new);
        this.register(ParticleTypes.TRIAL_SPAWNER_DETECTED_PLAYER_OMINOUS, TrialSpawnerDetectionParticle.Provider::new);
        this.register(ParticleTypes.VAULT_CONNECTION, FlyTowardsPositionParticle.VaultConnectionProvider::new);
        this.register(ParticleTypes.DUST_PILLAR, new TerrainParticle.DustPillarProvider());
        this.register(ParticleTypes.RAID_OMEN, SpellParticle.Provider::new);
        this.register(ParticleTypes.TRIAL_OMEN, SpellParticle.Provider::new);
        this.register(ParticleTypes.OMINOUS_SPAWNING, FlyStraightTowardsParticle.OminousSpawnProvider::new);
        this.register(ParticleTypes.BLOCK_CRUMBLE, new TerrainParticle.CrumblingProvider());
        this.register(ParticleTypes.FIREFLY, FireflyParticle.FireflyProvider::new);
    }
 
    private <T extends ParticleOptions> void register(ParticleType<T> type, ParticleProvider<T> provider) {
        this.providers.put(BuiltInRegistries.PARTICLE_TYPE.getId(type), provider);
    }
 
    private <T extends ParticleOptions> void register(ParticleType<T> type, ParticleResources.SpriteParticleRegistration<T> provider) {
        ParticleResources.MutableSpriteSet spriteSet = new ParticleResources.MutableSpriteSet();
        this.spriteSets.put(BuiltInRegistries.PARTICLE_TYPE.getKey(type), spriteSet);
        this.providers.put(BuiltInRegistries.PARTICLE_TYPE.getId(type), provider.create(spriteSet));
    }
 
    @Override
    public CompletableFuture<Void> reload(
        PreparableReloadListener.SharedState currentReload,
        Executor taskExecutor,
        PreparableReloadListener.PreparationBarrier preparationBarrier,
        Executor reloadExecutor
    ) {
        ResourceManager manager = currentReload.resourceManager();
 
        @OnlyIn(Dist.CLIENT)
        record ParticleDefinition(Identifier id, Optional<List<Identifier>> sprites) {
        }
 
        CompletableFuture<List<ParticleDefinition>> spriteSetsToLoad = CompletableFuture.<Map<Identifier, Resource>>supplyAsync(
                () -> PARTICLE_LISTER.listMatchingResources(manager), taskExecutor
            )
            .thenCompose(
                definitionsToScan -> {
                    List<CompletableFuture<ParticleDefinition>> loadTasks = new ArrayList<>(definitionsToScan.size());
                    definitionsToScan.forEach(
                        (resourceId, resource) -> {
                            Identifier particleId = PARTICLE_LISTER.fileToId(resourceId);
                            loadTasks.add(
                                CompletableFuture.supplyAsync(
                                    () -> new ParticleDefinition(particleId, this.loadParticleDescription(particleId, resource)), taskExecutor
                                )
                            );
                        }
                    );
                    return Util.sequence(loadTasks);
                }
            );
        CompletableFuture<SpriteLoader.Preparations> pendingSprites = currentReload.get(AtlasManager.PENDING_STITCH).get(AtlasIds.PARTICLES);
        return CompletableFuture.allOf(spriteSetsToLoad, pendingSprites).thenCompose(preparationBarrier::wait).thenAcceptAsync(unused -> {
            if (this.onReload != null) {
                this.onReload.run();
            }
 
            ProfilerFiller reloadProfiler = Profiler.get();
            reloadProfiler.push("upload");
            SpriteLoader.Preparations sprites = pendingSprites.join();
            reloadProfiler.popPush("bindSpriteSets");
            Set<Identifier> missingSprites = new HashSet<>();
            TextureAtlasSprite missingSprite = sprites.missing();
            spriteSetsToLoad.join().forEach(p -> {
                Optional<List<Identifier>> spriteIds = p.sprites();
                if (!spriteIds.isEmpty()) {
                    List<TextureAtlasSprite> contents = new ArrayList<>();
 
                    for (Identifier spriteId : spriteIds.get()) {
                        TextureAtlasSprite sprite = sprites.getSprite(spriteId);
                        if (sprite == null) {
                            missingSprites.add(spriteId);
                            contents.add(missingSprite);
                        } else {
                            contents.add(sprite);
                        }
                    }
 
                    if (contents.isEmpty()) {
                        contents.add(missingSprite);
                    }
 
                    this.spriteSets.get(p.id()).rebind(contents);
                }
            });
            if (!missingSprites.isEmpty()) {
                LOGGER.warn("Missing particle sprites: {}", missingSprites.stream().sorted().map(Identifier::toString).collect(Collectors.joining(",")));
            }
 
            reloadProfiler.pop();
        }, reloadExecutor);
    }
 
    private Optional<List<Identifier>> loadParticleDescription(Identifier id, Resource resource) {
        if (!this.spriteSets.containsKey(id)) {
            LOGGER.debug("Redundant texture list for particle: {}", id);
            return Optional.empty();
        } else {
            try {
                Optional var5;
                try (Reader reader = resource.openAsReader()) {
                    ParticleDescription description = ParticleDescription.fromJson(GsonHelper.parse(reader));
                    var5 = Optional.of(description.getTextures());
                }
 
                return var5;
            } catch (IOException var8) {
                throw new IllegalStateException("Failed to load description for particle " + id, var8);
            }
        }
    }
 
    public Int2ObjectMap<ParticleProvider<?>> getProviders() {
        return this.providers;
    }
 
    @OnlyIn(Dist.CLIENT)
    private static class MutableSpriteSet implements SpriteSet {
        private List<TextureAtlasSprite> sprites;
 
        @Override
        public TextureAtlasSprite get(int index, int max) {
            return this.sprites.get(index * (this.sprites.size() - 1) / max);
        }
 
        @Override
        public TextureAtlasSprite get(RandomSource random) {
            return this.sprites.get(random.nextInt(this.sprites.size()));
        }
 
        @Override
        public TextureAtlasSprite first() {
            return this.sprites.getFirst();
        }
 
        public void rebind(List<TextureAtlasSprite> ids) {
            this.sprites = ImmutableList.copyOf(ids);
        }
    }
 
    @FunctionalInterface
    @OnlyIn(Dist.CLIENT)
    private interface SpriteParticleRegistration<T extends ParticleOptions> {
        ParticleProvider<T> create(SpriteSet spriteSet);
    }
}

引用的其他类

  • BlockMarker

    • 引用位置: 方法调用/构造调用
    • 关联成员: BlockMarker.Provider(), Provider()
  • BreakingItemParticle

    • 引用位置: 方法调用/构造调用
    • 关联成员: BreakingItemParticle.CobwebProvider(), BreakingItemParticle.Provider(), BreakingItemParticle.SlimeProvider(), BreakingItemParticle.SnowballProvider(), CobwebProvider(), Provider(), SlimeProvider(), SnowballProvider()
  • ElderGuardianParticle

    • 引用位置: 方法调用/构造调用
    • 关联成员: ElderGuardianParticle.Provider(), Provider()
  • GustSeedParticle

    • 引用位置: 方法调用/构造调用
    • 关联成员: GustSeedParticle.Provider(), Provider()
  • HugeExplosionSeedParticle

    • 引用位置: 方法调用/构造调用
    • 关联成员: HugeExplosionSeedParticle.Provider(), Provider()
  • ParticleDescription

    • 引用位置: 方法调用
    • 关联成员: ParticleDescription.fromJson()
  • ParticleProvider

    • 引用位置: 参数/字段/返回值
  • TerrainParticle

    • 引用位置: 方法调用/构造调用
    • 关联成员: CrumblingProvider(), DustPillarProvider(), Provider(), TerrainParticle.CrumblingProvider(), TerrainParticle.DustPillarProvider(), TerrainParticle.Provider()
  • ParticleOptions

    • 引用位置: 返回值
  • ParticleType

    • 引用位置: 参数
  • FileToIdConverter

    • 引用位置: 字段/方法调用
    • 关联成员: FileToIdConverter.json()
  • Identifier

    • 引用位置: 参数/字段/返回值
  • PreparableReloadListener

    • 引用位置: 参数/实现
  • Resource

    • 引用位置: 参数
  • GsonHelper

    • 引用位置: 方法调用
    • 关联成员: GsonHelper.parse()
  • Util

    • 引用位置: 方法调用
    • 关联成员: Util.sequence()
  • Profiler

    • 引用位置: 方法调用
    • 关联成员: Profiler.get()