0
\$\begingroup\$

First of all, I want mods in my game, as stated in a previous question, I want to do that via registries. Users make content known to the game in the form of 'Registering' it, then it can be used in several other stuff. Registering a block to have it appear on the terrain is one example.

Registering is done in the form of events, where each registry has an OnEntryCollection event with a list where other classes subscribe to in order to add Entries, and then it gets invoked to gather said entries.

Basically I have a registry system, where there's a large meta-registry(The Game-registry) that has a list of smaller Registry<T> registries, each dedicated to a type (a block, an item, etc). I want to be able to add to these registries via a Registry.Add(T obj) method, but I'm not exactly sure how to do that because in order to store them I had to use an empty interface I made (IRegistry).

This is meant to be a way for me to add Entries in through code, from specific files I parse in, while also allowing modders to add in custom content through registry events I will add later. Nothing is meant to be added in through the inspector, rather registered in through events.

My code:

Game-Registry:

[SerializeField] List<IRegistry> registries = new List<IRegistry>();

Registry :

public class Registry<T> : IRegistry where T : IRegistryEntry {
    Dictionary<ResourceLocation, T> EntryDictionary = new Dictionary<ResourceLocation, T>();

    public delegate void registryAdditionHandler(List<T> entries);
    public event registryAdditionHandler OnRegisterAddEntries;

    ResourceLocation keyName;

    public Registry(ResourceLocation keyName) {
        this.keyName = keyName;
    }

    public void Register(T entry) {
        EntryDictionary.Add(entry.GetRegistryName(), entry);
    }
    public void Remove(ResourceLocation loc) {
        EntryDictionary.Remove(loc);
    }

    public T Get(ResourceLocation key) {
       return EntryDictionary[key];
    }
    public int Count() {
        return EntryDictionary.Count;

    }

    public bool ContainsEntryKey(ResourceLocation key) {
        return EntryDictionary.ContainsKey(key);
    }
    public bool ContainsEntryValue(T value) {
        return EntryDictionary.ContainsValue(value);
    }

    public bool TryGetValue(ResourceLocation key, out T value) {
        if (EntryDictionary.TryGetValue(key,out value)) {
            return true;
        }
        return false;
    }

    public ResourceLocation getRegistryName() {
        return keyName;
    }
}

IRegistry interface:

public interface IRegistry  {
}
\$\endgroup\$
8
  • \$\begingroup\$ Wait, the T entry at that point is derived from IRegistryEntry, a completely different interface. \$\endgroup\$
    – Faih Faih
    May 26, 2020 at 15:54
  • \$\begingroup\$ So then help us understand how your code tries to marry the list of IRegistry items with the Dictionary of IRegistryEntry items. It looks like there's more context here we can't see from just the samples you've shown us thus far. \$\endgroup\$
    – DMGregory
    May 26, 2020 at 16:01
  • \$\begingroup\$ Or, back up a step, forget about generics entirely, and just tell us what function these registries are meant to serve in your game, and how they're meant to be used. Then we can propose solutions that meet those needs, whether or not they have anything at all to do with the code you've shown so far. Getting bogged down in a particular implementation rather than focusing on the root problem can often lead you into an X/Y problem tarpit. \$\endgroup\$
    – DMGregory
    May 26, 2020 at 16:05
  • \$\begingroup\$ The Game registry wants to have a list of the generic Registries<T>, and if I wanted to add an entry in to, let's say, the block registry, I would have to grab it from the Game-Registry list and try call .Add(T entry). I can't do that, because the game registry is storing IRegistries instead, and I am not sure how to correct this. \$\endgroup\$
    – Faih Faih
    May 26, 2020 at 16:05
  • \$\begingroup\$ Are these individual registries MonoBehaviours or ScriptableObjects? \$\endgroup\$
    – DMGregory
    May 26, 2020 at 16:11

1 Answer 1

0
\$\begingroup\$

Are you looking for something like this?

public class MetaRegistry
{
    Dictionary<System.Type, IRegistry> _registries;

    Registry<T> GetOrCreateRegistryOfType<T>() where T: IRegistryEntry {
        Registry<T> registry;
        if (_registries.TryGetValue(typeof(T), out IRegistry interfaceRegistry)) {
            registry = (Registry<T>)interfaceRegistry;
        } else {
            registry = new Registry<T>();
            _registries.Add(typeof(T), registry);
        }
        return registry;
    }

    void AddToRegistry<T>(T value) where T : IRegistryEntry {
        GetOrCreateRegistryOfType<T>().Add(value);
    }
}
\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .