Example #1
0
        /// <summary>
        /// Called whenever a new environment has been received.
        /// </summary>
        /// <param name="ar">The results of the aysnchronous operation.</param>
        /// <remarks>
        /// Byte Array to Structure code taken from @cite stackOverflowByte (http://stackoverflow.com/questions/3278827/how-to-convert-structure-to-byte-array-in-c)
        /// </remarks>
        private void EnvironmentReceived(IAsyncResult ar)
        {
            var environment = new StatusReport();
            var size        = Marshal.SizeOf(environment);

            if (disposed)
            {
                return;
            }

            pipeServer.EndWaitForConnection(ar);

            var bytes = new List <byte>();

            var buffer = new byte[size];

            pipeServer.Read(buffer, 0, size);

            bytes.AddRange(buffer);

            var array = bytes.ToArray();

            var ptr = Marshal.AllocHGlobal(size);

            Marshal.Copy(array, 0, ptr, size);

            lock (latestEnvironmentLocker)
            {
                var report = (StatusReport)Marshal.PtrToStructure(ptr, typeof(StatusReport));
                latestEnvironment  = report.Environment;
                CurrentVector      = report.FieldVector;
                fieldType          = report.FieldType;
                latestBallVelocity = report.BallVelocity;
            }

            if (!worker.IsBusy)
            {
                worker.RunWorkerAsync();
            }

            Marshal.FreeHGlobal(ptr);
            pipeServer.Disconnect();
            pipeServer.BeginWaitForConnection(EnvironmentReceived, null);
        }
Example #2
0
        /// <summary>
        /// Renders the image based on the <see cref="latestEnvironment"/>.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="doWorkEventArgs">The <see cref="System.ComponentModel.DoWorkEventArgs"/> instance containing the event data.</param>
        /// <remarks>
        /// Buffers <see cref="latestEnvironment"/> into <see cref="currentEnvironment"/> before rendering, to ensure new incoming
        /// data doesn't interfere, even if it comes in while still rendering.
        /// </remarks>
        private void RenderImage(object sender, DoWorkEventArgs doWorkEventArgs)
        {
            int type;

            // Buffer the environment data
            lock (latestEnvironmentLocker)
            {
                currentEnvironment  = latestEnvironment;
                currentBallVelocity = latestBallVelocity;
                type = fieldType;
            }

            // Create the computation queue (this can't be saved and reused, not sure why)
            var queue = new ComputeCommandQueue(context, context.Devices[0], ComputeCommandQueueFlags.None);

            switch (type)
            {
            case 0:
                // Calculate the potential field
                ComputeField(queue, points);
                break;

            case 1:
                ComputeFinalApproachField(queue, points);
                break;

            case 2:
                ComputePosessionField(queue, points);
                break;
            }

            // Draw a picture of it
            var bitmap = RenderPoints(queue, points, outCl);

            // Calculate the field gradients
            ComputeGradient(queue, gradientPoints);
            // Draw a picture of them
            var bitmap2 = RenderPoints(queue, gradientPoints, outGradient);

            // Anonymous function which refreshes the images shown on the UI.  Has to be called on the UI thread to allow access
            // to the UI controls.
            Action refresh = () =>
            {
                using (var stream = new MemoryStream())
                {
                    bitmap.Save(stream, ImageFormat.Png);
                    stream.Seek(0, SeekOrigin.Begin);

                    var decoder = BitmapDecoder.Create(stream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnLoad);

                    var writeable = new WriteableBitmap(decoder.Frames.Single());
                    writeable.Freeze();

                    FieldImage.Source = writeable;
                }
                using (var stream = new MemoryStream())
                {
                    bitmap2.Save(stream, ImageFormat.Png);
                    stream.Seek(0, SeekOrigin.Begin);

                    var decoder = BitmapDecoder.Create(stream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnLoad);

                    var writeable = new WriteableBitmap(decoder.Frames.Single());
                    writeable.Freeze();

                    GradientImage.Source = writeable;
                }
            };

            Dispatcher.Invoke(refresh);

            queue.Finish();
            queue.Dispose();
        }