chr
2026-04-05 fe750b791d5b517cc4e9bc8e99a9a75139a0cfba
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
using System;
using System.Xml.Linq;
 
namespace OpenTap.Plugins
{
    class MixinSerializer : TapSerializerPlugin
    {
        static readonly XName rootElemName = "OpenTap.Mixins";
        private static readonly XName mixinElemName = "Mixin";
        
        public override double Order => 1.1;
        
        public override bool Deserialize(XElement node, ITypeData t, Action<object> setter)
        {
            var rootElem = node.Element(rootElemName);
            if (rootElem != null)
            {
                var elements = rootElem.Elements();
                void setter2(object targetObject)
                {
                    foreach (var elem in elements)
                    {
                        Serializer.Deserialize(elem, mixin =>
                        {
                            var mixin2 = (IMixinBuilder) mixin;
                            MixinFactory.LoadMixin(targetObject, mixin2);
 
                        }, TypeData.FromType(typeof(IMixinBuilder)));
                    }
                    setter(targetObject);
                }
                rootElem.Remove();
                return Serializer.Deserialize(node,  setter2, t);
            }
            return false;
        }
 
        public override bool Serialize(XElement node, object obj, ITypeData expectedType)
        {
            if (obj == null) return false;
            var dynamicMembers = DynamicMember.GetDynamicMembers(obj);
            XElement mixins = null;
            foreach (var dynamicMember in dynamicMembers)
            {
                if (dynamicMember is MixinMemberData mixin)
                {
                    if (mixins == null)
                    {
                        mixins = node.Element(rootElemName);
                        if (mixins == null)
                        {
                            mixins = new XElement(rootElemName);
                            node.Add(mixins);
                        }
                    }
                    
                    var encodedName =Serializer.PropertyXmlName(dynamicMember.Name); 
                    var currentElement = mixins.Element(encodedName);
                    // in some rare case this already happened once. This happens because we return false below.
                    // In this case it is safe to ignore it and continue.
                    if (currentElement == null)
                    {
                        XElement elem = new XElement(encodedName);
                        mixins.Add(elem);
                        Serializer.Serialize(elem, mixin.Source);
                    }
                }
            }
 
            // the mixin members has been serialized now, but
            // continue serializing as before. 
            return false;
        }
    }
}