#Getting GenericTypeArguments

1 messages · Page 1 of 1 (latest)

rich stream
#

@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...

umbral fjord
#

what did you try, exactly?

rich stream
#
                        
                        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

umbral fjord
#

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

rich stream
#

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

umbral fjord
#

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

rich stream
#

ah okay i see

umbral fjord
#

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

rich stream
#

[SerializeField] private Type serializedType = typeof(Consideration<NewTestConsideration2Data>);

#

i kinda thought having something like this would make that Consideration<NewTestConsideration2Data> somehow discoverable

umbral fjord
#

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), /* ... */ };

rich stream
#

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)

umbral fjord
#

you'd need to unseal Consideration to make that trick work, then

rich stream
#
    where T : unmanaged, IComponentData
{
    public Entity targetEntity;
    public Entity ownerEntity;
    public float score;
}
#

why is that sealed though?

umbral fjord
#

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

rich stream
#

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

umbral fjord
#

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

rich stream
#

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?

umbral fjord
#

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

rich stream
umbral fjord
#

are you searching for types derived from ConsiderationSys<>?

rich stream
#

which Consideration<T> is

#

and so i thought i will also find all Consideration<AnyOtherStruct>

umbral fjord
#

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

rich stream
#

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

umbral fjord
#

are you sure you can't just put a list somewhere? Or can Consideration<T> have user-defined Ts?

rich stream
#

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.

rich stream
#

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

umbral fjord
#

cool! Looks like an interesting project, good luck with it

rich stream
#

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

rich stream
#

just to finish this up: