PeriodicNotificationManager.java
net.minecraft.client.PeriodicNotificationManager
信息
- 全限定名:net.minecraft.client.PeriodicNotificationManager
- 类型:public class
- 包:net.minecraft.client
- 源码路径:src/main/java/net/minecraft/client/PeriodicNotificationManager.java
- 起始行号:L34
- 继承:SimplePreparableReloadListener<Map<String,List<PeriodicNotificationManager.Notification>>>
- 实现:AutoCloseable
- 职责:
TODO
字段/常量
-
CODEC- 类型:
Codec<Map<String,List<PeriodicNotificationManager.Notification>>> - 修饰符:
private static final - 源码定位:
L37 - 说明:
TODO
- 类型:
-
LOGGER- 类型:
Logger - 修饰符:
private static final - 源码定位:
L50 - 说明:
TODO
- 类型:
-
notifications- 类型:
Identifier - 修饰符:
private final - 源码定位:
L51 - 说明:
TODO
- 类型:
-
selector- 类型:
Object2BooleanFunction<String> - 修饰符:
private final - 源码定位:
L52 - 说明:
TODO
- 类型:
-
timer- 类型:
Timer - 修饰符:
private - 源码定位:
L53 - 说明:
TODO
- 类型:
-
notificationTask- 类型:
PeriodicNotificationManager.NotificationTask - 修饰符:
private - 源码定位:
L54 - 说明:
TODO
- 类型:
内部类/嵌套类型
-
net.minecraft.client.PeriodicNotificationManager.Notification- 类型:
record - 修饰符:
public - 源码定位:
L127 - 说明:
TODO
- 类型:
-
net.minecraft.client.PeriodicNotificationManager.NotificationTask- 类型:
class - 修饰符:
private static - 源码定位:
L137 - 说明:
TODO
- 类型:
构造器
public PeriodicNotificationManager(Identifier notifications, Object2BooleanFunction<String> selector) @ L56
- 构造器名:PeriodicNotificationManager
- 源码定位:L56
- 修饰符:public
参数:
- notifications: Identifier
- selector: Object2BooleanFunction
说明:
TODO
方法
下面的方法块按源码顺序生成。
protected Map<String,List<PeriodicNotificationManager.Notification>> prepare(ResourceManager manager, ProfilerFiller profiler) @ L61
- 方法名:prepare
- 源码定位:L61
- 返回类型:Map<String,List<PeriodicNotificationManager.Notification>>
- 修饰符:protected
参数:
- manager: ResourceManager
- profiler: ProfilerFiller
说明:
TODO
protected void apply(Map<String,List<PeriodicNotificationManager.Notification>> preparations, ResourceManager manager, ProfilerFiller profiler) @ L75
- 方法名:apply
- 源码定位:L75
- 返回类型:void
- 修饰符:protected
参数:
- preparations: Map<String,List<PeriodicNotificationManager.Notification>>
- manager: ResourceManager
- profiler: ProfilerFiller
说明:
TODO
public void close() @ L104
- 方法名:close
- 源码定位:L104
- 返回类型:void
- 修饰符:public
参数:
- 无
说明:
TODO
private void stopTimer() @ L109
- 方法名:stopTimer
- 源码定位:L109
- 返回类型:void
- 修饰符:private
参数:
- 无
说明:
TODO
private long calculateOptimalPeriod(List<PeriodicNotificationManager.Notification> notifications, long initialDelay) @ L115
- 方法名:calculateOptimalPeriod
- 源码定位:L115
- 返回类型:long
- 修饰符:private
参数:
- notifications: List<PeriodicNotificationManager.Notification>
- initialDelay: long
说明:
TODO
private long calculateInitialDelay(List<PeriodicNotificationManager.Notification> notifications) @ L122
- 方法名:calculateInitialDelay
- 源码定位:L122
- 返回类型:long
- 修饰符:private
参数:
- notifications: List<PeriodicNotificationManager.Notification>
说明:
TODO
代码
@OnlyIn(Dist.CLIENT)
public class PeriodicNotificationManager
extends SimplePreparableReloadListener<Map<String, List<PeriodicNotificationManager.Notification>>>
implements AutoCloseable {
private static final Codec<Map<String, List<PeriodicNotificationManager.Notification>>> CODEC = Codec.unboundedMap(
Codec.STRING,
RecordCodecBuilder.<PeriodicNotificationManager.Notification>create(
i -> i.group(
Codec.LONG.optionalFieldOf("delay", 0L).forGetter(PeriodicNotificationManager.Notification::delay),
Codec.LONG.fieldOf("period").forGetter(PeriodicNotificationManager.Notification::period),
Codec.STRING.fieldOf("title").forGetter(PeriodicNotificationManager.Notification::title),
Codec.STRING.fieldOf("message").forGetter(PeriodicNotificationManager.Notification::message)
)
.apply(i, PeriodicNotificationManager.Notification::new)
)
.listOf()
);
private static final Logger LOGGER = LogUtils.getLogger();
private final Identifier notifications;
private final Object2BooleanFunction<String> selector;
private @Nullable Timer timer;
private PeriodicNotificationManager.@Nullable NotificationTask notificationTask;
public PeriodicNotificationManager(Identifier notifications, Object2BooleanFunction<String> selector) {
this.notifications = notifications;
this.selector = selector;
}
protected Map<String, List<PeriodicNotificationManager.Notification>> prepare(ResourceManager manager, ProfilerFiller profiler) {
try {
Map var4;
try (Reader reader = manager.openAsReader(this.notifications)) {
var4 = CODEC.parse(JsonOps.INSTANCE, StrictJsonParser.parse(reader)).result().orElseThrow();
}
return var4;
} catch (Exception var8) {
LOGGER.warn("Failed to load {}", this.notifications, var8);
return ImmutableMap.of();
}
}
protected void apply(Map<String, List<PeriodicNotificationManager.Notification>> preparations, ResourceManager manager, ProfilerFiller profiler) {
List<PeriodicNotificationManager.Notification> notifications = preparations.entrySet()
.stream()
.filter(e -> this.selector.apply(e.getKey()))
.map(Entry::getValue)
.flatMap(Collection::stream)
.collect(Collectors.toList());
if (notifications.isEmpty()) {
this.stopTimer();
} else if (notifications.stream().anyMatch(n -> n.period == 0L)) {
Util.logAndPauseIfInIde("A periodic notification in " + this.notifications + " has a period of zero minutes");
this.stopTimer();
} else {
long delay = this.calculateInitialDelay(notifications);
long period = this.calculateOptimalPeriod(notifications, delay);
if (this.timer == null) {
this.timer = new Timer();
}
if (this.notificationTask == null) {
this.notificationTask = new PeriodicNotificationManager.NotificationTask(notifications, delay, period);
} else {
this.notificationTask = this.notificationTask.reset(notifications, period);
}
this.timer.scheduleAtFixedRate(this.notificationTask, TimeUnit.MINUTES.toMillis(delay), TimeUnit.MINUTES.toMillis(period));
}
}
@Override
public void close() {
this.stopTimer();
}
private void stopTimer() {
if (this.timer != null) {
this.timer.cancel();
}
}
private long calculateOptimalPeriod(List<PeriodicNotificationManager.Notification> notifications, long initialDelay) {
return notifications.stream().mapToLong(c -> {
long delayPeriods = c.delay - initialDelay;
return LongMath.gcd(delayPeriods, c.period);
}).reduce(LongMath::gcd).orElseThrow(() -> new IllegalStateException("Empty notifications from: " + this.notifications));
}
private long calculateInitialDelay(List<PeriodicNotificationManager.Notification> notifications) {
return notifications.stream().mapToLong(c -> c.delay).min().orElse(0L);
}
@OnlyIn(Dist.CLIENT)
public record Notification(long delay, long period, String title, String message) {
public Notification(long delay, long period, String title, String message) {
this.delay = delay != 0L ? delay : period;
this.period = period;
this.title = title;
this.message = message;
}
}
@OnlyIn(Dist.CLIENT)
private static class NotificationTask extends TimerTask {
private final Minecraft minecraft = Minecraft.getInstance();
private final List<PeriodicNotificationManager.Notification> notifications;
private final long period;
private final AtomicLong elapsed;
public NotificationTask(List<PeriodicNotificationManager.Notification> notifications, long elapsed, long period) {
this.notifications = notifications;
this.period = period;
this.elapsed = new AtomicLong(elapsed);
}
public PeriodicNotificationManager.NotificationTask reset(List<PeriodicNotificationManager.Notification> notifications, long period) {
this.cancel();
return new PeriodicNotificationManager.NotificationTask(notifications, this.elapsed.get(), period);
}
@Override
public void run() {
long currentMinute = this.elapsed.getAndAdd(this.period);
long nextMinute = this.elapsed.get();
for (PeriodicNotificationManager.Notification notification : this.notifications) {
if (currentMinute >= notification.delay) {
long elapsedPeriods = currentMinute / notification.period;
long currentPeriods = nextMinute / notification.period;
if (elapsedPeriods != currentPeriods) {
this.minecraft
.execute(
() -> SystemToast.add(
Minecraft.getInstance().getToastManager(),
SystemToast.SystemToastId.PERIODIC_NOTIFICATION,
Component.translatable(notification.title, elapsedPeriods),
Component.translatable(notification.message, elapsedPeriods)
)
);
return;
}
}
}
}
}
}引用的其他类
-
- 引用位置:
字段/构造调用 - 关联成员:
Timer()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
Minecraft.getInstance()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
SystemToast.add()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
Component.translatable()
- 引用位置:
-
- 引用位置:
参数/字段
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
SimplePreparableReloadListener
- 引用位置:
继承
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
StrictJsonParser.parse()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
Util.logAndPauseIfInIde()
- 引用位置:
-
- 引用位置:
参数
- 引用位置: