AtlasManager.java
net.minecraft.client.resources.model.sprite.AtlasManager
信息
- 全限定名:net.minecraft.client.resources.model.sprite.AtlasManager
- 类型:public class
- 包:net.minecraft.client.resources.model.sprite
- 源码路径:src/main/java/net/minecraft/client/resources/model/sprite/AtlasManager.java
- 起始行号:L30
- 实现:AutoCloseable, PreparableReloadListener, SpriteGetter
- 职责:
TODO
字段/常量
-
LOGGER- 类型:
Logger - 修饰符:
private static final - 源码定位:
L31 - 说明:
TODO
- 类型:
-
KNOWN_ATLASES- 类型:
List<AtlasManager.AtlasConfig> - 修饰符:
private static final - 源码定位:
L32 - 说明:
TODO
- 类型:
-
PENDING_STITCH- 类型:
PreparableReloadListener.StateKey<AtlasManager.PendingStitchResults> - 修饰符:
public static final - 源码定位:
L49 - 说明:
TODO
- 类型:
-
atlasByTexture- 类型:
Map<Identifier,AtlasManager.AtlasEntry> - 修饰符:
private final - 源码定位:
L50 - 说明:
TODO
- 类型:
-
atlasById- 类型:
Map<Identifier,AtlasManager.AtlasEntry> - 修饰符:
private final - 源码定位:
L51 - 说明:
TODO
- 类型:
-
spriteLookup- 类型:
Map<SpriteId,TextureAtlasSprite> - 修饰符:
private - 源码定位:
L52 - 说明:
TODO
- 类型:
-
maxMipmapLevels- 类型:
int - 修饰符:
private - 源码定位:
L53 - 说明:
TODO
- 类型:
内部类/嵌套类型
-
net.minecraft.client.resources.model.sprite.AtlasManager.AtlasConfig- 类型:
record - 修饰符:
public - 源码定位:
L168 - 说明:
TODO
- 类型:
-
net.minecraft.client.resources.model.sprite.AtlasManager.AtlasEntry- 类型:
record - 修饰符:
private - 源码定位:
L175 - 说明:
TODO
- 类型:
-
net.minecraft.client.resources.model.sprite.AtlasManager.PendingStitch- 类型:
record - 修饰符:
private - 源码定位:
L190 - 说明:
TODO
- 类型:
-
net.minecraft.client.resources.model.sprite.AtlasManager.PendingStitchResults- 类型:
class - 修饰符:
public static - 源码定位:
L199 - 说明:
TODO
- 类型:
构造器
public AtlasManager(TextureManager textureManager, int maxMipmapLevels) @ L55
- 构造器名:AtlasManager
- 源码定位:L55
- 修饰符:public
参数:
- textureManager: TextureManager
- maxMipmapLevels: int
说明:
TODO
方法
下面的方法块按源码顺序生成。
public TextureAtlas getAtlasOrThrow(Identifier atlasId) @ L67
- 方法名:getAtlasOrThrow
- 源码定位:L67
- 返回类型:TextureAtlas
- 修饰符:public
参数:
- atlasId: Identifier
说明:
TODO
public void forEach(BiConsumer<Identifier,TextureAtlas> output) @ L76
- 方法名:forEach
- 源码定位:L76
- 返回类型:void
- 修饰符:public
参数:
- output: BiConsumer<Identifier,TextureAtlas>
说明:
TODO
public void updateMaxMipLevel(int maxMipmapLevels) @ L80
- 方法名:updateMaxMipLevel
- 源码定位:L80
- 返回类型:void
- 修饰符:public
参数:
- maxMipmapLevels: int
说明:
TODO
public void close() @ L84
- 方法名:close
- 源码定位:L84
- 返回类型:void
- 修饰符:public
参数:
- 无
说明:
TODO
public TextureAtlasSprite get(SpriteId sprite) @ L92
- 方法名:get
- 源码定位:L92
- 返回类型:TextureAtlasSprite
- 修饰符:public
参数:
- sprite: SpriteId
说明:
TODO
public void prepareSharedState(PreparableReloadListener.SharedState currentReload) @ L108
- 方法名:prepareSharedState
- 源码定位:L108
- 返回类型:void
- 修饰符:public
参数:
- currentReload: PreparableReloadListener.SharedState
说明:
TODO
public CompletableFuture<Void> reload(PreparableReloadListener.SharedState currentReload, Executor taskExecutor, PreparableReloadListener.PreparationBarrier preparationBarrier, Executor reloadExecutor) @ L124
- 方法名:reload
- 源码定位:L124
- 返回类型:CompletableFuture
- 修饰符:public
参数:
- currentReload: PreparableReloadListener.SharedState
- taskExecutor: Executor
- preparationBarrier: PreparableReloadListener.PreparationBarrier
- reloadExecutor: Executor
说明:
TODO
private void updateSpriteMaps(AtlasManager.PendingStitchResults pendingStitches) @ L146
- 方法名:updateSpriteMaps
- 源码定位:L146
- 返回类型:void
- 修饰符:private
参数:
- pendingStitches: AtlasManager.PendingStitchResults
说明:
TODO
代码
@OnlyIn(Dist.CLIENT)
public class AtlasManager implements AutoCloseable, PreparableReloadListener, SpriteGetter {
private static final Logger LOGGER = LogUtils.getLogger();
private static final List<AtlasManager.AtlasConfig> KNOWN_ATLASES = List.of(
new AtlasManager.AtlasConfig(Sheets.ARMOR_TRIMS_SHEET, AtlasIds.ARMOR_TRIMS, false),
new AtlasManager.AtlasConfig(Sheets.BANNER_SHEET, AtlasIds.BANNER_PATTERNS, false),
new AtlasManager.AtlasConfig(Sheets.BED_SHEET, AtlasIds.BEDS, false),
new AtlasManager.AtlasConfig(TextureAtlas.LOCATION_BLOCKS, AtlasIds.BLOCKS, true),
new AtlasManager.AtlasConfig(TextureAtlas.LOCATION_ITEMS, AtlasIds.ITEMS, false),
new AtlasManager.AtlasConfig(Sheets.CHEST_SHEET, AtlasIds.CHESTS, false),
new AtlasManager.AtlasConfig(Sheets.DECORATED_POT_SHEET, AtlasIds.DECORATED_POT, false),
new AtlasManager.AtlasConfig(Sheets.GUI_SHEET, AtlasIds.GUI, false, Set.of(GuiMetadataSection.TYPE)),
new AtlasManager.AtlasConfig(Sheets.MAP_DECORATIONS_SHEET, AtlasIds.MAP_DECORATIONS, false),
new AtlasManager.AtlasConfig(Sheets.PAINTINGS_SHEET, AtlasIds.PAINTINGS, false),
new AtlasManager.AtlasConfig(TextureAtlas.LOCATION_PARTICLES, AtlasIds.PARTICLES, false),
new AtlasManager.AtlasConfig(Sheets.SHIELD_SHEET, AtlasIds.SHIELD_PATTERNS, false),
new AtlasManager.AtlasConfig(Sheets.SHULKER_SHEET, AtlasIds.SHULKER_BOXES, false),
new AtlasManager.AtlasConfig(Sheets.SIGN_SHEET, AtlasIds.SIGNS, false),
new AtlasManager.AtlasConfig(Sheets.CELESTIAL_SHEET, AtlasIds.CELESTIALS, false)
);
public static final PreparableReloadListener.StateKey<AtlasManager.PendingStitchResults> PENDING_STITCH = new PreparableReloadListener.StateKey<>();
private final Map<Identifier, AtlasManager.AtlasEntry> atlasByTexture = new HashMap<>();
private final Map<Identifier, AtlasManager.AtlasEntry> atlasById = new HashMap<>();
private Map<SpriteId, TextureAtlasSprite> spriteLookup = Map.of();
private int maxMipmapLevels;
public AtlasManager(TextureManager textureManager, int maxMipmapLevels) {
for (AtlasManager.AtlasConfig info : KNOWN_ATLASES) {
TextureAtlas atlasTexture = new TextureAtlas(info.textureId);
textureManager.register(info.textureId, atlasTexture);
AtlasManager.AtlasEntry atlasEntry = new AtlasManager.AtlasEntry(atlasTexture, info);
this.atlasByTexture.put(info.textureId, atlasEntry);
this.atlasById.put(info.definitionLocation, atlasEntry);
}
this.maxMipmapLevels = maxMipmapLevels;
}
public TextureAtlas getAtlasOrThrow(Identifier atlasId) {
AtlasManager.AtlasEntry atlasEntry = this.atlasById.get(atlasId);
if (atlasEntry == null) {
throw new IllegalArgumentException("Invalid atlas id: " + atlasId);
} else {
return atlasEntry.atlas();
}
}
public void forEach(BiConsumer<Identifier, TextureAtlas> output) {
this.atlasById.forEach((atlasId, entry) -> output.accept(atlasId, entry.atlas));
}
public void updateMaxMipLevel(int maxMipmapLevels) {
this.maxMipmapLevels = maxMipmapLevels;
}
@Override
public void close() {
this.spriteLookup = Map.of();
this.atlasById.values().forEach(AtlasManager.AtlasEntry::close);
this.atlasById.clear();
this.atlasByTexture.clear();
}
@Override
public TextureAtlasSprite get(SpriteId sprite) {
TextureAtlasSprite result = this.spriteLookup.get(sprite);
if (result != null) {
return result;
} else {
Identifier atlasTextureId = sprite.atlasLocation();
AtlasManager.AtlasEntry atlasEntry = this.atlasByTexture.get(atlasTextureId);
if (atlasEntry == null) {
throw new IllegalArgumentException("Invalid atlas texture id: " + atlasTextureId);
} else {
return atlasEntry.atlas().missingSprite();
}
}
}
@Override
public void prepareSharedState(PreparableReloadListener.SharedState currentReload) {
int atlasCount = this.atlasById.size();
List<AtlasManager.PendingStitch> pendingStitches = new ArrayList<>(atlasCount);
Map<Identifier, CompletableFuture<SpriteLoader.Preparations>> pendingStitchById = new HashMap<>(atlasCount);
List<CompletableFuture<?>> readyForUploads = new ArrayList<>(atlasCount);
this.atlasById.forEach((atlasId, atlasEntry) -> {
CompletableFuture<SpriteLoader.Preparations> stitchingDone = new CompletableFuture<>();
pendingStitchById.put(atlasId, stitchingDone);
pendingStitches.add(new AtlasManager.PendingStitch(atlasEntry, stitchingDone));
readyForUploads.add(stitchingDone.thenCompose(SpriteLoader.Preparations::readyForUpload));
});
CompletableFuture<?> allReadyForUploads = CompletableFuture.allOf(readyForUploads.toArray(CompletableFuture[]::new));
currentReload.set(PENDING_STITCH, new AtlasManager.PendingStitchResults(pendingStitches, pendingStitchById, allReadyForUploads));
}
@Override
public CompletableFuture<Void> reload(
PreparableReloadListener.SharedState currentReload,
Executor taskExecutor,
PreparableReloadListener.PreparationBarrier preparationBarrier,
Executor reloadExecutor
) {
AtlasManager.PendingStitchResults pendingStitches = currentReload.get(PENDING_STITCH);
ResourceManager resourceManager = currentReload.resourceManager();
pendingStitches.pendingStitches
.forEach(pending -> pending.entry.scheduleLoad(resourceManager, taskExecutor, this.maxMipmapLevels).whenComplete((value, throwable) -> {
if (value != null) {
pending.preparations.complete(value);
} else {
pending.preparations.completeExceptionally(throwable);
}
}));
return pendingStitches.allReadyToUpload
.thenCompose(preparationBarrier::wait)
.thenAcceptAsync(unused -> this.updateSpriteMaps(pendingStitches), reloadExecutor);
}
private void updateSpriteMaps(AtlasManager.PendingStitchResults pendingStitches) {
this.spriteLookup = pendingStitches.joinAndUpload();
Map<Identifier, TextureAtlasSprite> globalSpriteLookup = new HashMap<>();
this.spriteLookup
.forEach(
(id, sprite) -> {
if (!id.texture().equals(MissingTextureAtlasSprite.getLocation())) {
TextureAtlasSprite previous = globalSpriteLookup.putIfAbsent(id.texture(), sprite);
if (previous != null) {
LOGGER.warn(
"Duplicate sprite {} from atlas {}, already defined in atlas {}. This will be rejected in a future version",
id.texture(),
id.atlasLocation(),
previous.atlasLocation()
);
}
}
}
);
}
@OnlyIn(Dist.CLIENT)
public record AtlasConfig(Identifier textureId, Identifier definitionLocation, boolean createMipmaps, Set<MetadataSectionType<?>> additionalMetadata) {
public AtlasConfig(Identifier textureId, Identifier definitionLocation, boolean createMipmaps) {
this(textureId, definitionLocation, createMipmaps, Set.of());
}
}
@OnlyIn(Dist.CLIENT)
private record AtlasEntry(TextureAtlas atlas, AtlasManager.AtlasConfig config) implements AutoCloseable {
@Override
public void close() {
this.atlas.clearTextureData();
}
private CompletableFuture<SpriteLoader.Preparations> scheduleLoad(ResourceManager resourceManager, Executor executor, int maxMipmapLevels) {
return SpriteLoader.create(this.atlas)
.loadAndStitch(
resourceManager, this.config.definitionLocation, this.config.createMipmaps ? maxMipmapLevels : 0, executor, this.config.additionalMetadata
);
}
}
@OnlyIn(Dist.CLIENT)
private record PendingStitch(AtlasManager.AtlasEntry entry, CompletableFuture<SpriteLoader.Preparations> preparations) {
public void joinAndUpload(Map<SpriteId, TextureAtlasSprite> result) {
SpriteLoader.Preparations preparations = this.preparations.join();
this.entry.atlas.upload(preparations);
preparations.regions().forEach((spriteId, spriteContents) -> result.put(new SpriteId(this.entry.config.textureId, spriteId), spriteContents));
}
}
@OnlyIn(Dist.CLIENT)
public static class PendingStitchResults {
private final List<AtlasManager.PendingStitch> pendingStitches;
private final Map<Identifier, CompletableFuture<SpriteLoader.Preparations>> stitchFuturesById;
private final CompletableFuture<?> allReadyToUpload;
private PendingStitchResults(
List<AtlasManager.PendingStitch> pendingStitches,
Map<Identifier, CompletableFuture<SpriteLoader.Preparations>> stitchFuturesById,
CompletableFuture<?> allReadyToUpload
) {
this.pendingStitches = pendingStitches;
this.stitchFuturesById = stitchFuturesById;
this.allReadyToUpload = allReadyToUpload;
}
public Map<SpriteId, TextureAtlasSprite> joinAndUpload() {
Map<SpriteId, TextureAtlasSprite> result = new HashMap<>();
this.pendingStitches.forEach(pendingStitch -> pendingStitch.joinAndUpload(result));
return result;
}
public CompletableFuture<SpriteLoader.Preparations> get(Identifier atlasId) {
return Objects.requireNonNull(this.stitchFuturesById.get(atlasId));
}
}
}引用的其他类
-
- 引用位置:
方法调用 - 关联成员:
MissingTextureAtlasSprite.getLocation()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
SpriteLoader.create()
- 引用位置:
-
- 引用位置:
参数/构造调用/返回值 - 关联成员:
TextureAtlas()
- 引用位置:
-
- 引用位置:
字段/返回值
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
实现
- 引用位置:
-
- 引用位置:
参数/字段/构造调用 - 关联成员:
SpriteId()
- 引用位置:
-
- 引用位置:
参数/字段
- 引用位置:
-
- 引用位置:
参数/字段/实现
- 引用位置: