aardvark-platform / aardvark.base

Aardvark.Base is the foundation of the open-source Aardvark Platform for visual computing, real-time graphics, and visualization.
https://aardvarkians.com/
Apache License 2.0
153 stars 9 forks source link

IO Coder ProxyType concept seems broken #77

Open luithefirst opened 2 years ago

luithefirst commented 2 years ago

Does anyone remember what use cases ProxyTypes are for and how they are supposed to be used?

I for example have these, but actually I no longer directly code PixImages for quite a while:

Aardvark.Base.Coder.TypeInfo.Add(new Aardvark.Base.Coder.TypeInfo(typeof(PixImage<float>), () => new PixImageProxy<float>())
            {
                Object2ProxyFun = x => ((PixImage)x).ToFieldCoderProxy(),
                Proxy2ObjectFun = x => ((PixImageProxy)x).ToPixImage(),
                ProxyType = typeof(PixImageProxy<float>)
            });

I believe they were necessary because there was some restriction with generics. I would need to create an example with PixImage to see how this would have worked, but actually, a see some flaws in the coder when proxies are used.

The creator of the TypeInfo "() => new PixImageProxy()" creates this proxy object. When this is used in the coder during deserialization the Line: https://github.com/aardvark-platform/aardvark.base/blob/4eb7b4728c79eeec641146a6807820632a38ae8c/src/Aardvark.Base.IO/BinaryReadingCoder.cs#L226 stores a ref to the proxy object and when the ref is used later you get an InvalidCastException. Note: Within CodeFields, a ref to the parent object may also already be used, but the Proxy2ObjectFun would only be invoked after this, so the actual object to where these refs should point to does not exist yet.

I don't see how this could be fixed, only by redefining how proxies work (decode):

A ran into this issue because I currently somehow need to convert an object from an old type to a new type. The new type however is not actually new so when I would simply redirect the types (decode "OldType" as "NewType"), I cannot distinguish between data from "OldType Version=X" and "NewType, Version=X".

(Since I actually do not have refs to the parent object that I want to convert with a proxy, we could simply store the objRef index and overwrite it after Proxy2ObjectFun is invoked.)

The next thing I tried to is register Converters, starting with "Aardvark.Base.Coder.TypeInfoVersion.Add", but I did not manage to register them property yet. When I look at the code here: https://github.com/aardvark-platform/aardvark.base/blob/4eb7b4728c79eeec641146a6807820632a38ae8c/src/Aardvark.Base.IO/BinaryReadingCoder.cs#L192 newTypeInfo would always be the TypeInfo that was retrieved using the coded type name (OldType). The Name used here: https://github.com/aardvark-platform/aardvark.base/blob/4eb7b4728c79eeec641146a6807820632a38ae8c/src/Aardvark.Base.IO/BinaryReadingCoder.cs#L290 is then the OldType but should actually be NewType. Since Name actually a string, I maybe can somehow create such a custom type info... Then I "only" need to register the converter properly, TypeInfoVersion.Add does not do this (does not run into the proper cases), or I just have not figured out how.

Does anyone still have Converters around? Any help is appreciated!

luithefirst commented 2 years ago

I somehow managed to use the convertes, but they (of course) have the same issue as proxies with references. In order to solve this for now (me), I have implemented that the references are replaced after proxy or converter conversions. So they can be used as long as references to converted objects are not coded in their sub-objects.