//----------------------------------------------------------------------- // // Copyright (c) 2018 Sirenix IVS // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // //----------------------------------------------------------------------- using VRC.Udon.Serialization.OdinSerializer; [assembly: RegisterFormatter(typeof(GradientFormatter))] namespace VRC.Udon.Serialization.OdinSerializer { using System; using System.Reflection; using UnityEngine; /// /// Custom formatter for the type. /// /// public class GradientFormatter : MinimalBaseFormatter { private static readonly Serializer AlphaKeysSerializer = Serializer.Get(); private static readonly Serializer ColorKeysSerializer = Serializer.Get(); // The Gradient.mode member of type UnityEngine.GradientMode was added in a later version of Unity // Therefore we need to handle it using reflection, as it might not be there if Odin is running in an early version private static readonly PropertyInfo ModeProperty = typeof(Gradient).GetProperty("mode", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); private static readonly Serializer EnumSerializer = ModeProperty != null ? Serializer.Get() : null; protected override Gradient GetUninitializedObject() { return new Gradient(); } /// /// Reads into the specified value using the specified reader. /// /// The value to read into. /// The reader to use. protected override void Read(ref Gradient value, IDataReader reader) { value.alphaKeys = GradientFormatter.AlphaKeysSerializer.ReadValue(reader); value.colorKeys = GradientFormatter.ColorKeysSerializer.ReadValue(reader); string name; reader.PeekEntry(out name); if (name == "mode") { try { if (ModeProperty != null) { ModeProperty.SetValue(value, EnumSerializer.ReadValue(reader), null); } else { reader.SkipEntry(); } } catch (Exception) { reader.Context.Config.DebugContext.LogWarning("Failed to read Gradient.mode, due to Unity's API disallowing setting of this member on other threads than the main thread. Gradient.mode value will have been lost."); } } } /// /// Writes from the specified value using the specified writer. /// /// The value to write from. /// The writer to use. protected override void Write(ref Gradient value, IDataWriter writer) { GradientFormatter.AlphaKeysSerializer.WriteValue(value.alphaKeys, writer); GradientFormatter.ColorKeysSerializer.WriteValue(value.colorKeys, writer); if (ModeProperty != null) { try { EnumSerializer.WriteValue("mode", ModeProperty.GetValue(value, null), writer); } catch (Exception) { writer.Context.Config.DebugContext.LogWarning("Failed to write Gradient.mode, due to Unity's API disallowing setting of this member on other threads than the main thread. Gradient.mode will have been lost upon deserialization."); } } } } }