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
using System;
using System.Collections.Generic;
using System.Linq;
 
namespace OpenTap
{
    /// <summary> Helper class for producing mixin builders. </summary>
    static class MixinFactory
    {
        /// <summary> Creates mixin builders for a type. </summary>
        public static IEnumerable<IMixinBuilder> GetMixinBuilders(ITypeData targetType)
        {
            foreach (var factoryType in TypeData.GetDerivedTypes<IMixinBuilder>())
            {
                if (factoryType.CanCreateInstance == false)
                    continue;
                var types = factoryType.GetAttribute<MixinBuilderAttribute>()?.Types ?? Array.Empty<Type>();
                if (!types.Any(targetType.DescendsTo))
                    continue;
                var instance = (IMixinBuilder)factoryType.CreateInstance();
                instance.Initialize(targetType);
                yield return instance;
            }
        }
        static readonly TraceSource log = Log.CreateSource("Mixins");
        public static MixinMemberData LoadMixin(object target, IMixinBuilder mixin)
        {
 
            try
            {
                var mem = mixin.ToDynamicMember(TypeData.GetTypeData(target));
                if (mem == null)
                {
                    if (mixin is IValidatingObject validating && validating.Error is string err && string.IsNullOrEmpty(err) == false)
                    {
                        log.Error($"Unable to load mixin: {err}");
                    }
                    else
                    {
                        log.Error($"Unable to load mixin: {TypeData.GetTypeData(mixin)?.GetDisplayAttribute()?.Name ?? mixin.ToString()}");
                    }
                    return null;
                }
                DynamicMember.AddDynamicMember(target, mem);
                mem.SetValue(target, mem.NewInstance());
                return mem;
            }
            catch (Exception e)
            {
                log.Error($"Unable to load mixin: {e.Message}");
                log.Debug(e);
            }
            return null;
        }
        
        // Unload and dispose mixin member data
        public static void UnloadMixin(object src2, MixinMemberData remMember)
        {
            var member = DynamicMember.GetDynamicMembers(src2).FirstOrDefault(x => remMember.Name == x.Name);
            //var member = TypeData.GetTypeData(src2).GetMember(remMember.Name);
            if (member == null) return;
            
            DynamicMember.RemoveDynamicMember(src2, member);
            if (member is MixinMemberData mixin)
                mixin.Dispose();
        }
    }
}