Skip to content
This repository was archived by the owner on Jun 3, 2024. It is now read-only.

Commit 827b734

Browse files
rikka0w0coderbot16TheGlitch76
authored
Add custom registry support (#79)
* Add custom registry support * Use vanilla registry for storage, simplify impl * Simplify the vanilla wrapper, ForgeRegistry#register() now supports replacement * Code clean up * more clean up * add ClearableRegistry interface * version 0.2.0 * Add Readme.md, add StructureFeature registration support * code clean up * Remove clear() on vanilla registry, impl remove() for Forge mod registries * Add default registry entry support * Fix problems * Better removable registry impl * Make the registry system inject less invasive * Fix some potential compatibility problem in StructureFeature registration and getSlaveMap() * Update patchwork-registries/src/main/java/net/minecraftforge/registries/GameData.java Co-authored-by: coderbot <[email protected]> * Add patchwork$ prefix and code style fixes * Update patchwork-registries/src/main/java/net/minecraftforge/registries/ForgeRegistry.java Co-authored-by: Glitch <[email protected]> * Apply suggestions from code review Co-authored-by: Glitch <[email protected]> * rename * resolve collision * resolve collision * resolve collision, last time a wrong file was edited Co-authored-by: coderbot <[email protected]> Co-authored-by: Glitch <[email protected]>
1 parent 8151578 commit 827b734

28 files changed

+1698
-227
lines changed

patchwork-dispatcher/src/main/java/net/patchworkmc/impl/Patchwork.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import org.apache.logging.log4j.Logger;
3030
import net.minecraftforge.api.distmarker.Dist;
3131
import net.minecraftforge.common.MinecraftForge;
32+
import net.minecraftforge.event.RegistryEvent;
3233
import net.minecraftforge.eventbus.api.Event;
3334
import net.minecraftforge.fml.DistExecutor;
3435
import net.minecraftforge.fml.ModContainer;
@@ -66,7 +67,10 @@ private static void dispatch(Map<ForgeInitializer, FMLModContainer> mods, Functi
6667
for (FMLModContainer container : mods.values()) {
6768
ModLoadingContext.get().setActiveContainer(container, new FMLJavaModLoadingContext(container));
6869

69-
container.getEventBus().post(provider.apply(container));
70+
Event event = provider.apply(container);
71+
LOGGER.debug("Firing event for modid {} : {}", container.getModId(), event.toString());
72+
container.getEventBus().post(event);
73+
LOGGER.debug("Fired event for modid {} : {}", container.getModId(), event.toString());
7074

7175
ModLoadingContext.get().setActiveContainer(null, "minecraft");
7276
}
@@ -118,6 +122,7 @@ public void onInitialize() {
118122
ModList.get().setLoadedMods(mods.values());
119123
// Send initialization events
120124

125+
dispatch(mods, new RegistryEvent.NewRegistry());
121126
RegistryEventDispatcher.dispatchRegistryEvents(event -> dispatch(mods, event));
122127
dispatch(mods, FMLCommonSetupEvent::new);
123128

patchwork-registries/README.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Implemented features
2+
1. `RegistryEvent.NewRegistry` for allowing forge mods to add their own registry
3+
2. `RegistryEvent.Register` for different in-game object registration and forge mods' custom registry
4+
3. (TODO 9) StructureFeature and Feature registry
5+
4. IForgeRegistry callbacks: CreateCallback, AddCallback and ClearCallback
6+
5. Default entry support
7+
6. Slave maps for wrapped vanilla registries: IForgeRegistry#getSlaveMap
8+
7. (TODO 2) A fully modifiable registry for custom Forge mod registries
9+
8. (TODO 5) Forge mods can now access fabric registries via the vanilla registry, if they really need to.
10+
11+
# TODO
12+
1. StructureFeature registration needs more testing
13+
2. ~~A fully modifiable Forge mod registry implementation~~
14+
3. Code clean up in ForgeRegistries, the entry order should match Forge's version.
15+
4. Custom forge registries and Patchwork's wrapper implementation, see GameData:
16+
```
17+
public static final Identifier MODDIMENSIONS = new Identifier("forge:moddimensions");
18+
public static final Identifier SERIALIZERS = new Identifier("minecraft:dataserializers");
19+
public static final Identifier LOOT_MODIFIER_SERIALIZERS = new Identifier("forge:loot_modifier_serializers");
20+
```
21+
5. ~~Make fabric registries visible to Forge mods (Carefully consider this!)~~
22+
6. Unimplemented features in ForgeRegistry and RegistryManager: saveToDisk, legacyName, alias, sync, dump
23+
7. Unimplemented IForgeRegistry callbacks: ValidateCallback, BakeCallback, DummyFactory and MissingFactory
24+
8. Some vanilla registry types are not patched yet, add checks to avoid crash, see `ForgeRegistry#<init>`
25+
9. ~~Make callbacks for handling StructureFeature registry~~
26+
27+
# Note
28+
1. Vanilla and Fabric registry system does not support replacement and clearing, an error will be thrown if such operation is performed by a Forge mod

patchwork-registries/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
archivesBaseName = "patchwork-registries"
2-
version = getSubprojectVersion(project, "0.1.0")
2+
version = getSubprojectVersion(project, "0.3.0")
33

44
dependencies {
55
compile project(path: ':patchwork-fml', configuration: 'dev')

patchwork-registries/src/main/java/net/minecraftforge/event/RegistryEvent.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
package net.minecraftforge.event;
2121

22+
import net.minecraftforge.eventbus.api.Event;
2223
import net.minecraftforge.eventbus.api.GenericEvent;
2324
import net.minecraftforge.registries.IForgeRegistry;
2425
import net.minecraftforge.registries.IForgeRegistryEntry;
@@ -30,6 +31,16 @@ public class RegistryEvent<T> extends GenericEvent<T> {
3031
super(clazz);
3132
}
3233

34+
/**
35+
* Register new registries when you receive this event.
36+
*/
37+
public static class NewRegistry extends Event {
38+
@Override
39+
public String toString() {
40+
return "RegistryEvent.NewRegistry";
41+
}
42+
}
43+
3344
public static class Register<V extends IForgeRegistryEntry<V>> extends RegistryEvent<V> {
3445
private final IForgeRegistry<V> registry;
3546
private final Identifier name;
@@ -51,5 +62,10 @@ public IForgeRegistry<V> getRegistry() {
5162
public Identifier getName() {
5263
return name;
5364
}
65+
66+
@Override
67+
public String toString() {
68+
return "RegistryEvent.Register<" + registry.getRegistryName() + ">";
69+
}
5470
}
5571
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* Minecraft Forge, Patchwork Project
3+
* Copyright (c) 2016-2020, 2019-2020
4+
*
5+
* This library is free software; you can redistribute it and/or
6+
* modify it under the terms of the GNU Lesser General Public
7+
* License as published by the Free Software Foundation version 2.1
8+
* of the License.
9+
*
10+
* This library is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+
* Lesser General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU Lesser General Public
16+
* License along with this library; if not, write to the Free Software
17+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18+
*/
19+
20+
package net.minecraftforge.fml.common.registry;
21+
22+
import net.minecraftforge.registries.IForgeRegistry;
23+
import net.minecraftforge.registries.IForgeRegistryEntry;
24+
import net.minecraftforge.registries.RegistryManager;
25+
26+
public class GameRegistry {
27+
/**
28+
* Retrieves the registry associated with this super class type.
29+
* If the return is non-null it is HIGHLY recommended that modders cache this
30+
* value as the return will never change for a given type in a single run of Minecraft once set.
31+
*
32+
* @param registryType The base class of items in this registry.
33+
* @return The registry, Null if none is registered.
34+
*/
35+
public static <K extends IForgeRegistryEntry<K>> IForgeRegistry<K> findRegistry(Class<K> registryType) {
36+
return RegistryManager.ACTIVE.getRegistry(registryType);
37+
}
38+
}

patchwork-registries/src/main/java/net/minecraftforge/registries/ForgeRegistries.java

Lines changed: 40 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -20,47 +20,7 @@
2020
package net.minecraftforge.registries;
2121

2222
import net.minecraft.Bootstrap;
23-
import net.minecraft.block.Block;
24-
import net.minecraft.block.entity.BlockEntityType;
25-
import net.minecraft.container.ContainerType;
26-
import net.minecraft.enchantment.Enchantment;
27-
import net.minecraft.entity.EntityType;
28-
import net.minecraft.entity.ai.brain.Activity;
29-
import net.minecraft.entity.ai.brain.MemoryModuleType;
30-
import net.minecraft.entity.ai.brain.Schedule;
31-
import net.minecraft.entity.ai.brain.sensor.SensorType;
32-
import net.minecraft.entity.decoration.painting.PaintingMotive;
33-
import net.minecraft.entity.effect.StatusEffect;
34-
import net.minecraft.fluid.Fluid;
35-
import net.minecraft.item.Item;
36-
import net.minecraft.particle.ParticleType;
37-
import net.minecraft.potion.Potion;
38-
import net.minecraft.recipe.RecipeSerializer;
39-
import net.minecraft.recipe.RecipeType;
40-
import net.minecraft.sound.SoundEvent;
41-
import net.minecraft.stat.StatType;
42-
import net.minecraft.structure.StructurePieceType;
43-
import net.minecraft.structure.pool.StructurePoolElementType;
44-
import net.minecraft.structure.processor.StructureProcessorType;
45-
import net.minecraft.structure.rule.RuleTestType;
4623
import net.minecraft.util.Identifier;
47-
import net.minecraft.util.registry.Registry;
48-
import net.minecraft.village.VillagerProfession;
49-
import net.minecraft.village.VillagerType;
50-
import net.minecraft.world.biome.Biome;
51-
import net.minecraft.world.biome.source.BiomeSourceType;
52-
import net.minecraft.world.chunk.ChunkStatus;
53-
import net.minecraft.world.dimension.DimensionType;
54-
import net.minecraft.world.gen.carver.Carver;
55-
import net.minecraft.world.gen.chunk.ChunkGeneratorType;
56-
import net.minecraft.world.gen.decorator.Decorator;
57-
import net.minecraft.world.gen.feature.Feature;
58-
import net.minecraft.world.gen.feature.StructureFeature;
59-
import net.minecraft.world.gen.surfacebuilder.SurfaceBuilder;
60-
import net.minecraft.world.poi.PointOfInterestType;
61-
62-
import net.patchworkmc.impl.registries.RegistryClassMapping;
63-
import net.patchworkmc.impl.registries.RegistryEventDispatcher;
6424

6525
/**
6626
* A class that exposes static references to all vanilla registries.
@@ -101,65 +61,56 @@ public class ForgeRegistries {
10161
public static final IForgeRegistry SURFACE_BUILDERS;
10262
public static final IForgeRegistry PROFESSIONS;
10363

104-
// TODO: Forge Registries, when these are implemented
64+
// TODO: Forge Registries, unimplemented
10565
// public static final IForgeRegistry MOD_DIMENSIONS = wrap(ModDimension.class);
10666
// public static final IForgeRegistry DATA_SERIALIZERS = wrap(DataSerializerEntry.class);
10767

10868
static {
10969
// Make sure all the registries have been setup first.
11070
Bootstrap.initialize();
11171

112-
BLOCKS = wrap("block", Block.class);
113-
ITEMS = wrap("item", Item.class);
114-
ACTIVITIES = wrap("activity", Activity.class);
115-
BIOMES = wrap("biome", Biome.class);
116-
BIOME_PROVIDER_TYPES = wrap("biome_source_type", BiomeSourceType.class);
117-
TILE_ENTITIES = wrap("block_entity_type", BlockEntityType.class);
118-
WORLD_CARVERS = wrap("carver", Carver.class);
119-
CHUNK_GENERATOR_TYPES = wrap("chunk_generator_type", ChunkGeneratorType.class);
120-
CHUNK_STATUS = wrap("chunk_status", ChunkStatus.class);
121-
wrap("custom_stat", Identifier.class);
122-
DECORATORS = wrap("decorator", Decorator.class);
123-
wrap("dimension_type", DimensionType.class);
124-
ENCHANTMENTS = wrap("enchantment", Enchantment.class);
125-
ENTITIES = wrap("entity_type", EntityType.class);
126-
FEATURES = wrap("feature", Feature.class);
127-
FLUIDS = wrap("fluid", Fluid.class);
128-
MEMORY_MODULE_TYPES = wrap("memory_module_type", MemoryModuleType.class);
129-
CONTAINERS = wrap("menu", ContainerType.class);
130-
POTIONS = wrap("mob_effect", StatusEffect.class);
131-
PAINTING_TYPES = wrap("motive", PaintingMotive.class);
132-
PARTICLE_TYPES = wrap("particle_type", ParticleType.class);
133-
POI_TYPES = wrap("point_of_interest_type", PointOfInterestType.class);
134-
POTION_TYPES = wrap("potion", Potion.class);
135-
RECIPE_SERIALIZERS = wrap("recipe_serializer", RecipeSerializer.class);
136-
wrap("recipe_type", RecipeType.class);
137-
wrap("rule_test", RuleTestType.class);
138-
SCHEDULES = wrap("schedule", Schedule.class);
139-
SENSOR_TYPES = wrap("sensor_type", SensorType.class);
140-
SOUND_EVENTS = wrap("sound_event", SoundEvent.class);
141-
STAT_TYPES = wrap("stat_type", StatType.class);
142-
wrap("structure_feature", StructureFeature.class);
143-
wrap("structure_piece", StructurePieceType.class);
144-
wrap("structure_pool_element", StructurePoolElementType.class);
145-
wrap("structure_processor", StructureProcessorType.class);
146-
SURFACE_BUILDERS = wrap("surface_builder", SurfaceBuilder.class);
147-
PROFESSIONS = wrap("villager_profession", VillagerProfession.class);
148-
wrap("villager_type", VillagerType.class);
72+
BLOCKS = GameData.wrapVanilla(GameData.BLOCKS);
73+
ITEMS = GameData.wrapVanilla(GameData.ITEMS);
74+
ACTIVITIES = GameData.wrapVanilla(GameData.ACTIVITIES);
75+
BIOMES = GameData.wrapVanilla(GameData.BIOMES);
76+
BIOME_PROVIDER_TYPES = GameData.wrapVanilla(GameData.BIOME_PROVIDER_TYPES);
77+
TILE_ENTITIES = GameData.wrapVanilla(GameData.TILEENTITIES);
78+
WORLD_CARVERS = GameData.wrapVanilla(GameData.WORLD_CARVERS);
79+
CHUNK_GENERATOR_TYPES = GameData.wrapVanilla(GameData.CHUNK_GENERATOR_TYPES);
80+
CHUNK_STATUS = GameData.wrapVanilla(GameData.CHUNK_STATUS);
81+
wrap("custom_stat");
82+
DECORATORS = GameData.wrapVanilla(GameData.DECORATORS);
83+
wrap("dimension_type");
84+
ENCHANTMENTS = GameData.wrapVanilla(GameData.ENCHANTMENTS);
85+
ENTITIES = GameData.wrapVanilla(GameData.ENTITIES);
86+
FEATURES = GameData.wrapVanilla(GameData.FEATURES);
87+
FLUIDS = GameData.wrapVanilla(GameData.FLUIDS);
88+
MEMORY_MODULE_TYPES = GameData.wrapVanilla(GameData.MEMORY_MODULE_TYPES);
89+
CONTAINERS = GameData.wrapVanilla(GameData.CONTAINERS);
90+
POTIONS = GameData.wrapVanilla(GameData.POTIONS);
91+
PAINTING_TYPES = GameData.wrapVanilla(GameData.PAINTING_TYPES);
92+
PARTICLE_TYPES = GameData.wrapVanilla(GameData.PARTICLE_TYPES);
93+
POI_TYPES = GameData.wrapVanilla(GameData.POI_TYPES);
94+
POTION_TYPES = GameData.wrapVanilla(GameData.POTIONTYPES);
95+
RECIPE_SERIALIZERS = GameData.wrapVanilla(GameData.RECIPE_SERIALIZERS);
96+
wrap("recipe_type");
97+
wrap("rule_test");
98+
SCHEDULES = GameData.wrapVanilla(GameData.SCHEDULES);
99+
SENSOR_TYPES = GameData.wrapVanilla(GameData.SENSOR_TYPES);
100+
SOUND_EVENTS = GameData.wrapVanilla(GameData.SOUNDEVENTS);
101+
STAT_TYPES = GameData.wrapVanilla(GameData.STAT_TYPES);
102+
wrap("structure_feature");
103+
wrap("structure_piece");
104+
wrap("structure_pool_element");
105+
wrap("structure_processor");
106+
SURFACE_BUILDERS = GameData.wrapVanilla(GameData.SURFACE_BUILDERS);
107+
PROFESSIONS = GameData.wrapVanilla(GameData.PROFESSIONS);
108+
wrap("villager_type");
149109
}
150110

151111
@SuppressWarnings("unchecked")
152-
private static <T> IForgeRegistry wrap(String name, Class superClazz) {
153-
Identifier identifier = new Identifier("minecraft", name);
154-
Registry registry = Registry.REGISTRIES.get(identifier);
155-
156-
ForgeRegistry wrapped = new ForgeRegistry(identifier, registry, superClazz);
157-
158-
RegistryClassMapping.register(wrapped);
159-
RegistryManager.ACTIVE.addRegistry(identifier, wrapped);
160-
RegistryEventDispatcher.register(wrapped);
161-
162-
return wrapped;
112+
private static void wrap(String vanillaName) {
113+
GameData.wrapVanilla(new Identifier(vanillaName));
163114
}
164115

165116
public static void init() {

0 commit comments

Comments
 (0)