Exemple #1
0
            public void Dispose()
            {
                switch (operation)
                {
                case Operation.Loading:
                    FARLogger.Debug("ConfigAdapter finished loading");
                    FARConfig.IsLoading = false;
                    Instance.loading    = false;
                    break;

                case Operation.Saving:
                    FARLogger.Debug("ConfigAdapter finished saving");
                    Instance.saving = false;
                    break;

                case Operation.None:
                    FARLogger.Debug("ConfigAdapter finished task");
                    break;

                default:
                    throw new ArgumentOutOfRangeException(nameof(operation), operation, null);
                }

                Instance.Completed = !(Instance.saving || Instance.loading);
            }
            public IEnumerator LoadAsync()
            {
                FARLogger.Debug(string.Format("Loading asset bundle {0}", BundlePath));
                var createRequest = AssetBundle.LoadFromFileAsync(BundlePath);

                yield return(createRequest);

                assetBundle = createRequest.assetBundle;
                if (assetBundle == null)
                {
                    FARLogger.Error(string.Format("Could not load asset bundle from {0}", BundlePath));
                    yield break;
                }

                var loadRequest = assetBundle.LoadAllAssetsAsync(typeof(T));

                yield return(loadRequest);

                foreach (var asset in loadRequest.allAssets)
                {
                    FARLogger.Debug(string.Format("Adding {0} to dictionary", asset));
                    Add(asset.name, (T)asset);
                }

                FARLogger.Debug(string.Format("Finished loading {0} assets from {1}", typeof(T), BundlePath));
                AssetsLoaded = true;

                OnLoad();
            }
Exemple #3
0
        private IEnumerator DoLoad(Action callback)
        {
            // offload to another thread and wait for it to complete
            Task task = Task.Factory.StartNew(InitTask);

            yield return(new WaitUntil(() => task.IsCompleted));

            if (task.Exception != null)
            {
                FARLogger.Exception(task.Exception, "Exception while loading FAR addons:");
                yield break;
            }

            // do instantiation in the main thread in case any of the types are Unity objects
            FARLogger.Debug("Instantiating FAR addons");
            foreach (Pair <FARAddonAttribute, Type> pair in AddonTypes)
            {
                yield return(SetupType(pair.Second, pair.First.Persistant, AddonObjects));

                yield return(null);
            }

            FARLogger.Debug("Instantiating Reloadable types");
            foreach (Type type in ReloadableTypes)
            {
                yield return(SetupType(type, true, ReloadableObjects));

                yield return(null);
            }

            callback?.Invoke();
        }
            public IEnumerator LoadAsync()
            {
                FARLogger.Debug($"Loading asset bundle {BundlePath}");
                AssetBundleCreateRequest createRequest = AssetBundle.LoadFromFileAsync(BundlePath);

                yield return(createRequest);

                assetBundle = createRequest.assetBundle;
                if (assetBundle == null)
                {
                    FARLogger.Error($"Could not load asset bundle from {BundlePath}");
                    yield break;
                }

                AssetBundleRequest loadRequest = assetBundle.LoadAllAssetsAsync(typeof(T));

                yield return(loadRequest);

                foreach (Object asset in loadRequest.allAssets)
                {
                    FARLogger.Debug($"Adding {asset} to dictionary");
                    Add(asset.name, (T)asset);
                }

                FARLogger.Debug($"Finished loading {typeof(T)} assets from {BundlePath}");
                AssetsLoaded = true;

                OnLoad();
            }
Exemple #5
0
        public IEnumerator Reload()
        {
            FARLogger.Debug("Reloading IReloadable objects");

            // sort again in case priorities have changed
            ReloadableObjects.Sort((x, y) => y.Priority.CompareTo(x.Priority));

            foreach (IReloadable reloadable in ReloadableObjects)
            {
                reloadable.Completed = false;
                reloadable.DoReload();
                yield return(new WaitUntil(() => reloadable.Completed));
            }
        }
Exemple #6
0
        private void Awake()
        {
            if (instance == null)
            {
                FARLogger.Debug($"MonoSingleton {this} is awake");
                instance = this as T;
                OnAwake();
            }

            else
            {
                FARLogger.Trace($"{this} is a MonoSingleton but an instance already exists, destroying self");
                destroyingDuplicate = true;
                Destroy(this);
            }
        }
Exemple #7
0
            // cannot override default ctor...
            public LoadGuard(Operation op)
            {
                operation = op;
                switch (op)
                {
                case Operation.Loading:
                    FARLogger.Debug("ConfigAdapter started loading");
                    FARConfig.IsLoading = true;
                    Instance.loading    = true;
                    break;

                case Operation.Saving:
                    FARLogger.Debug("ConfigAdapter started saving");
                    Instance.saving = true;
                    break;

                case Operation.None:
                    FARLogger.Debug("ConfigAdapter started task");
                    break;

                default:
                    throw new ArgumentOutOfRangeException(nameof(op), op, null);
                }
            }
        /// <summary>
        ///     C# implementation of
        ///     https://github.com/scipy/scipy/blob/d5617d81064885ef2ec961492bc703f36bb36ee9/scipy/optimize/zeros.py#L95-L363
        ///     with optional <see cref="minLimit" /> and <see cref="maxLimit" /> constraints for physical problems. The solver
        ///     terminates when it either reaches the maximum number of iterations <see cref="maxIter" />, current and previous
        ///     <see cref="function" /> values are equal, current and previous solutions are close enough, are both NaN  or both
        ///     fall outside limits.
        /// </summary>
        /// <param name="function">Function to find root of</param>
        /// <param name="x0">Initial guess</param>
        /// <param name="x1">Optional second guess</param>
        /// <param name="tol">Absolute convergence tolerance</param>
        /// <param name="rTol">Relative convergence tolerance</param>
        /// <param name="maxIter">Maximum number of iterations</param>
        /// <param name="maxLimit">Maximum value of the solution</param>
        /// <param name="minLimit">Minimum value of the solution</param>
        /// <returns><see cref="OptimizationResult" /> solution</returns>
        /// <exception cref="ArgumentException">When initial and second guesses are equal</exception>
        public static OptimizationResult Secant(
            Func <double, double> function,
            double x0,
            double?x1       = null,
            double tol      = 0.001,
            double rTol     = 0.001,
            int maxIter     = 50,
            double maxLimit = double.PositiveInfinity,
            double minLimit = double.NegativeInfinity
            )
        {
            // ReSharper disable CompareOfFloatsByEqualityOperator
            int    funcCalls = 0;
            double p0        = x0;
            double p1;

            if (x1 is null)
            {
                const double eps = 1e-4;
                p1  = x0 * (1 + eps);
                p1 += p1 >= 0 ? eps : -eps;
            }
            else
            {
                if (x1 == x0)
                {
                    throw new ArgumentException($"{nameof(x1)} and {nameof(x0)} must be different");
                }
                p1 = (double)x1;
            }

            double q0 = function(p0);
            double q1 = function(p1);

            funcCalls += 2;
            double p = 0;

            if (Math.Abs(q1) < Math.Abs(q0))
            {
                Swap(ref p0, ref p1);
                Swap(ref q0, ref q1);
            }

            for (int itr = 0; itr < maxIter; itr++)
            {
                if (q1 == q0)
                {
                    if (p1 != p0)
                    {
                        FARLogger.Warning($"Tolerance of {(p1 - p0).ToString(CultureInfo.InvariantCulture)} reached");
                    }
                    FARLogger.Debug($"Secant method converged in {funcCalls.ToString()} function calls");
                    return(new OptimizationResult((p1 + p0) / 2, funcCalls, true));
                }

                if (Math.Abs(q1) > Math.Abs(q0))
                {
                    p = (-q0 / q1 * p1 + p0) / (1 - q0 / q1);
                }
                else
                {
                    p = (-q1 / q0 * p0 + p1) / (1 - q1 / q0);
                }

                if (IsClose(p, p1, tol, rTol))
                {
                    FARLogger.Debug($"Secant method converged in {funcCalls.ToString()} function calls with tolerance of {(p1 - p).ToString(CultureInfo.InvariantCulture)}");
                    return(new OptimizationResult(p, funcCalls, true));
                }

                p0 = p1;
                q0 = q1;
                p1 = p;

                if (double.IsNaN(p0) && double.IsNaN(p1))
                {
                    FARLogger.Warning($"Both {nameof(p0)} and {nameof(p1)} are NaN, used {funcCalls.ToString()} function calls");
                    return(new OptimizationResult(p, funcCalls));
                }

                if (p1 < minLimit && p0 < minLimit || p1 > maxLimit && p0 > maxLimit)
                {
                    FARLogger.Warning($"{nameof(p1)} and {nameof(p0)} are outside the limits, used {funcCalls.ToString()} function calls");
                    return(new OptimizationResult(p, funcCalls));
                }

                q1 = function(p1);
                funcCalls++;
            }

            FARLogger.Warning($"Secant method failed to converge in {funcCalls.ToString()} function calls");
            return(new OptimizationResult(p, funcCalls));
            // ReSharper restore CompareOfFloatsByEqualityOperator
        }
        // ReSharper disable once UnusedMember.Global
        public static OptimizationResult BrentsMethod(
            Func <double, double> function,
            double a,
            double b,
            double epsilon = 0.001,
            int maxIter    = int.MaxValue
            )
        {
            double delta = epsilon * 100;
            double fa    = function(a);
            double fb    = function(b);

            if (fa * fb >= 0)
            {
                FARLogger.Debug("Brent's method failed to converge in 2 calls due to invalid brackets");
                return(new OptimizationResult(0, 2));
            }

            if (Math.Abs(fa) < Math.Abs(fb))
            {
                double tmp = fa;
                fa = fb;
                fb = tmp;

                tmp = a;
                a   = b;
                b   = tmp;
            }

            double c = a, d = a, fc = function(c);
            int    funcCalls = 3;

            double s = b;

            bool flag = true;

            for (int iter = 0; iter < maxIter; iter++)
            {
                if (fa - fc > double.Epsilon && fb - fc > double.Epsilon) //inverse quadratic interpolation
                {
                    s  = a * fc * fb / ((fa - fb) * (fa - fc));
                    s += b * fc * fa / ((fb - fa) * (fb - fc));
                    s += c * fc * fb / ((fc - fa) * (fc - fb));
                }
                else
                {
                    s  = (b - a) / (fb - fa); //secant method
                    s *= fb;
                    s  = b - s;
                }

                double b_s = Math.Abs(b - s), b_c = Math.Abs(b - c), c_d = Math.Abs(c - d);

                //Conditions for bisection method
                bool   condition1;
                double a3pb_over4 = (3 * a + b) * 0.25;

                if (a3pb_over4 > b)
                {
                    if (s < a3pb_over4 && s > b)
                    {
                        condition1 = false;
                    }
                    else
                    {
                        condition1 = true;
                    }
                }
                else if (s > a3pb_over4 && s < b)
                {
                    condition1 = false;
                }
                else
                {
                    condition1 = true;
                }

                bool condition2;

                if (flag && b_s >= b_c * 0.5)
                {
                    condition2 = true;
                }
                else
                {
                    condition2 = false;
                }

                bool condition3;

                if (!flag && b_s >= c_d * 0.5)
                {
                    condition3 = true;
                }
                else
                {
                    condition3 = false;
                }

                bool condition4;

                if (flag && b_c <= delta)
                {
                    condition4 = true;
                }
                else
                {
                    condition4 = false;
                }

                bool condition5;

                if (!flag && c_d <= delta)
                {
                    condition5 = true;
                }
                else
                {
                    condition5 = false;
                }

                if (condition1 || condition2 || condition3 || condition4 || condition5)
                {
                    s    = a + b;
                    s   *= 0.5;
                    flag = true;
                }
                else
                {
                    flag = false;
                }

                double fs = function(s);
                funcCalls++;
                d = c;
                c = b;

                if (fa * fs < 0)
                {
                    b  = s;
                    fb = fs;
                }
                else
                {
                    a  = s;
                    fa = fs;
                }

                if (Math.Abs(fa) < Math.Abs(fb))
                {
                    double tmp = fa;
                    fa = fb;
                    fb = tmp;

                    tmp = a;
                    a   = b;
                    b   = tmp;
                }

                if (fs.NearlyEqual(0) || Math.Abs(a - b) <= epsilon)
                {
                    return(new OptimizationResult(s, funcCalls, true));
                }
            }

            FARLogger.Debug($"Brent's method failed to converged in {funcCalls.ToString()} function calls");

            return(new OptimizationResult(s, funcCalls));
        }