mirror of
https://github.com/FabricMC/fabric.git
synced 2024-12-01 03:47:18 -05:00
Add RegistryEntryAddedCallback.allEntries (#4235)
* Add RegistryEntryAddedCallback.allEntries
* Pass a RegistryEntry.Reference
* Remove some temp test code
* Add note about recursion.
(cherry picked from commit aa5b2ca19e
)
This commit is contained in:
parent
54a41b1cc9
commit
2758bfbf66
2 changed files with 135 additions and 0 deletions
|
@ -16,17 +16,54 @@
|
|||
|
||||
package net.fabricmc.fabric.api.event.registry;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import net.minecraft.registry.Registry;
|
||||
import net.minecraft.registry.entry.RegistryEntry;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import net.fabricmc.fabric.api.event.Event;
|
||||
import net.fabricmc.fabric.impl.registry.sync.ListenableRegistry;
|
||||
|
||||
/**
|
||||
* An event for when an entry is added to a registry.
|
||||
*
|
||||
* @param <T> the type of the entry within the registry
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface RegistryEntryAddedCallback<T> {
|
||||
/**
|
||||
* Called when a new entry is added to the registry.
|
||||
*
|
||||
* @param rawId the raw id of the entry
|
||||
* @param id the identifier of the entry
|
||||
* @param object the object that was added
|
||||
*/
|
||||
void onEntryAdded(int rawId, Identifier id, T object);
|
||||
|
||||
/**
|
||||
* Get the {@link Event} for the {@link RegistryEntryAddedCallback} for the given registry.
|
||||
*
|
||||
* @param registry the registry to get the event for
|
||||
* @return the event
|
||||
*/
|
||||
static <T> Event<RegistryEntryAddedCallback<T>> event(Registry<T> registry) {
|
||||
return ListenableRegistry.get(registry).fabric_getAddObjectEvent();
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a callback for all present and future entries in the registry.
|
||||
*
|
||||
* <p>Note: The callback is recursive and will be invoked for anything registered within the callback itself.
|
||||
*
|
||||
* @param registry the registry to listen to
|
||||
* @param consumer the callback that accepts a {@link RegistryEntry.Reference}
|
||||
*/
|
||||
static <T> void allEntries(Registry<T> registry, Consumer<RegistryEntry.Reference<T>> consumer) {
|
||||
event(registry).register((rawId, id, object) -> consumer.accept(registry.getEntry(id).orElseThrow()));
|
||||
// Call the consumer for all existing entries, after registering the callback.
|
||||
// This way if the callback registers a new entry, it will also be called for that entry.
|
||||
// It is also important to take a copy of the registry with .toList() to avoid concurrent modification exceptions if the callback modifies the registry.
|
||||
registry.streamEntries().toList().forEach(consumer);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* 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.test.registry.sync;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Captor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import net.minecraft.Bootstrap;
|
||||
import net.minecraft.SharedConstants;
|
||||
import net.minecraft.registry.Registry;
|
||||
import net.minecraft.registry.RegistryKey;
|
||||
import net.minecraft.registry.SimpleRegistry;
|
||||
import net.minecraft.registry.entry.RegistryEntry;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import net.fabricmc.fabric.api.event.registry.FabricRegistryBuilder;
|
||||
import net.fabricmc.fabric.api.event.registry.RegistryEntryAddedCallback;
|
||||
|
||||
public class RegistryEntryAddedCallbackTest {
|
||||
@Mock
|
||||
private Consumer<RegistryEntry.Reference<String>> mockConsumer;
|
||||
|
||||
@Captor
|
||||
private ArgumentCaptor<RegistryEntry.Reference<String>> captor;
|
||||
|
||||
@BeforeAll
|
||||
static void beforeAll() {
|
||||
SharedConstants.createGameVersion();
|
||||
Bootstrap.initialize();
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
void beforeEach() {
|
||||
MockitoAnnotations.openMocks(this);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testEntryAddedCallback() {
|
||||
RegistryKey<Registry<String>> testRegistryKey = RegistryKey.ofRegistry(id(UUID.randomUUID().toString()));
|
||||
SimpleRegistry<String> testRegistry = FabricRegistryBuilder.createSimple(testRegistryKey)
|
||||
.buildAndRegister();
|
||||
|
||||
Registry.register(testRegistry, id("before"), "before");
|
||||
RegistryEntryAddedCallback.allEntries(testRegistry, mockConsumer);
|
||||
|
||||
// Test that the callback can register new entries.
|
||||
RegistryEntryAddedCallback.allEntries(testRegistry, s -> {
|
||||
if (s.value().equals("before")) {
|
||||
Registry.register(testRegistry, id("during"), "during");
|
||||
}
|
||||
});
|
||||
|
||||
Registry.register(testRegistry, id("after"), "after");
|
||||
|
||||
verify(mockConsumer, times(3)).accept(captor.capture());
|
||||
|
||||
List<String> values = captor.getAllValues()
|
||||
.stream()
|
||||
.map(RegistryEntry.Reference::value)
|
||||
.toList();
|
||||
|
||||
assertEquals(3, values.size());
|
||||
assertEquals("before", values.getFirst());
|
||||
assertEquals("during", values.get(1));
|
||||
assertEquals("after", values.get(2));
|
||||
}
|
||||
|
||||
private static Identifier id(String path) {
|
||||
return Identifier.of("registry_sync_test_entry_added_test", path);
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue