static KeyframeFormatter() { Is_In_2018_1_Or_Above = typeof(Keyframe).GetProperty("weightedMode") != null; if (Is_In_2018_1_Or_Above) { if (EmitUtilities.CanEmit) { Formatter = (IFormatter <Keyframe>)FormatterEmitter.GetEmittedFormatter(typeof(Keyframe), SerializationPolicies.Everything); } else { Formatter = new ReflectionFormatter <Keyframe>(SerializationPolicies.Everything); } } }
private static IFormatter CreateFormatter(Type type, ISerializationPolicy policy) { if (FormatterUtilities.IsPrimitiveType(type)) { throw new ArgumentException("Cannot create formatters for a primitive type like " + type.Name); } // First call formatter locators before checking for registered formatters for (int i = 0; i < FormatterLocators.Count; i++) { try { IFormatter result; if (FormatterLocators[i].LocatorInstance.TryGetFormatter(type, FormatterLocationStep.BeforeRegisteredFormatters, policy, out result)) { return(result); } } catch (TargetInvocationException ex) { throw ex; } catch (TypeInitializationException ex) { throw ex; } #pragma warning disable CS0618 // Type or member is obsolete catch (ExecutionEngineException ex) #pragma warning restore CS0618 // Type or member is obsolete { throw ex; } catch (Exception ex) { Debug.LogException(new Exception("Exception was thrown while calling FormatterLocator " + FormatterLocators[i].GetType().FullName + ".", ex)); } } // Then check for valid registered formatters for (int i = 0; i < FormatterInfos.Count; i++) { var info = FormatterInfos[i]; Type formatterType = null; if (type == info.TargetType) { formatterType = info.FormatterType; } else if (info.FormatterType.IsGenericType && info.TargetType.IsGenericParameter) { Type[] inferredArgs; if (info.FormatterType.TryInferGenericParameters(out inferredArgs, type)) { formatterType = info.FormatterType.GetGenericTypeDefinition().MakeGenericType(inferredArgs); } } else if (type.IsGenericType && info.FormatterType.IsGenericType && info.TargetType.IsGenericType && type.GetGenericTypeDefinition() == info.TargetType.GetGenericTypeDefinition()) { Type[] args = type.GetGenericArguments(); if (info.FormatterType.AreGenericConstraintsSatisfiedBy(args)) { formatterType = info.FormatterType.GetGenericTypeDefinition().MakeGenericType(args); } } if (formatterType != null) { var instance = GetFormatterInstance(formatterType); if (instance == null) { continue; } if (info.AskIfCanFormatTypes && !((IAskIfCanFormatTypes)instance).CanFormatType(type)) { continue; } return(instance); } } // Then call formatter locators after checking for registered formatters for (int i = 0; i < FormatterLocators.Count; i++) { try { IFormatter result; if (FormatterLocators[i].LocatorInstance.TryGetFormatter(type, FormatterLocationStep.AfterRegisteredFormatters, policy, out result)) { return(result); } } catch (TargetInvocationException ex) { throw ex; } catch (TypeInitializationException ex) { throw ex; } #pragma warning disable CS0618 // Type or member is obsolete catch (ExecutionEngineException ex) #pragma warning restore CS0618 // Type or member is obsolete { throw ex; } catch (Exception ex) { Debug.LogException(new Exception("Exception was thrown while calling FormatterLocator " + FormatterLocators[i].GetType().FullName + ".", ex)); } } // If we can, emit a formatter to handle serialization of this object { if (EmitUtilities.CanEmit) { var result = FormatterEmitter.GetEmittedFormatter(type, policy); if (result != null) { return(result); } } } if (EmitUtilities.CanEmit) { Debug.LogWarning("Fallback to reflection for type " + type.Name + " when emit is possible on this platform."); } // Finally, we fall back to a reflection-based formatter if nothing else has been found return((IFormatter)Activator.CreateInstance(typeof(ReflectionFormatter <>).MakeGenericType(type))); }