From 8dfb97fd87cb9de71423fbf2be7d9645b5bfff4c Mon Sep 17 00:00:00 2001 From: shedaniel Date: Wed, 30 Dec 2020 20:24:09 +0800 Subject: [PATCH] Add DeferredRegister --- .../registry/DeferredRegister.java | 130 ++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 common/src/main/java/me/shedaniel/architectury/registry/DeferredRegister.java diff --git a/common/src/main/java/me/shedaniel/architectury/registry/DeferredRegister.java b/common/src/main/java/me/shedaniel/architectury/registry/DeferredRegister.java new file mode 100644 index 00000000..55d56b9f --- /dev/null +++ b/common/src/main/java/me/shedaniel/architectury/registry/DeferredRegister.java @@ -0,0 +1,130 @@ +/* + * This file is part of architectury. + * Copyright (C) 2020 shedaniel + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package me.shedaniel.architectury.registry; + +import com.google.common.base.Objects; +import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.LazyLoadedValue; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Supplier; + +public class DeferredRegister { + private final Supplier registriesSupplier; + private final ResourceKey> key; + private final List> entries = new ArrayList<>(); + private boolean registered = false; + + private DeferredRegister(Supplier registriesSupplier, ResourceKey> key) { + this.registriesSupplier = registriesSupplier; + this.key = key; + } + + @NotNull + public static DeferredRegister create(Registries registries, ResourceKey> key) { + return new DeferredRegister<>(() -> registries, key); + } + + @NotNull + public static DeferredRegister create(Supplier registries, ResourceKey> key) { + return new DeferredRegister<>(registries, key); + } + + @NotNull + public static DeferredRegister create(LazyLoadedValue registries, ResourceKey> key) { + return create(registries::get, key); + } + + public RegistrySupplier register(ResourceLocation id, Supplier supplier) { + Entry entry = new Entry<>(id, supplier); + this.entries.add(entry); + if (registered) { + Registry registry = registriesSupplier.get().get(key); + entry.value = registry.registerSupplied(entry.id, entry.supplier); + } + return entry; + } + + public void register() { + if (registered) { + throw new IllegalStateException("Cannot register a deferred register twice!"); + } + registered = true; + Registry registry = registriesSupplier.get().get(key); + for (Entry entry : entries) { + entry.value = registry.registerSupplied(entry.id, entry.supplier); + } + } + + private class Entry implements RegistrySupplier { + private final ResourceLocation id; + private final Supplier supplier; + private RegistrySupplier value; + + public Entry(ResourceLocation id, Supplier supplier) { + this.id = id; + this.supplier = supplier; + } + + @Override + public @NotNull ResourceLocation getRegistryId() { + return key.location(); + } + + @Override + public @NotNull ResourceLocation getId() { + return id; + } + + @Override + public boolean isPresent() { + return value != null && value.isPresent(); + } + + @Override + public T get() { + if (isPresent()) { + return value.get(); + } + throw new NullPointerException("Registry Object not present: " + this.id); + } + + @Override + public int hashCode() { + return Objects.hashCode(getRegistryId(), getId()); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (!(obj instanceof RegistrySupplier)) return false; + RegistrySupplier other = (RegistrySupplier) obj; + return other.getRegistryId().equals(getRegistryId()) && other.getId().equals(getId()); + } + + @Override + public String toString() { + return getRegistryId().toString() + "@" + id.toString(); + } + } +}