mirror of
https://github.com/FabricMC/fabric.git
synced 2025-07-28 15:09:35 -04:00
Registry event API + loot table fix (#194)
This commit is contained in:
parent
6263b147d3
commit
99245497ed
19 changed files with 428 additions and 228 deletions
fabric-registry-sync-v0
build.gradle
src/main/java/net/fabricmc/fabric
api/event/registry
impl/registry
mixin/registry
|
@ -1,5 +1,5 @@
|
|||
archivesBaseName = "fabric-registry-sync-v0"
|
||||
version = getSubprojectVersion(project, "0.1.2")
|
||||
version = getSubprojectVersion(project, "0.2.0")
|
||||
|
||||
dependencies {
|
||||
compile project(path: ':fabric-api-base', configuration: 'dev')
|
||||
|
|
|
@ -14,11 +14,23 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.impl.registry.callbacks;
|
||||
package net.fabricmc.fabric.api.event.registry;
|
||||
|
||||
import net.fabricmc.fabric.api.event.Event;
|
||||
import net.fabricmc.fabric.impl.registry.ListenableRegistry;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface RegistryPostRegisterCallback<T> extends RegistryCallback<T> {
|
||||
void onPostRegister(int rawId, Identifier id, T object);
|
||||
public interface RegistryEntryAddedCallback<T> {
|
||||
void onEntryAdded(int rawId, Identifier id, T object);
|
||||
|
||||
static <T> Event<RegistryEntryAddedCallback<T>> event(Registry<T> registry) {
|
||||
if (!(registry instanceof ListenableRegistry)) {
|
||||
throw new IllegalArgumentException("Unsupported registry: " + registry.getClass().getName());
|
||||
}
|
||||
|
||||
//noinspection unchecked
|
||||
return (Event<RegistryEntryAddedCallback<T>>) ((ListenableRegistry) registry).fabric_getAddObjectEvent();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.api.event.registry;
|
||||
|
||||
import net.fabricmc.fabric.api.event.Event;
|
||||
import net.fabricmc.fabric.impl.registry.ListenableRegistry;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface RegistryEntryRemovedCallback<T> {
|
||||
void onEntryRemoved(int rawId, Identifier id, T object);
|
||||
|
||||
static <T> Event<RegistryEntryRemovedCallback<T>> event(Registry<T> registry) {
|
||||
if (!(registry instanceof ListenableRegistry)) {
|
||||
throw new IllegalArgumentException("Unsupported registry: " + registry.getClass().getName());
|
||||
}
|
||||
|
||||
//noinspection unchecked
|
||||
return (Event<RegistryEntryRemovedCallback<T>>) ((ListenableRegistry) registry).fabric_getRemoveObjectEvent();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.api.event.registry;
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.Int2IntMap;
|
||||
import net.fabricmc.fabric.api.event.Event;
|
||||
import net.fabricmc.fabric.impl.registry.ListenableRegistry;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
|
||||
/**
|
||||
* The remapping process functions as follows:
|
||||
*
|
||||
* - RegistryEntryRemovedCallbacks are called to remove any objects culled in the process, with the old numeric ID.
|
||||
* - RegistryIdRemapCallback is emitted to allow remapping the IDs of objects still present.
|
||||
* - RegistryEntryAddedCallbacks are called to add any objects added in the process, with the new numeric ID.
|
||||
*
|
||||
* RegistryIdRemapCallback is called on every remapping operation, if you want to do your own processing in one swoop
|
||||
* (say, rebuild the ID map from scratch).
|
||||
*
|
||||
* Generally speaking, a remap can only cause object *removals*; object *additions* are necessary to reverse remaps.
|
||||
*
|
||||
* @param <T> The registry type.
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface RegistryIdRemapCallback<T> {
|
||||
void onRemap(RemapState<T> state);
|
||||
|
||||
interface RemapState<T> {
|
||||
Int2IntMap getRawIdChangeMap();
|
||||
Identifier getIdFromOld(int oldRawId);
|
||||
Identifier getIdFromNew(int newRawId);
|
||||
}
|
||||
|
||||
static <T> Event<RegistryIdRemapCallback<T>> event(Registry<T> registry) {
|
||||
if (!(registry instanceof ListenableRegistry)) {
|
||||
throw new IllegalArgumentException("Unsupported registry: " + registry.getClass().getName());
|
||||
}
|
||||
|
||||
//noinspection unchecked
|
||||
return (Event<RegistryIdRemapCallback<T>>) ((ListenableRegistry) registry).fabric_getRemapEvent();
|
||||
}
|
||||
}
|
|
@ -17,12 +17,12 @@
|
|||
package net.fabricmc.fabric.impl.registry;
|
||||
|
||||
import net.fabricmc.fabric.api.event.Event;
|
||||
import net.fabricmc.fabric.impl.registry.callbacks.RegistryPostRegisterCallback;
|
||||
import net.fabricmc.fabric.impl.registry.callbacks.RegistryPreClearCallback;
|
||||
import net.fabricmc.fabric.impl.registry.callbacks.RegistryPreRegisterCallback;
|
||||
import net.fabricmc.fabric.api.event.registry.RegistryEntryAddedCallback;
|
||||
import net.fabricmc.fabric.api.event.registry.RegistryIdRemapCallback;
|
||||
import net.fabricmc.fabric.api.event.registry.RegistryEntryRemovedCallback;
|
||||
|
||||
public interface ListenableRegistry<T> {
|
||||
Event<RegistryPreClearCallback<T>> getPreClearEvent();
|
||||
Event<RegistryPreRegisterCallback<T>> getPreRegisterEvent();
|
||||
Event<RegistryPostRegisterCallback<T>> getPostRegisterEvent();
|
||||
Event<RegistryEntryAddedCallback<T>> fabric_getAddObjectEvent();
|
||||
Event<RegistryEntryRemovedCallback<T>> fabric_getRemoveObjectEvent();
|
||||
Event<RegistryIdRemapCallback<T>> fabric_getRemapEvent();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.impl.registry;
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.Int2IntMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import net.fabricmc.fabric.api.event.registry.RegistryIdRemapCallback;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
|
||||
public class RemapStateImpl<T> implements RegistryIdRemapCallback.RemapState<T> {
|
||||
private final Int2IntMap rawIdChangeMap;
|
||||
private final Int2ObjectMap<Identifier> newIdMap;
|
||||
|
||||
public RemapStateImpl(Registry<T> registry, Int2IntMap rawIdChangeMap) {
|
||||
this.rawIdChangeMap = rawIdChangeMap;
|
||||
this.newIdMap = new Int2ObjectOpenHashMap<>();
|
||||
|
||||
for (Int2IntMap.Entry entry : rawIdChangeMap.int2IntEntrySet()) {
|
||||
Identifier id = registry.getId(registry.get(entry.getIntValue()));
|
||||
newIdMap.put(entry.getIntValue(), id);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Int2IntMap getRawIdChangeMap() {
|
||||
return rawIdChangeMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Identifier getIdFromOld(int oldRawId) {
|
||||
return newIdMap.get(rawIdChangeMap.getOrDefault(oldRawId, -1));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Identifier getIdFromNew(int newRawId) {
|
||||
return newIdMap.get(newRawId);
|
||||
}
|
||||
}
|
|
@ -16,8 +16,12 @@
|
|||
|
||||
package net.fabricmc.fabric.impl.registry;
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.Int2IntMap;
|
||||
|
||||
public interface RemovableIdList<T> {
|
||||
void clear();
|
||||
void remove(T o);
|
||||
void removeId(int i);
|
||||
void fabric_clear();
|
||||
void fabric_remove(T o);
|
||||
void fabric_removeId(int i);
|
||||
void fabric_remapId(int from, int to);
|
||||
void fabric_remapIds(Int2IntMap map);
|
||||
}
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.impl.registry.callbacks;
|
||||
|
||||
public interface RegistryCallback<T> {
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.impl.registry.callbacks;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface RegistryPreClearCallback<T> extends RegistryCallback<T> {
|
||||
void onPreClear();
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.impl.registry.callbacks;
|
||||
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface RegistryPreRegisterCallback<T> extends RegistryCallback<T> {
|
||||
void onPreRegister(int rawId, Identifier id, T object, boolean isNewToRegistry);
|
||||
}
|
|
@ -16,10 +16,10 @@
|
|||
|
||||
package net.fabricmc.fabric.impl.registry.trackers;
|
||||
|
||||
import net.fabricmc.fabric.api.event.registry.RegistryEntryAddedCallback;
|
||||
import net.fabricmc.fabric.api.event.registry.RegistryIdRemapCallback;
|
||||
import net.fabricmc.fabric.api.event.registry.RegistryEntryRemovedCallback;
|
||||
import net.fabricmc.fabric.impl.registry.RemovableIdList;
|
||||
import net.fabricmc.fabric.impl.registry.ListenableRegistry;
|
||||
import net.fabricmc.fabric.impl.registry.callbacks.RegistryPreClearCallback;
|
||||
import net.fabricmc.fabric.impl.registry.callbacks.RegistryPreRegisterCallback;
|
||||
import net.minecraft.util.IdList;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
|
@ -27,40 +27,40 @@ import net.minecraft.util.registry.Registry;
|
|||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class IdListTracker<V, OV> implements RegistryPreClearCallback<V>, RegistryPreRegisterCallback<V> {
|
||||
public class IdListTracker<V, OV> implements RegistryEntryAddedCallback<V>, RegistryIdRemapCallback<V>, RegistryEntryRemovedCallback<V> {
|
||||
private final IdList<OV> mappers;
|
||||
private final Registry<V> registry;
|
||||
private Map<Identifier, OV> mapperCache = new HashMap<>();
|
||||
private Map<Identifier, OV> removedMapperCache = new HashMap<>();
|
||||
|
||||
private IdListTracker(Registry<V> registry, IdList<OV> mappers) {
|
||||
this.registry = registry;
|
||||
private IdListTracker(IdList<OV> mappers) {
|
||||
this.mappers = mappers;
|
||||
}
|
||||
|
||||
public static <V, OV> void register(Registry<V> registry, IdList<OV> mappers) {
|
||||
IdListTracker<V, OV> updater = new IdListTracker<>(registry, mappers);
|
||||
((ListenableRegistry<V>) registry).getPreClearEvent().register(updater);
|
||||
((ListenableRegistry<V>) registry).getPreRegisterEvent().register(updater);
|
||||
IdListTracker<V, OV> updater = new IdListTracker<>(mappers);
|
||||
RegistryEntryAddedCallback.event(registry).register(updater);
|
||||
RegistryIdRemapCallback.event(registry).register(updater);
|
||||
RegistryEntryRemovedCallback.event(registry).register(updater);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPreClear() {
|
||||
mapperCache.clear();
|
||||
for (Identifier id : registry.getIds()) {
|
||||
int rawId = registry.getRawId(registry.get(id));
|
||||
OV mapper = mappers.get(rawId);
|
||||
if (mapper != null) {
|
||||
mapperCache.put(id, mapper);
|
||||
}
|
||||
public void onEntryAdded(int rawId, Identifier id, V object) {
|
||||
if (removedMapperCache.containsKey(id)) {
|
||||
mappers.set(removedMapperCache.get(id), rawId);
|
||||
}
|
||||
}
|
||||
|
||||
((RemovableIdList) mappers).clear();
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void onRemap(RemapState<V> state) {
|
||||
((RemovableIdList<OV>) mappers).fabric_remapIds(state.getRawIdChangeMap());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPreRegister(int id, Identifier identifier, V object, boolean isNewToRegistry) {
|
||||
if (mapperCache.containsKey(identifier)) {
|
||||
mappers.set(mapperCache.get(identifier), id);
|
||||
public void onEntryRemoved(int rawId, Identifier id, V object) {
|
||||
if (mappers.get(rawId) != null) {
|
||||
removedMapperCache.put(id, mappers.get(rawId));
|
||||
//noinspection unchecked
|
||||
((RemovableIdList<OV>) mappers).fabric_removeId(rawId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,49 +17,57 @@
|
|||
package net.fabricmc.fabric.impl.registry.trackers;
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import net.fabricmc.fabric.impl.registry.ListenableRegistry;
|
||||
import net.fabricmc.fabric.impl.registry.callbacks.RegistryPreClearCallback;
|
||||
import net.fabricmc.fabric.impl.registry.callbacks.RegistryPreRegisterCallback;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import net.fabricmc.fabric.api.event.registry.RegistryEntryAddedCallback;
|
||||
import net.fabricmc.fabric.api.event.registry.RegistryIdRemapCallback;
|
||||
import net.fabricmc.fabric.api.event.registry.RegistryEntryRemovedCallback;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class Int2ObjectMapTracker<V, OV> implements RegistryPreClearCallback<V>, RegistryPreRegisterCallback<V> {
|
||||
public class Int2ObjectMapTracker<V, OV> implements RegistryEntryAddedCallback<V>, RegistryIdRemapCallback<V>, RegistryEntryRemovedCallback<V> {
|
||||
private final Int2ObjectMap<OV> mappers;
|
||||
private final Registry<V> registry;
|
||||
private Map<Identifier, OV> mapperCache = new HashMap<>();
|
||||
private Map<Identifier, OV> removedMapperCache = new HashMap<>();
|
||||
|
||||
private Int2ObjectMapTracker(Registry<V> registry, Int2ObjectMap<OV> mappers) {
|
||||
this.registry = registry;
|
||||
private Int2ObjectMapTracker(Int2ObjectMap<OV> mappers) {
|
||||
this.mappers = mappers;
|
||||
}
|
||||
|
||||
public static <V, OV> void register(Registry<V> registry, Int2ObjectMap<OV> mappers) {
|
||||
Int2ObjectMapTracker<V, OV> updater = new Int2ObjectMapTracker<>(registry, mappers);
|
||||
((ListenableRegistry<V>) registry).getPreClearEvent().register(updater);
|
||||
((ListenableRegistry<V>) registry).getPreRegisterEvent().register(updater);
|
||||
Int2ObjectMapTracker<V, OV> updater = new Int2ObjectMapTracker<>(mappers);
|
||||
RegistryEntryAddedCallback.event(registry).register(updater);
|
||||
RegistryIdRemapCallback.event(registry).register(updater);
|
||||
RegistryEntryRemovedCallback.event(registry).register(updater);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPreClear() {
|
||||
mapperCache.clear();
|
||||
for (Identifier id : registry.getIds()) {
|
||||
int rawId = registry.getRawId(registry.get(id));
|
||||
OV mapper = mappers.get(rawId);
|
||||
if (mapper != null) {
|
||||
mapperCache.put(id, mapper);
|
||||
}
|
||||
public void onEntryAdded(int rawId, Identifier id, V object) {
|
||||
if (removedMapperCache.containsKey(id)) {
|
||||
mappers.put(rawId, removedMapperCache.get(id));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRemap(RemapState<V> state) {
|
||||
Int2ObjectMap<OV> oldMappers = new Int2ObjectOpenHashMap<>(mappers);
|
||||
|
||||
mappers.clear();
|
||||
for (int i : oldMappers.keySet()) {
|
||||
int newI = state.getRawIdChangeMap().getOrDefault(i, i);
|
||||
if (mappers.containsKey(newI)) {
|
||||
throw new RuntimeException("Int2ObjectMap contained two equal IDs " + newI + " (" + state.getIdFromOld(i) + "/" + i + " -> " + state.getIdFromNew(newI) + "/" + newI + ")!");
|
||||
}
|
||||
|
||||
mappers.put(newI, oldMappers.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPreRegister(int id, Identifier identifier, V object, boolean isNewToRegistry) {
|
||||
if (mapperCache.containsKey(identifier)) {
|
||||
mappers.put(id, mapperCache.get(identifier));
|
||||
public void onEntryRemoved(int rawId, Identifier id, V object) {
|
||||
if (mappers.containsKey(rawId)) {
|
||||
removedMapperCache.put(id, mappers.remove(rawId));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,39 +16,39 @@
|
|||
|
||||
package net.fabricmc.fabric.impl.registry.trackers;
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectRBTreeMap;
|
||||
import net.fabricmc.fabric.api.event.registry.RegistryIdRemapCallback;
|
||||
import net.fabricmc.fabric.impl.registry.RemovableIdList;
|
||||
import net.fabricmc.fabric.impl.registry.ListenableRegistry;
|
||||
import net.fabricmc.fabric.impl.registry.callbacks.RegistryPostRegisterCallback;
|
||||
import net.fabricmc.fabric.impl.registry.callbacks.RegistryPreClearCallback;
|
||||
import net.minecraft.util.IdList;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.registry.SimpleRegistry;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.function.Function;
|
||||
|
||||
public final class StateIdTracker<T, S> implements RegistryPreClearCallback<T>, RegistryPostRegisterCallback<T> {
|
||||
public final class StateIdTracker<T, S> implements RegistryIdRemapCallback<T> {
|
||||
private final Registry<T> registry;
|
||||
private final IdList<S> stateList;
|
||||
private final Function<T, Collection<S>> stateGetter;
|
||||
|
||||
public static <T, S> void register(SimpleRegistry<T> registry, IdList<S> stateList, Function<T, Collection<S>> stateGetter) {
|
||||
StateIdTracker<T, S> tracker = new StateIdTracker<>(stateList, stateGetter);
|
||||
((ListenableRegistry<T>) registry).getPreClearEvent().register(tracker);
|
||||
((ListenableRegistry<T>) registry).getPostRegisterEvent().register(tracker);
|
||||
public static <T, S> void register(Registry<T> registry, IdList<S> stateList, Function<T, Collection<S>> stateGetter) {
|
||||
RegistryIdRemapCallback.event(registry).register(new StateIdTracker<>(registry, stateList, stateGetter));
|
||||
}
|
||||
|
||||
private StateIdTracker(IdList<S> stateList, Function<T, Collection<S>> stateGetter) {
|
||||
private StateIdTracker(Registry<T> registry, IdList<S> stateList, Function<T, Collection<S>> stateGetter) {
|
||||
this.registry = registry;
|
||||
this.stateList = stateList;
|
||||
this.stateGetter = stateGetter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPreClear() {
|
||||
((RemovableIdList) stateList).clear();
|
||||
}
|
||||
public void onRemap(RemapState<T> state) {
|
||||
((RemovableIdList) stateList).fabric_clear();
|
||||
|
||||
@Override
|
||||
public void onPostRegister(int rawId, Identifier id, T object) {
|
||||
stateGetter.apply(object).forEach(stateList::add);
|
||||
Int2ObjectMap<T> sortedBlocks = new Int2ObjectRBTreeMap<>();
|
||||
registry.forEach((t) -> sortedBlocks.put(registry.getRawId(t), t));
|
||||
for (T b : sortedBlocks.values()) {
|
||||
stateGetter.apply(b).forEach(stateList::add);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,15 +16,18 @@
|
|||
|
||||
package net.fabricmc.fabric.impl.registry.trackers.vanilla;
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.Int2IntMap;
|
||||
import net.fabricmc.fabric.api.event.registry.RegistryEntryAddedCallback;
|
||||
import net.fabricmc.fabric.api.event.registry.RegistryIdRemapCallback;
|
||||
import net.fabricmc.fabric.api.event.registry.RegistryEntryRemovedCallback;
|
||||
import net.fabricmc.fabric.impl.registry.RemovableIdList;
|
||||
import net.fabricmc.fabric.impl.registry.ListenableRegistry;
|
||||
import net.fabricmc.fabric.impl.registry.callbacks.RegistryPostRegisterCallback;
|
||||
import net.fabricmc.fabric.impl.registry.callbacks.RegistryPreClearCallback;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
import net.minecraft.world.biome.Biome;
|
||||
|
||||
public final class BiomeParentTracker implements RegistryPreClearCallback<Biome>, RegistryPostRegisterCallback<Biome> {
|
||||
import java.util.Objects;
|
||||
|
||||
public final class BiomeParentTracker implements RegistryEntryAddedCallback<Biome>, RegistryEntryRemovedCallback<Biome>, RegistryIdRemapCallback<Biome> {
|
||||
private final Registry<Biome> registry;
|
||||
|
||||
private BiomeParentTracker(Registry<Biome> registry) {
|
||||
|
@ -33,19 +36,32 @@ public final class BiomeParentTracker implements RegistryPreClearCallback<Biome>
|
|||
|
||||
public static void register(Registry<Biome> registry) {
|
||||
BiomeParentTracker tracker = new BiomeParentTracker(registry);
|
||||
((ListenableRegistry<Biome>) registry).getPreClearEvent().register(tracker);
|
||||
((ListenableRegistry<Biome>) registry).getPostRegisterEvent().register(tracker);
|
||||
RegistryEntryAddedCallback.event(registry).register(tracker);
|
||||
RegistryIdRemapCallback.event(registry).register(tracker);
|
||||
RegistryEntryRemovedCallback.event(registry).register(tracker);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPostRegister(int rawId, Identifier id, Biome object) {
|
||||
public void onEntryAdded(int rawId, Identifier id, Biome object) {
|
||||
if (object.hasParent()) {
|
||||
Biome.PARENT_BIOME_ID_MAP.set(object, registry.getRawId(registry.get(new Identifier(object.getParent()))));
|
||||
Biome.PARENT_BIOME_ID_MAP.set(object, registry.getRawId(registry.get(new Identifier(Objects.requireNonNull(object.getParent())))));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPreClear() {
|
||||
((RemovableIdList) Biome.PARENT_BIOME_ID_MAP).clear();
|
||||
public void onRemap(RemapState<Biome> state) {
|
||||
for (Int2IntMap.Entry entry : state.getRawIdChangeMap().int2IntEntrySet()) {
|
||||
if (Biome.PARENT_BIOME_ID_MAP.get(entry.getIntKey()) != null) {
|
||||
//noinspection unchecked
|
||||
((RemovableIdList<Biome>) Biome.PARENT_BIOME_ID_MAP).fabric_remapId(entry.getIntKey(), entry.getIntValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void onEntryRemoved(int rawId, Identifier id, Biome object) {
|
||||
((RemovableIdList<Biome>) Biome.PARENT_BIOME_ID_MAP).fabric_remove(object);
|
||||
((RemovableIdList<Biome>) Biome.PARENT_BIOME_ID_MAP).fabric_removeId(rawId);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,32 +16,31 @@
|
|||
|
||||
package net.fabricmc.fabric.impl.registry.trackers.vanilla;
|
||||
|
||||
import net.fabricmc.fabric.impl.registry.ListenableRegistry;
|
||||
import net.fabricmc.fabric.impl.registry.callbacks.RegistryPostRegisterCallback;
|
||||
import net.fabricmc.fabric.impl.registry.callbacks.RegistryPreClearCallback;
|
||||
import net.fabricmc.fabric.impl.registry.callbacks.RegistryPreRegisterCallback;
|
||||
import net.fabricmc.fabric.api.event.registry.RegistryEntryAddedCallback;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.item.BlockItem;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.registry.SimpleRegistry;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
|
||||
public final class BlockInitTracker implements RegistryPreRegisterCallback<Block> {
|
||||
private BlockInitTracker() {
|
||||
public final class BlockInitTracker implements RegistryEntryAddedCallback<Block> {
|
||||
private final Registry<Block> registry;
|
||||
|
||||
private BlockInitTracker(Registry<Block> registry) {
|
||||
this.registry = registry;
|
||||
}
|
||||
|
||||
public static void register(SimpleRegistry<Block> registry) {
|
||||
BlockInitTracker tracker = new BlockInitTracker();
|
||||
((ListenableRegistry<Block>) registry).getPreRegisterEvent().register(tracker);
|
||||
public static void register(Registry<Block> registry) {
|
||||
BlockInitTracker tracker = new BlockInitTracker(registry);
|
||||
RegistryEntryAddedCallback.event(registry).register(tracker);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPreRegister(int rawId, Identifier id, Block object, boolean isNewToRegistry) {
|
||||
if (isNewToRegistry) {
|
||||
object.getStateFactory().getStates().forEach(BlockState::initShapeCache);
|
||||
object.getDropTableId();
|
||||
}
|
||||
public void onEntryAdded(int rawId, Identifier id, Block object) {
|
||||
object.getStateFactory().getStates().forEach(BlockState::initShapeCache);
|
||||
|
||||
// if false, getDropTableId() will generate an invalid drop table ID
|
||||
assert id.equals(registry.getId(object));
|
||||
|
||||
object.getDropTableId();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,34 +16,26 @@
|
|||
|
||||
package net.fabricmc.fabric.impl.registry.trackers.vanilla;
|
||||
|
||||
import net.fabricmc.fabric.impl.registry.ListenableRegistry;
|
||||
import net.fabricmc.fabric.impl.registry.callbacks.RegistryPostRegisterCallback;
|
||||
import net.fabricmc.fabric.impl.registry.callbacks.RegistryPreClearCallback;
|
||||
import net.fabricmc.fabric.api.event.registry.RegistryEntryAddedCallback;
|
||||
import net.minecraft.item.BlockItem;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.registry.SimpleRegistry;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
|
||||
public final class BlockItemTracker implements RegistryPreClearCallback<Item>, RegistryPostRegisterCallback<Item> {
|
||||
public final class BlockItemTracker implements RegistryEntryAddedCallback<Item> {
|
||||
private BlockItemTracker() {
|
||||
|
||||
}
|
||||
|
||||
public static void register(SimpleRegistry<Item> registry) {
|
||||
public static void register(Registry<Item> registry) {
|
||||
BlockItemTracker tracker = new BlockItemTracker();
|
||||
((ListenableRegistry<Item>) registry).getPreClearEvent().register(tracker);
|
||||
((ListenableRegistry<Item>) registry).getPostRegisterEvent().register(tracker);
|
||||
RegistryEntryAddedCallback.event(registry).register(tracker);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPostRegister(int rawId, Identifier id, Item object) {
|
||||
public void onEntryAdded(int rawId, Identifier id, Item object) {
|
||||
if (object instanceof BlockItem) {
|
||||
((BlockItem) object).registerBlockItemMap(Item.BLOCK_ITEM_MAP, object);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPreClear() {
|
||||
Item.BLOCK_ITEM_MAP.clear();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,14 +16,19 @@
|
|||
|
||||
package net.fabricmc.fabric.mixin.registry;
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.Int2IntMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2IntMaps;
|
||||
import net.fabricmc.fabric.impl.registry.RemovableIdList;
|
||||
import net.minecraft.util.IdList;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@Mixin(IdList.class)
|
||||
public class MixinIdList implements RemovableIdList<Object> {
|
||||
|
@ -35,7 +40,7 @@ public class MixinIdList implements RemovableIdList<Object> {
|
|||
private List<Object> list;
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
public void fabric_clear() {
|
||||
nextId = 0;
|
||||
idMap.clear();
|
||||
list.clear();
|
||||
|
@ -51,17 +56,55 @@ public class MixinIdList implements RemovableIdList<Object> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void remove(Object o) {
|
||||
public void fabric_remove(Object o) {
|
||||
if (idMap.containsKey(o)) {
|
||||
fabric_removeInner(o);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeId(int i) {
|
||||
Object obj = list.get(i);
|
||||
if (obj != null) {
|
||||
fabric_removeInner(obj);
|
||||
public void fabric_removeId(int i) {
|
||||
List<Object> removals = new ArrayList<>();
|
||||
|
||||
for (Object o : idMap.keySet()) {
|
||||
int j = idMap.get(o);
|
||||
if (i == j) {
|
||||
removals.add(o);
|
||||
}
|
||||
}
|
||||
|
||||
removals.forEach(this::fabric_removeInner);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fabric_remapId(int from, int to) {
|
||||
fabric_remapIds(Int2IntMaps.singleton(from, to));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fabric_remapIds(Int2IntMap map) {
|
||||
// remap idMap
|
||||
idMap.replaceAll((a, b) -> map.get(b));
|
||||
|
||||
// remap list
|
||||
nextId = 0;
|
||||
List<Object> oldList = new ArrayList<>(list);
|
||||
list.clear();
|
||||
|
||||
for (int k = 0; k < oldList.size(); k++) {
|
||||
Object o = oldList.get(k);
|
||||
if (o != null) {
|
||||
int i = map.getOrDefault(k, k);
|
||||
|
||||
while (list.size() <= i) {
|
||||
list.add(null);
|
||||
}
|
||||
|
||||
list.set(i, o);
|
||||
if (nextId <= i) {
|
||||
nextId = i + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,16 +18,19 @@ package net.fabricmc.fabric.mixin.registry;
|
|||
|
||||
import com.google.common.collect.BiMap;
|
||||
import com.google.common.collect.HashBiMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2IntMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
|
||||
import net.fabricmc.fabric.api.event.Event;
|
||||
import net.fabricmc.fabric.api.event.EventFactory;
|
||||
import net.fabricmc.fabric.api.event.registry.RegistryEntryAddedCallback;
|
||||
import net.fabricmc.fabric.api.event.registry.RegistryIdRemapCallback;
|
||||
import net.fabricmc.fabric.api.event.registry.RegistryEntryRemovedCallback;
|
||||
import net.fabricmc.fabric.impl.registry.ListenableRegistry;
|
||||
import net.fabricmc.fabric.impl.registry.RemapStateImpl;
|
||||
import net.fabricmc.fabric.impl.registry.RemapException;
|
||||
import net.fabricmc.fabric.impl.registry.RemappableRegistry;
|
||||
import net.fabricmc.fabric.impl.registry.callbacks.RegistryPostRegisterCallback;
|
||||
import net.fabricmc.fabric.impl.registry.callbacks.RegistryPreClearCallback;
|
||||
import net.fabricmc.fabric.impl.registry.callbacks.RegistryPreRegisterCallback;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.Int2ObjectBiMap;
|
||||
import net.minecraft.util.registry.SimpleRegistry;
|
||||
|
@ -43,7 +46,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
|||
import java.util.*;
|
||||
|
||||
@Mixin(SimpleRegistry.class)
|
||||
public abstract class MixinIdRegistry<T> implements RemappableRegistry, ListenableRegistry<T> {
|
||||
public abstract class MixinIdRegistry<T> implements RemappableRegistry, ListenableRegistry {
|
||||
@Shadow
|
||||
protected Int2ObjectBiMap<T> indexedEntries;
|
||||
@Shadow
|
||||
|
@ -53,65 +56,86 @@ public abstract class MixinIdRegistry<T> implements RemappableRegistry, Listenab
|
|||
@Unique
|
||||
private static Logger FABRIC_LOGGER = LogManager.getLogger();
|
||||
|
||||
private final Event<RegistryPreClearCallback> fabric_preClearEvent = EventFactory.createArrayBacked(RegistryPreClearCallback.class,
|
||||
(callbacks) -> () -> {
|
||||
for (RegistryPreClearCallback callback : callbacks) {
|
||||
callback.onPreClear();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
private final Event<RegistryPreRegisterCallback> fabric_preRegisterEvent = EventFactory.createArrayBacked(RegistryPreRegisterCallback.class,
|
||||
(callbacks) -> (a, b, c, d) -> {
|
||||
for (RegistryPreRegisterCallback callback : callbacks) {
|
||||
@Unique
|
||||
private final Event<RegistryEntryAddedCallback> fabric_addObjectEvent = EventFactory.createArrayBacked(RegistryEntryAddedCallback.class,
|
||||
(callbacks) -> (rawId, id, object) -> {
|
||||
for (RegistryEntryAddedCallback callback : callbacks) {
|
||||
//noinspection unchecked
|
||||
callback.onPreRegister(a, b, c, d);
|
||||
callback.onEntryAdded(rawId, id, object);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
private final Event<RegistryPostRegisterCallback> fabric_postRegisterEvent = EventFactory.createArrayBacked(RegistryPostRegisterCallback.class,
|
||||
(callbacks) -> (a, b, c) -> {
|
||||
for (RegistryPostRegisterCallback callback : callbacks) {
|
||||
@Unique
|
||||
private final Event<RegistryEntryRemovedCallback> fabric_removeObjectEvent = EventFactory.createArrayBacked(RegistryEntryRemovedCallback.class,
|
||||
(callbacks) -> (rawId, id, object) -> {
|
||||
for (RegistryEntryRemovedCallback callback : callbacks) {
|
||||
//noinspection unchecked
|
||||
callback.onPostRegister(a, b, c);
|
||||
callback.onEntryRemoved(rawId, id, object);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
@Unique
|
||||
private final Event<RegistryIdRemapCallback> fabric_postRemapEvent = EventFactory.createArrayBacked(RegistryIdRemapCallback.class,
|
||||
(callbacks) -> (a) -> {
|
||||
for (RegistryIdRemapCallback callback : callbacks) {
|
||||
//noinspection unchecked
|
||||
callback.onRemap(a);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
@Unique
|
||||
private Object2IntMap<Identifier> fabric_prevIndexedEntries;
|
||||
@Unique
|
||||
private BiMap<Identifier, T> fabric_prevEntries;
|
||||
|
||||
@Override
|
||||
public Event<RegistryPreClearCallback<T>> getPreClearEvent() {
|
||||
public Event<RegistryEntryAddedCallback<T>> fabric_getAddObjectEvent() {
|
||||
//noinspection unchecked
|
||||
return (Event<RegistryPreClearCallback<T>>) (Event) fabric_preClearEvent;
|
||||
return (Event<RegistryEntryAddedCallback<T>>) (Event) fabric_addObjectEvent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Event<RegistryPreRegisterCallback<T>> getPreRegisterEvent() {
|
||||
public Event<RegistryEntryRemovedCallback<T>> fabric_getRemoveObjectEvent() {
|
||||
//noinspection unchecked
|
||||
return (Event<RegistryPreRegisterCallback<T>>) (Event) fabric_preRegisterEvent;
|
||||
return (Event<RegistryEntryRemovedCallback<T>>) (Event) fabric_removeObjectEvent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Event<RegistryPostRegisterCallback<T>> getPostRegisterEvent() {
|
||||
public Event<RegistryIdRemapCallback<T>> fabric_getRemapEvent() {
|
||||
//noinspection unchecked
|
||||
return (Event<RegistryPostRegisterCallback<T>>) (Event) fabric_postRegisterEvent;
|
||||
return (Event<RegistryIdRemapCallback<T>>) (Event) fabric_postRemapEvent;
|
||||
}
|
||||
|
||||
// The rest of the registry isn't thread-safe, so this one need not be either.
|
||||
@Unique
|
||||
private boolean fabric_isObjectNew = false;
|
||||
|
||||
@SuppressWarnings({"unchecked", "ConstantConditions"})
|
||||
@Inject(method = "set", at = @At("HEAD"))
|
||||
public void setPre(int id, Identifier identifier, Object object, CallbackInfoReturnable info) {
|
||||
boolean isNewToRegistry = !entries.containsKey(identifier);
|
||||
fabric_preRegisterEvent.invoker().onPreRegister(id, identifier, object, isNewToRegistry);
|
||||
if (!entries.containsKey(identifier)) {
|
||||
fabric_isObjectNew = true;
|
||||
} else {
|
||||
T oldObject = entries.get(identifier);
|
||||
int oldId = indexedEntries.getId(oldObject);
|
||||
if (oldObject != object || oldId != id) {
|
||||
fabric_removeObjectEvent.invoker().onEntryRemoved(oldId, identifier, oldObject);
|
||||
fabric_isObjectNew = true;
|
||||
} else {
|
||||
fabric_isObjectNew = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked", "ConstantConditions"})
|
||||
@SuppressWarnings("unchecked")
|
||||
@Inject(method = "set", at = @At("RETURN"))
|
||||
public void setPost(int id, Identifier identifier, Object object, CallbackInfoReturnable info) {
|
||||
SimpleRegistry<Object> registry = (SimpleRegistry<Object>) (Object) this;
|
||||
fabric_postRegisterEvent.invoker().onPostRegister(id, identifier, object);
|
||||
if (fabric_isObjectNew) {
|
||||
fabric_addObjectEvent.invoker().onEntryAdded(id, identifier, object);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -193,7 +217,7 @@ public abstract class MixinIdRegistry<T> implements RemappableRegistry, Listenab
|
|||
|
||||
for (Identifier id : registry.getIds()) {
|
||||
if (!remoteIndexedEntries.containsKey(id)) {
|
||||
FABRIC_LOGGER.warn("Adding " + id + " to registry.");
|
||||
FABRIC_LOGGER.warn("Adding " + id + " to saved/remote registry.");
|
||||
remoteIndexedEntries.put(id, ++maxValue);
|
||||
}
|
||||
}
|
||||
|
@ -204,14 +228,22 @@ public abstract class MixinIdRegistry<T> implements RemappableRegistry, Listenab
|
|||
for (Identifier id : registry.getIds()) {
|
||||
if (!remoteIndexedEntries.containsKey(id)) {
|
||||
droppedIds.add(id);
|
||||
Object object = registry.get(id);
|
||||
|
||||
// Emit RemoveObject events for removed objects.
|
||||
//noinspection unchecked
|
||||
fabric_getRemoveObjectEvent().invoker().onEntryRemoved(registry.getRawId(object), id, (T) object);
|
||||
}
|
||||
}
|
||||
|
||||
entries.keySet().removeAll(droppedIds);
|
||||
}
|
||||
|
||||
// Inform about registry clearing.
|
||||
fabric_preClearEvent.invoker().onPreClear();
|
||||
Int2IntMap idMap = new Int2IntOpenHashMap();
|
||||
for (Object o : indexedEntries) {
|
||||
Identifier id = registry.getId(o);
|
||||
idMap.put(registry.getRawId(o), remoteIndexedEntries.getInt(id));
|
||||
}
|
||||
|
||||
// entries was handled above, if it was necessary.
|
||||
indexedEntries.clear();
|
||||
|
@ -235,29 +267,40 @@ public abstract class MixinIdRegistry<T> implements RemappableRegistry, Listenab
|
|||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
//noinspection unchecked
|
||||
fabric_preRegisterEvent.invoker().onPreRegister(id, identifier, object, false);
|
||||
|
||||
// Add the new object, increment nextId to match.
|
||||
indexedEntries.put(object, id);
|
||||
if (nextId <= id) {
|
||||
nextId = id + 1;
|
||||
}
|
||||
|
||||
//noinspection unchecked
|
||||
fabric_postRegisterEvent.invoker().onPostRegister(id, identifier, object);
|
||||
}
|
||||
|
||||
//noinspection unchecked
|
||||
fabric_getRemapEvent().invoker().onRemap(new RemapStateImpl(registry, idMap));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unmap(String name) throws RemapException {
|
||||
if (fabric_prevIndexedEntries != null) {
|
||||
List<Identifier> addedIds = new ArrayList<>();
|
||||
|
||||
// Emit AddObject events for previously culled objects.
|
||||
for (Identifier id : fabric_prevEntries.keySet()) {
|
||||
if (!entries.containsKey(id)) {
|
||||
assert fabric_prevIndexedEntries.containsKey(id);
|
||||
addedIds.add(id);
|
||||
}
|
||||
}
|
||||
|
||||
entries.clear();
|
||||
entries.putAll(fabric_prevEntries);
|
||||
|
||||
remap(name, fabric_prevIndexedEntries, RemapMode.AUTHORITATIVE);
|
||||
|
||||
for (Identifier id : addedIds) {
|
||||
fabric_getAddObjectEvent().invoker().onEntryAdded(indexedEntries.getId(entries.get(id)), id, entries.get(id));
|
||||
}
|
||||
|
||||
fabric_prevIndexedEntries = null;
|
||||
fabric_prevEntries = null;
|
||||
}
|
||||
|
|
|
@ -39,12 +39,14 @@ import java.io.IOException;
|
|||
|
||||
@Mixin(WorldSaveHandler.class)
|
||||
public class MixinWorldSaveHandler {
|
||||
@Unique
|
||||
private static final int FABRIC_ID_REGISTRY_BACKUPS = 3;
|
||||
@Unique
|
||||
private static Logger FABRIC_LOGGER = LogManager.getLogger();
|
||||
@Shadow
|
||||
public File worldDir;
|
||||
|
||||
@Unique
|
||||
private CompoundTag fabric_lastSavedIdMap = null;
|
||||
|
||||
private boolean fabric_readIdMapFile(File file) throws IOException, RemapException {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue