Open Albeoris opened 2 years ago
Greetings!
Thank you for the proposal. This, however, is related more to Il2CppUnhollower which is the library for Il2Cpp<->Managed interop. I'll move the issue to our Il2CppUnhollower repo instead.
If this is still a requested feature, I could look into it, as I've worked on the Class-Injector before for generics and interfaces. I'm a little bit confused by this issue thread though. How would you work with the injected type? Do you want to pass it to il2cpp code or use it yourself somewhere? The example you provided is a standard library type and is not inheriting from Il2CppObjectBase.
Hi, @HookedBehemoth !
How would you work with the injected type? Do you want to pass it to il2cpp code or use it yourself somewhere?
Yes, this is still a requested feature:
IL2CPP does not contain all the methods that the original type has. For example, if the game authors did not use Dictionary<String,String>.TryGetValue, then the compiled code will not have this method.
Wanted change: the ability to register missing methods using the full type description as a reference. This will allow us to handle IL2CPP collections in the usual way, without having to convert the IL2CPP instance to a regular one by copying all the elements.
// Register type Dictionary<String, String> and all its methods
ClassInjector.EnsureTypeRegisteredWithAllMethods<Dictionary<String, String>>();
// Registers all methods for all types inherited from Dictionary<,>
ClassInjector.EnsureAllMethodsRegistered(typeof(Dictionary<,>));
Passing a Generic argument to the IL2CPP layer, it will be converted to a concrete type. If such a type does not exist in the assembly, an error will be thrown.
class Graph<T>
{
// Public method allow us to pass any Node<T>
void Add(Node<T> value);
// But there is only two implementations on IL2CPP layer:
// Graph_Event // Graph<Event>
// Graph_Condition // Graph<Condition>
// Node_Event // Node<Event>
// Node_Condition // Node<Condition>
}
// So this call will throw an error:
Graph<Scene>.Add(SpecialNodes.CurrentScene);
Wanted change: the ability to register Generic<Scene>
and its dependencies included Node<Scene>
on IL2CPP layer and use them without errors.
ClassInjector.EnsureTypeRegisteredWithAllMethods<Graph<Scene>>();
Ideally, we should support injecting any aspect of the type system. That would enable us to automatically inject unstripped classes as part of our code generation.
Describe your proposal
Generic types such as Dictionary, List and HashSet are very helpful in mod development.
Now we have to use Dictionary<Object, Object>, as it is most often found in every game. But it also does not support all the necessary methods, for example TryGetValue is often not available.
I'd like to get support for Generic types. It is not yet clear how they differ conceptually from any other types, since at the IL2CPP level we will get a specific type, like Dictionary_String_String.
Error:
Proposed solution
Add the ability to register a specific Generic type and all its methods.
If such a type is already registered, register the methods that are missing because they were not used at the time of compilation.
Alternatives
In the case of Dictionary, List and HashSet, we can continue to use Dictionary<Object, Object> under hood, but provide a clever wrapper like
for Reference types.
Related: BepInEx/BepInEx#334