Example #1
0
        internal void Begin([NotNull] AttractorModel attractor)
        {
            if (attractor == null)
            {
                throw new ArgumentNullException(nameof(attractor));
            }

            Statistics.Reset(attractor);
            PerformanceCounter.Reset();
            _stopwatch.Reset();

            lock (_randomLock)
            {
                _random = new Random((int)DateTime.Now.Ticks);
            }

            if (!Equals(attractor, _attractor))
            {
                _attractor  = attractor;
                _transforms = attractor.Transforms.ToArray();
                _colors     = attractor.ColorMap.Render(1024);
                _selector   = new TransformSelector(_transforms);
            }

            _onBeginning?.Invoke();

            PerformanceCounter.Start();
            _stopwatch.Start();
        }
        internal void Reset([NotNull] AttractorModel attractor)
        {
            if (!IsEnabled)
            {
                return;
            }

            lock (_stLock)
            {
                _hitCounters = new int[attractor.Transforms.Count];
                _min         = new Vertex(double.NaN, double.NaN);
                _max         = new Vertex(double.NaN, double.NaN);
            }
        }
Example #3
0
        public void Iterate([NotNull] AttractorModel attractor, double density, CancellationToken cancellationToken = default)
        {
            if (attractor == null)
            {
                throw new ArgumentNullException(nameof(attractor));
            }

            if (density <= 0 || cancellationToken.IsCancellationRequested)
            {
                return;
            }

            var batchSize = mBatchSize;
            var totalSize = (long)Math.Ceiling(_context.BackBuffer.BufferSize * density);

            _configuration?.Invoke(_context);

            var batchCount = (int)Math.Ceiling((double)totalSize / batchSize);
            var threads    = Enumerable.Range(0, batchCount).Select(x => new IterationThread(_context)).ToArray();

            using (new Scope(() => _context.Begin(attractor), () => _context.End(threads.Length, density)).Enter())
            {
                var parallelOptions = new ParallelOptions();

                if (!AllowMultithreading)
                {
                    parallelOptions.MaxDegreeOfParallelism = 1;
                    batchSize = (long)Math.Ceiling(_context.BackBuffer.BufferSize * density);
                }

                if (cancellationToken.IsCancellationRequested)
                {
                    return;
                }

                Parallel.ForEach(threads, parallelOptions, thread => ProcessBatch(thread, batchSize, cancellationToken));
            }

            if (cancellationToken.IsCancellationRequested)
            {
                return;
            }

            using (_context.PerformanceCounter.EnterMeasureScope("Bitmap processing"))
            {
                _context.BackBuffer.ProcessImage(this, _context, cancellationToken);
            }
        }
Example #4
0
 public void Iterate([NotNull] AttractorModel attractor, CancellationToken cancellationToken = default) => Iterate(attractor, 1, cancellationToken);
Example #5
0
        protected override IResult Execute(CancellationToken cancellationToken)
        {
            if (string.IsNullOrWhiteSpace(FormulaFile))
            {
                WriteHelp();
                return(Result.Success);
            }

            Log.Write("Preparing...");

            var formulaFileName = Path.GetFileName(FormulaFile);
            var directory       = new FileSystemStore(Path.GetDirectoryName(FormulaFile) ?? throw new FileNotFoundException("Unable to access formula file", FormulaFile));

            var size = Resolution <= 0 ? 512 : Resolution;

            using (var backBuffer = new BackBuffer(size, size))
            {
                using var bitmap      = new Bitmap(backBuffer.Width, backBuffer.Height, PixelFormat.Format32bppArgb);
                using var diagnostics = new DiagnosticsWindow();
                using var preview     = new PreviewControl(backBuffer, bitmap);

                var formula  = AttractorModel.FromJson(directory.Open(formulaFileName).AsText());
                var iterator = new Iterator(backBuffer).Configure(config => config
                                                                  .Statistics(s => s.SetEnabled(Trace))
                                                                  .PerformanceCounter(s => s.SetEnabled(Trace))
                                                                  .OnFinalize(WriteHeader)
                                                                  .Log(Log));

                iterator.AllowMultithreading = !ForceSingleThreading;

                var n = 0;

                using (var bitmapG = Graphics.FromImage(bitmap))
                {
                    bitmapG.FillRectangle(Brushes.Black, 0, 0, bitmap.Width, bitmap.Height);
                }

                preview.SampleCallback = (sample, stats) =>
                {
                    diagnostics.Invoke(new Action(
                                           () =>
                    {
                        diagnostics.brightness.Series[0].Points.AddXY(iterator.GetCurrentDensity(), stats.AverageBrightness);
                        diagnostics.peakPoint.Series[0].Points.AddXY(iterator.GetCurrentDensity(), stats.HighAccumulator);
                        diagnostics.peakPoint.Series[1].Points.AddXY(iterator.GetCurrentDensity(), stats.LowAccumulator);
                    }));
                };

                preview.RenderCallback = () =>
                {
                    var cd        = iterator.GetCurrentDensity();
                    var increment = cd < 10 ? 1 : GetDensity(++n) / 10.0;
                    // ReSharper disable once MethodSupportsCancellation
                    iterator.Iterate(formula, increment);
                    _totalDensity = iterator.GetCurrentDensity();
                };

                preview.Dock = DockStyle.Fill;
                diagnostics.histogramPanel.Controls.Add(preview);

                var thread = new Thread(() => preview.RenderLoop(() => !preview.Visible))
                {
                    IsBackground = true
                };

                diagnostics.Shown += (o, e) => thread.Start();
                diagnostics.ShowDialog();
            }

            return(Result.Success);
        }