Generic interfaces

I sketched something up based on the assumption you have T1, T2 -> T1. It makes use of a newly introduced feature in 5.0 which allows to instantiate generic types (including their adaptive content) at runtime. Kairos is making heavy use of that feature btw. Let me try to explain what’s happening in that patch.

Our ingredients are the following:

  • We have a generic interface IModifier<T1, T2> with two implementations Add<T1, T2> and Multiply<T1, T2>
  • Both of these implementations make use of an adaptive node called Lift which essentially lifts from T1 to T2 allowing us to use the normal adaptive nodes like + or * on the result.
  • For Lift we provide implementations for the case T → T, Float → Vector3 and Vector3 -> Float - more could be added of course

So far we can now create different generic instances of Add or Multiply with different permutations of its type arguments (Float & Float, Vector3 & Float, Float & Vector3). By adding additional Lift operations this list would grow quickly.

In any case, like it was already pointed out in this thread, you will only know your type arguments at runtime. So basically we need to find a way to create those Add or Multiply modifiers at runtime. Here the before mentioned new feature comes to the rescue: it’s a node called MakeGenericVLTypeInfo. Combined with GetTypeByName and CreateInstance we can now already start to create modifiers at runtime based on runtime type information only. Nice, but we lack one central part still: we don’t know how to call Modify - remember it is part of a generic interface, so we’d need to know the exact type instantation at compile time, which we don’t.

The trick here is to introduce a non-generic interface which will act as our non-generic accessor.
Now I could’ve implemented that non-generic version on the original classes (Add, Multiply) but decided for a different pattern, where I implement the non-generic accessor on a separate class which I then make available trhough a node called DynamicModifier. That DynamicModifier also asks for a model which describes what modifier to apply. There are for sure multiple ways of doing this, but I took the path we also took in Kairos since it’s quite common that you might want to pass implementation specific arguments. You’ll again find usage of the adaptive feature here, this time it’s about creating the modifier based on the model and the type arguments. Like I said, we did it like that in Kairos and it served us well so far, so why not stick to that pattern.

GenericInterfaceWithDynamicAccess.vl (68.8 KB)