-
Notifications
You must be signed in to change notification settings - Fork 0
Reading and Writing
MyModConfig shared = holder.data(); // cheap, shared — treat as read-only
MyModConfig mine = holder.copy(); // deep copy you own, safe to mutate freelydata() returns the live published snapshot. It is cheap — no locking, no copying — and is the
right choice for hot paths. The returned object is shared with every concurrent reader — mutating it would corrupt the live state. Take a copy() when you need to hold a reading that cannot shift while you examine
multiple fields at once, or when you need to mutate values locally before applying them.
holder.update(config -> config.showHints = false); // publish in memory only
holder.updateAndSave(config -> config.hudScale = 3); // publish and write to diskThe lambda passed to update receives a private candidate copy, not the live state. The candidate
is validated before publication. If validation fails, the live state is never touched and the
failed update is reported on the returned UpdateResult. A mutator that throws is treated as a
defect and propagates regardless of the failure policy.
UpdateResult result = holder.updateAndSave(config -> config.hudScale = 99);
if (!result.accepted()) {
result.violations().forEach(v -> LOGGER.warn("{}: {}", v.id(), v.message()));
}Holders built with createAsync() add non-blocking variants that return CompletableFuture:
AsyncConfigHolder<MyModConfig> holder = /* ... */;
holder.saveAsync();
holder.updateAndSaveAsync(config -> config.hudScale = 3).thenAccept(result -> { /* ... */ });