#Getting GenericTypeArguments
1 messages · Page 1 of 1 (latest)
@knotty rapids had to go afk and just now tried it. I dont get it to work but it should be exactly what i need...
what did you try, exactly?
if (t.IsGenericTypeDefinition)
{
Debug.Log($"{t.Name} is a generic Type");
var genericTypeArguments = t.GenericTypeArguments;
Debug.Log(genericTypeArguments.Length);
}```
t is Consideration`1
and testtype is just a instance i created to make sure length of GenericTypeArguments should be 1
then t won't have any generic type arguments (or at least, one or more are not specified yet) because it's a generic type definition
typeof(Consideration<>).GenericTypeArguments isn't a concrete type
typeof(Consideration<Translation>).GenericTypeArguments[0] will be Translation
hmm so why do i not find concrete types of generic definitions when looping over all types in an assembly?
{
if (typeof(IBufferElementData).IsAssignableFrom(t) && t.IsPublic)
{
if (t.IsGenericTypeDefinition)
{
Debug.Log($"{t.Name} is a generic Type");
var genericTypeArguments = t.GenericTypeArguments;
Debug.Log(genericTypeArguments.Length);
}
var typeEntry = new SearchTreeEntry(new GUIContent(t.Name))
{
level = 3,
userData = t
};
tempTypeList.Add(typeEntry);
atLeastOneEntry = true;
}
}```
thats what i currently have. i have types like Consideration<NewTestConsiderationData> that would be IBufferElementData and public
what you're saying makes no sense. A generic type definition can't be concrete
List<T> is a generic type definition
List<string> is a generic type, but is not a generic type definition
ah okay i see
I suspect you don't have any concrete definitions of Consideration<T>. Searching for Consideration<Translation> will yield nothing, because the type you're looking for is Consideration<>, with a generic parameter of Translation
[SerializeField] private Type serializedType = typeof(Consideration<NewTestConsideration2Data>);
i kinda thought having something like this would make that Consideration<NewTestConsideration2Data> somehow discoverable
nope, but you can cheat a little
class TestConsideration2DataType : Consideration<NewTestConsideration2Data> {}
if there is a limit to the types that might be included, it's probably better to go that route instead
meaning:
var typesThatMightAppearInList = new [] { typeof(Consideration<>).MakeGenericType(typeof(NewTestConsideration2Data), /* ... */ };
hmm i think i cant do it in my case. TestConsiderationDataType must be a struct :S
it complains about Consideration beeing sealed (its public though)
you'd need to unseal Consideration to make that trick work, then
where T : unmanaged, IComponentData
{
public Entity targetEntity;
public Entity ownerEntity;
public float score;
}
why is that sealed though?
it's a struct
What are you trying to do, exactly? This seems more and more like a design smell
serializing a type probably means you're going to have to resort to even more reflection at runtime
oh boy i dont even know where to start explaining...
public class PositionRefTypeProvider : ComponentTypeProvider
{
[SerializeField] private Type serializedType = typeof(Translation);
public override Type GetComponentType()
{
return serializedType;
}
}```
I am codegenerating such a TypeProvider class for scriptable Objects representing Nodes in a graph where each TypeProvider holds a Type (which can also be generic) because i need that type to be discoverable by Burst. Basically i cannot use any reflection at runtime and need to do everything beforehand.
my current problem of finding generic types with arguments is that i want the User of my Graph to be able to select that generic type in a SearchWindow when he would click that IComponentData button:
instead of it displaying Consideration`1 in that searchwindow i need it to show Consideration<Translation> for example
These Nodes that "provide" types are used to codegen Generic Systems that then just look like this :
using UtilityAI.Core;
[assembly: Unity.Jobs.RegisterGenericJobType(typeof(OutputBufferToDecisionJob<Consideration<CraftBedData>>))]
[DisableAutoCreation]
public class CraftBedSys : ConsiderationSys<Consideration<CraftBedData>,Consideration<ProximityToCraftingStationData>,Consideration<AxeData>> {}```
so in the end i got graphs like this (values in that graph make no sense. thats my testgraph :S) :
basically each node represents a codegened system that gets its generic type parameters from the childnodes
its some kind of codeless UtilityAI for DOTS
well, if you can't define the types ahead of time, you might be forced into crawling the il code and looking for references that way
hmm what do you mean by define a type? public class CraftBedSys : ConsiderationSys<Consideration<CraftBedData>,Consideration<ProximityToCraftingStationData>,Consideration<AxeData>> {}
does this line not define the types?
I mean define the types that might be used for a given generic type definition, for example Consideration<any T> won't be discoverable unless you look for references to Consideration<> in method definitions. Otherwise, if you can define a concrete type like that it'll work fine
that was my original suggestion from before, define concrete types
yes but the concrete type i define with the system is not a Consideration<T> itself. it just has those as generic parameters. and somehow i cannot discover those despite them being used in a concrete type
are you searching for types derived from ConsiderationSys<>?
#1081500508545617920 message
no i was searching through all assemblies looking for Types implementing IBufferElementData
which Consideration<T> is
and so i thought i will also find all Consideration<AnyOtherStruct>
the only Consideration that implements IBufferElementData is Consideration<>, so you should be finding Consideration` and that's it unless you scan through the assembly and look for anywhere Consideration gets used
hm ok i see. this seems too expensive since i scan through all assemblies... i bet thats why burst needs me to do this : [assembly: RegisterGenericComponentType(typeof(Consideration<BedsData>))]
i wonder if i can somehow get those registeredGenericComponentTypes as a list
are you sure you can't just put a list somewhere? Or can Consideration<T> have user-defined Ts?
yep user defines the T in Editor (which can be any IcomponentData/ IBufferElementData in whole Project) and i codegen the Consideration<UserSpecifiedT>
but i guess in the codegen step i can maintain a list.
Okay i looked into TypeManager after looking at that RegisterGenericComponentType.
https://docs.unity3d.com/Packages/com.unity.entities@1.0/api/Unity.Entities.TypeManager.html
TypeManager.AllTypes has the Consideration<AnyStruct> in the list when i register it as a GenericComponentType
i dont even have to care about assemblies anymore
Thank you so much for all that explaining! i wouldnt have known what to look for
cool! Looks like an interesting project, good luck with it
thanks! its actually really working great already. just the UX is not on point. just making it Editor only workflow without any code proved to be quite hard for a editor tooling noob like me
just to finish this up: