public UsdTypeBinding(ToVtConverter toVtConverter,
                       ToCsConverter toCsConverter,
                       pxr.SdfValueTypeName sdfName)
 {
     toVtValue   = toVtConverter;
     toCsObject  = toCsConverter;
     sdfTypeName = sdfName;
 }
Ejemplo n.º 2
0
        /// <summary>
        /// Binds the specified C# type to the given USD array and scene description (Sdf) types,
        /// looking for ConverterT.ToVtArray(csType) and ConverterT.FromVtArray(vtArrayType).
        /// </summary>
        ///
        /// <typeparam name="ConverterT">
        /// The C# class type providing type conversion rules ToVtArray and FromVtArray.
        /// </typeparam>
        ///
        /// <param name="csType">The C# type to be mapped to USD</param>
        /// <param name="vtArrayType">The USD C++ value type (Vt)</param>
        /// <param name="sdfName">The USD scene description (Sdf) type</param>
        ///
        /// TODO: The C++ type can be inferred from the Sdf type, so vtArrayType is not needed.
        ///
        public void BindArrayType <ConverterT>(Type csType,
                                               Type vtArrayType,
                                               pxr.SdfValueTypeName sdfName,
                                               string methodNamePrefix = "")
        {
            var csToVtArray = typeof(ConverterT)
                              .GetMethod(methodNamePrefix + "ToVtArray", new Type[] { csType });

            if (csToVtArray == null)
            {
                throw new ArgumentException(string.Format("No ToVtArray overload found for type {0}",
                                                          csType.ToString()));
            }

            var vtToCsArray = typeof(ConverterT)
                              .GetMethod(methodNamePrefix + "FromVtArray", new Type[] { vtArrayType });

            if (vtToCsArray == null)
            {
                throw new ArgumentException(string.Format("No FromVtArray overload found for type {0}",
                                                          vtArrayType.ToString()));
            }

            var valToVtArray = typeof(pxr.UsdCs).GetMethod("VtValueTo" + vtArrayType.Name,
                                                           new Type[] { typeof(pxr.VtValue), vtArrayType });

            if (valToVtArray == null)
            {
                throw new ArgumentException(string.Format("No VtValueTo{...} converter found for type {0}",
                                                          vtArrayType.ToString()));
            }

            var           copyConverter = (ToCsCopyConverter)CodeGen.EmitToCs <ToCsCopyConverter>(valToVtArray, vtToCsArray);
            ToCsConverter toCs          = (vtValue) => ToCsConvertHelper(vtValue, vtArrayType, copyConverter);
            ToVtConverter toVt          =
                (ToVtConverter)CodeGen.EmitToVt <ToVtConverter>(csToVtArray, csType, vtArrayType);

            bindings[csType] = new UsdTypeBinding(toVt, toCs, sdfName);
        }
        /// <summary>
        /// Binds the specified C# type to the given USD array and scene description (Sdf) types,
        /// looking for ConverterT.ToVtArray(csType) and ConverterT.FromVtArray(vtArrayType).
        /// </summary>
        ///
        /// <typeparam name="ConverterT">
        /// The C# class type providing type conversion rules ToVtArray and FromVtArray.
        /// </typeparam>
        ///
        /// <param name="csType">The C# type to be mapped to USD</param>
        /// <param name="vtArrayType">The USD C++ value type (Vt)</param>
        /// <param name="sdfName">The USD scene description (Sdf) type</param>
        ///
        /// TODO: The C++ type can be inferred from the Sdf type, so vtArrayType is not needed.
        ///
        public void BindArrayType <ConverterT>(Type csType,
                                               Type vtArrayType,
                                               pxr.SdfValueTypeName sdfName,
                                               string methodNamePrefix = "")
        {
            // ConverterT and the function being found will be something like:
            //   class IntrinsicTypeConverter {
            //     static public VtTokenArray ToVtArray(string[] input);
            //
            var csToVtArray = typeof(ConverterT)
                              .GetMethod(methodNamePrefix + "ToVtArray", new Type[] { csType });

            if (csToVtArray == null)
            {
                throw new ArgumentException(string.Format("No ToVtArray overload found for type {0}",
                                                          csType.ToString()));
            }

            // ConverterT and the function being found will be something like:
            //   class IntrinsicTypeConverter {
            //     static public string[] FromVtArray(VtTokenArray input);
            //
            var vtToCsArray = typeof(ConverterT)
                              .GetMethod(methodNamePrefix + "FromVtArray", new Type[] { vtArrayType });

            if (vtToCsArray == null)
            {
                throw new ArgumentException(string.Format("No FromVtArray overload found for type {0}",
                                                          vtArrayType.ToString()));
            }

            // The specific UsdCs method being located here will be somthing like:
            //   class UsdCs {
            //     public static void VtValueToVtTokenArray(VtValue value, VtTokenArray output);
            //
            var valToVtArray = typeof(pxr.UsdCs).GetMethod("VtValueTo" + vtArrayType.Name,
                                                           new Type[] { typeof(pxr.VtValue), vtArrayType });

            if (valToVtArray == null)
            {
                throw new ArgumentException(string.Format("No VtValueTo{...} converter found for type {0}",
                                                          vtArrayType.ToString()));
            }

            // The following code constructs functions to:
            //
            //   1) Convert the VtValue (type-erased container) to a specific VtArray<T> type and then
            //      convert the VtArray<T> to a native C# type.
            //
            //   2) Convert a strongly typed C# array to a strongly typed VtArray<T> and then
            //      convert the VtArray<T> to a type-erased VtValue.
            //
            // For example, to will convert:
            //
            //   1) VtValue -> VtArray<TfToken> -> string[]
            //   2) string[] -> VtArray<TfToken> -> VtValue
            //

            ToCsConverter toCs = null;
            ToVtConverter toVt = null;


            if (IsCodeGenEnabled())
            {
                // EmitToCs and EmitToVt are not defined when not using NET_4_6
#if NET_4_6
                var copyConverter = (ToCsCopyConverter)CodeGen.EmitToCs <ToCsCopyConverter>(valToVtArray, vtToCsArray);
                toCs = (vtValue) => ToCsConvertHelper(vtValue, vtArrayType, copyConverter);
                toVt = (ToVtConverter)CodeGen.EmitToVt <ToVtConverter>(csToVtArray, csType, vtArrayType);
#endif
            }
            else
            {
                // In .NET2 or when IL2CPP is enabled , we cannot dynamically emit code.
                // Instead, we use late binding, which is slower, but also doesn't crash.
                // In the future, we should generate code to do these conversions, rather than using late binding.
                toCs = (vtValue) => ToCsDynamicConvertHelper(vtValue, vtArrayType, valToVtArray, vtToCsArray);
                toVt = CsArrayToVtValue(csToVtArray, csType, vtArrayType);
            }

            bindings[csType] = new UsdTypeBinding(toVt, toCs, sdfName);
        }