Exemple #1
0
        static Reflector()
        {
            foreach (var type in
                     //This is more correct but way slower
                     //AppDomain.CurrentDomain.GetAssemblies()
                     //.Where(a => !a.IsDynamic)
                     //.Where(a => a.GetCustomAttributes(false).Any(c => c is ReflectAttribute))
                     ReflectableAssemblies
                     .SelectMany(a => a.GetTypes()))
            {
                foreach (var ca in type.GetCustomAttributes())
                {
                    if (ca is ReflectAttribute ra)
                    {
                        ReflectionData.RecordPublic(type, ra.returnType);
                        break;
                    }
                }
            }

            InitializeEnumResolvers();
            AllowMath <TEx <float> >();
            AllowMath <TEx <bool> >(); //This will also allow stuff like (if + true false), which will error if you actually use it
            AllowMath <TEx <Vector2> >();
            AllowMath <TEx <Vector3> >();
            AllowMath <TEx <Vector4> >();
            AllowMath <TEx <V2RV2> >();

            void CreatePostAggregates(string method, string shortcut)
            {
                var mi = typeof(ExPostAggregators).GetMethod(method) ??
                         throw new Exception($"Couldn't find post-aggregator \"{method}\"");
                var attrs    = Attribute.GetCustomAttributes(mi);
                var priority = 999;

                Type[]? types = null;
                foreach (var attr in attrs)
                {
                    if (attr is PAPriorityAttribute pp)
                    {
                        priority = pp.priority;
                    }
                    else if (attr is PASourceTypesAttribute ps)
                    {
                        types = ps.types;
                    }
                }
                void CreateAggregateMethod(MethodInfo gmi)
                {
                    var prms = gmi.GetParameters();

                    if (prms.Length != 2)
                    {
                        throw new Exception($"Post-aggregator \"{method}\" doesn't have 2 arguments");
                    }
                    var sourceType = prms[0].ParameterType;
                    var searchType = prms[1].ParameterType;

                    if (gmi.ReturnType != sourceType)
                    {
                        throw new Exception($"Post-aggregator \"{method}\" has a different return and first argument type");
                    }
                    postAggregators.SetDefaultSet(sourceType, shortcut,
                                                  new PostAggregate(priority, sourceType, searchType, gmi));
                }

                if (types == null)
                {
                    CreateAggregateMethod(mi);
                }
                else
                {
                    //types = [ (float), (v2) ... ]
                    foreach (var rt in types)
                    {
                        CreateAggregateMethod(mi.MakeGenericMethod(rt));
                    }
                }
            }

            CreatePostAggregates("PA_Add", "+");
            CreatePostAggregates("PA_Mul", "*");
            CreatePostAggregates("PA_Sub", "-");
            CreatePostAggregates("PA_Div", "/");
            CreatePostAggregates("PA_FDiv", "//");
            CreatePostAggregates("PA_Pow", "^");
            CreatePostAggregates("PA_And", "&");
            CreatePostAggregates("PA_Or", "|");
            void CreatePreAggregates(string method, string shortcut)
            {
                var mi = typeof(ExPreAggregators).GetMethod(method) ??
                         throw new Exception($"Couldn't find post-aggregator \"{method}\"");
                var attrs    = Attribute.GetCustomAttributes(mi);
                var priority = 999;
                var types    = new Type[0];

                foreach (var attr in attrs)
                {
                    if (attr is PAPriorityAttribute pp)
                    {
                        priority = pp.priority;
                    }
                    else if (attr is PASourceTypesAttribute ps)
                    {
                        types = ps.types;
                    }
                }
                //types = [ (float), (v2) ... ]
                foreach (var rt in types)
                {
                    var gmi  = mi.MakeGenericMethod(rt);
                    var prms = gmi.GetParameters();
                    if (prms.Length != 2)
                    {
                        throw new Exception($"Pre-aggregator \"{method}\" doesn't have 2 arguments");
                    }
                    var resultType  = gmi.ReturnType;
                    var searchType1 = prms[0].ParameterType;
                    var searchType2 = prms[1].ParameterType;
                    if (preAggregators.TryGetValue(resultType, out var res))
                    {
                        if (res.firstType != searchType1)
                        {
                            throw new Exception(
                                      $"Pre-aggregators currently support only one reducer type, " +
                                      $"but return type {resultType.RName()} is associated with " +
                                      $"{res.firstType.RName()} and {searchType1.RName()}.");
                        }
                    }
                    else
                    {
                        res = new PreAggregate(searchType1);
                    }
                    res.AddResolver(new PreAggregateResolver(shortcut, searchType2, gmi, priority));
                    preAggregators[resultType] = res;
                }
            }

            CreatePreAggregates("PA_Mul", "*");
            CreatePreAggregates("PA_GT", ">");
            CreatePreAggregates("PA_LT", "<");
            CreatePreAggregates("PA_GEQ", ">=");
            CreatePreAggregates("PA_LEQ", "<=");
            CreatePreAggregates("PA_EQ", "=");
            CreatePreAggregates("PA_NEQ", "=/=");
            foreach (var key in preAggregators.Keys.ToArray())
            {
                var res = preAggregators[key];
                res.SortResolvers();
                preAggregators[key] = res;
            }
        }