-
Notifications
You must be signed in to change notification settings - Fork 74
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improvements to struct interop for DOTS #70
base: master
Are you sure you want to change the base?
Conversation
With the last commit, I think I fixed the generation issue Kasuromi found earlier. Now I added another kind of |
Il2CppInterop.Generator/Passes/Pass12CreateGenericNonBlittableTypes.cs
Outdated
Show resolved
Hide resolved
Il2CppInterop.Generator/Passes/Pass12CreateGenericNonBlittableTypes.cs
Outdated
Show resolved
Hide resolved
This PR of Il2CppInterop should be used from now on: BepInEx/Il2CppInterop#70
Hello! I am open to reviewing this pull request if you rebase it. |
I can do that sometime later, however recently I'm rather busy with Core Keeper's 1.0 release. |
Also if I had to guess there is a lot of changes that would be needed because of #124 for this to work properly. |
That is correct. The switch to AsmResolver required many changes. In some ways, it was a rewrite of the generator. |
Do you have any Cecil to AsmResolver migration guides perhaps? I'm not familiar with the latter. |
They are very similar, though I don't have any guides. |
f38c606
to
6663045
Compare
@ds5678 Hello, I have rebased and updated the PR in order to work with AsmResolver as you asked. (Previous version of the PR is available here) I have checked that the output of this version of PR is consistent or very close to original PR output. To verify this I used your tool mentioned in your #124 PR. Additionally I have installed a few mods from VRising Thunderstore (Bloodstone, VCF). From my quick test, all tested mods are working. |
@@ -6,7 +6,7 @@ namespace Il2CppInterop.Runtime.Attributes; | |||
/// This attribute indicates that the target should not be exposed to IL2CPP in injected classes | |||
/// </summary> | |||
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Property | | |||
AttributeTargets.Event)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not injecting all the instance fields of a struct sounds like a bad idea.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, you are definitely correct that this is a bad idea.
The reason I did this was that you cannot inject a generic type. And I needed to have my job structs contain a handle type. Like this:
public struct ExampleJob
{
//These fields can be used as is
public float inputData;
public NativeArray<Entity> entities;
public EntityCommandBuffer ecb;
// I can't inject this type, nor can I use original type (Because it doesn't have code compiled for CustomComponentCD)
// So I hide the field
[HideFromIl2Cpp]
public ModComponentDataFromEntity<CustomComponentCD> inputFromEntity;
}
In order not to have crazy issues I had to hack Job Scheduler code, access internal structs and manually adjust the struct size for the code to work.
Or simply it's a giant hack, but it did work. (Here's the code: link)
As such I see two solutions:
- Remove this ability and implement generic injection or some way to use generic types with types not used by the game code (This one would probably be a huge thing, and would simplify a lot of things I had to do)
- Keep this for now, but perhaps warn if encountered to inform the modder about consequences of doing this
if (baseClassPointer.ValueType || baseClassPointer.EnumType) | ||
throw new ArgumentException($"Base class {baseType} is value type and can't be inherited from"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does baseClassPointer.ValueType
return true
for System.ValueType
? If not, this shouldn't be changed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm pretty sure it does return true
. This check being removed is exactly why structs can be injected. This is big part of this PR.
Specifically structs are needed because Unity's ECS (Entity Component System) heavily relies on structs to hold game state. By injecting custom ones we can add our own game state.
|
||
namespace Il2CppInterop.Generator.Utils; | ||
|
||
public struct GenericParameterContext |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's wrong with AsmResolver.DotNet.Signatures.GenericContext
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The problem is that It handles a different problem. Specifically GenericContext
allows to resolve a type from a GenericParamterSignature
.
But what I need here is to resolve GenericParameter
(Which has all the information about the parameter including constraints and attributes) from GenericParamterSignature
(Which is a weird type that doesn't even know who it belongs to).
This is all caused by the weird design of AsmResolver. I have read some messages on their discord describing why GenericParamterSignature
is as it is. However the fact metadata stores it this way, doesn't really justify complicating handling of GenericParamterSignature
by making them glorified ints. I found Cecil's approach of GenericParameters
having all context at all times much more convenient, and the code was written around that.
So GenericParameterContext
was needed to implement the logic with AsmResolver. Perhaps maybe Washi can take a look at this code and say how they would do it.
This PR includes three improvements, which make working with DOTS based games much easier:
unmanaged
.