Home

AirMess Sound Visualizer

April 20, 2014

Trying out a new audio visualizer for fun 🙂

Advertisements

yield is a very useful keyword in C# that allows you to create dynamic enumerators of stuffs without having to fill in a List<T> of things you want to return first. The generated code builds a state machine that will go forward, step by step, whenever the caller calls MoveNext on the IEnumerable it gets back (usually using foreach).

        static void Main(string[] args)
        {
            var input = new[] { "A", "B", "C" };

            Console.WriteLine(String.Join("\n", Process(input)));
        }

        static IEnumerable<string> Process(IEnumerable<string> input)
        {
            if (input == null)
                throw new ArgumentNullException("input");

            foreach (var item in input)
            {
                yield return "Process " + item;
            }
        }

        // Output :
        // Process A
        // Process B
        // Process C

The second really useful thing is Parallel.ForEach. Whenever you have to process loads of independent data that are CPU hungry you can launch the process in parallel and have it scheduled for you by the .NET runtime.

        static void Main(string[] args)
        {
            var input = new[] { "A", "B", "C" };

            Stopwatch w = new Stopwatch();
            w.Start();
            Process(input);
            w.Stop();

            Console.WriteLine("{0}s ", w.Elapsed.TotalSeconds);
        }

        static void Process(IEnumerable<string> input)
        {
            if (input == null)
                throw new ArgumentNullException("input");

            Parallel.ForEach(input, item =>
                {
                    // Something long
                    Thread.Sleep(1000);
                });
        }
        
        // Output :
        // ~ 1s although we had 3 stuffs that each took 1s

What if we could write that?

        static void Main(string[] args)
        {
            var input = new[] { "A", "B", "C" };

            Stopwatch w = new Stopwatch();
            w.Start();
            var result = Process(input);
            w.Stop();

            Console.WriteLine("{0}s ", w.Elapsed.TotalSeconds);
            Console.WriteLine(String.Join("\n", result));
        }

        static IEnumerable<string> Process(IEnumerable<string> input)
        {
            if (input == null)
                throw new ArgumentNullException("input");

            Parallel.ForEach(input, item =>
                {
                    // Something long
                    Thread.Sleep(1000);
                    
                    // >>>> THE POWER !!
                    yield return "Process " + item;
                });
        }

But no we can’t because “The yield statement cannot be used inside an anonymous method or lambda expression“.
You obviously can’t mix those two pieces of magic together. In fact, if we could this would produce some of the weirdest bugs ever if something went wrong. But maybe we can’t build something that looks like it, for the sake of doing it?

        static void Main(string[] args)
        {
            var input = new[] { "A", "B", "C" };

            Stopwatch w = new Stopwatch();
            w.Start();
            var result = Process(input);

            Trace.WriteLine(String.Format("{0}s before enumerating", w.Elapsed.TotalSeconds));
            Trace.WriteLine(String.Format(String.Join("\n", result)));
            Trace.WriteLine(String.Format("{0}s after enumerating", w.Elapsed.TotalSeconds));
        }

        static IEnumerable<string> Process(IEnumerable<string> input)
        {
            if (input == null)
                throw new ArgumentNullException("input");

            var workQueue = new ConcurrentQueue<string>();
            Exception workException = null;
            var completed = false;

            // This task will run on its side in another thread
            Task.Run(() =>
            {
                try
                {
                    Parallel.ForEach(input, item =>
                        {
                            // Something long
                            Thread.Sleep(1000);

                            // Push our results here
                            workQueue.Enqueue("Process " + item);
                        });
                }
                catch (Exception ex)
                {
                    // We don't want a crash to be lost in another thread
                    // so we have to bring it back somehow on the main thread
                    workException = ex;
                }

                completed = true;
            });

            // Not the most elegant, but it's just for fun so ...
            while (!completed)
            {
                string item;
                if (workQueue.TryDequeue(out item))
                    yield return item;
                else
                    Thread.Sleep(1); // remember, just for fun
            }

            // We don't want to lose the last items
            string finalItem;
            while (workQueue.TryDequeue(out finalItem))
                yield return finalItem;

            // Buble the exception if there's one
            if (workException != null)
            {
                throw new Exception("Error while doing stuffs", workException);
            }
        }

Output:

0.00039s before enumerating
Process B
Process A
Process C
1.0398348s after enumerating

Notice than we did have an “yield behavior” as the processing was not executed on the call to Process, and how the whole process took 1s where it has 3 items that each took 1s. We also don’t have a reliable order anymore, it could have been any combination of B, A and C.

But anyway, nailed it 🙂

Say you have state defining struct you want to be copy:

 

        public struct MyStruct
        {
            public int A;
        }

Then use it like that:

            var S0 = new MyStruct();
            S0.A = 42;

            var S1 = S0;
            S1.A = 1337;

            Trace.WriteLine(String.Format("S0 = {0}, S1 = {1}", S0.A, S1.A));

The output is: S0 = 42, S1 = 1337
Even though S1 = S0, because it’s a struct it was copied. If I replace struct by class I get S0 = 1337, S1 = 1337. Everything’s normal.

Let say I want to have an array in this struct:

        public struct MyStruct
        {
            // Can't initialize the array directly
            public int[] A;

            // We can't customize the parameterless constructor
            public MyStruct(int size)
            {
                A = new int[size];
            }
        }

        var S0 = new MyStruct(1);
        S0.A[0] = 42;

        var S1 = S0;
        S1.A[0] = 1337;

        Trace.WriteLine(String.Format("S0 = {0}, S1 = {1}", S0.A[0], S1.A[0]));

The output is … S0 = 1337, S1 = 1337
That’s because the reference to the array was copied in the struct, not the actual value.
How can we have the array inside the struct?

        public unsafe struct MyStruct
        {
            public fixed int A[1];
        }

        unsafe static void Main(string[] args)
        {
            var S0 = new MyStruct();
            S0.A[0] = 42;

            var S1 = S0;
            S1.A[0] = 1337;

            Trace.WriteLine(String.Format("S0 = {0}, S1 = {1}", S0.A[0], S1.A[0]));
        }

And I get S0 = 42, S1 = 1337. But there are 2 problems in this approach.

  • You now have to build everything using the unsafe keyword because now A is a int*
  • This works:
                var S0 = new MyStruct();
                S0.A[1] = 42;
    
                var S1 = S0;
                S1.A[1] = 1337;
    
                Trace.WriteLine(String.Format("S0 = {0}, S1 = {1}", S0.A[1], S1.A[1]));
    

    .
    Even though my array is 1 element long, I was able to access the second in-existent element and change it. That’s a buffer overflow: because my array is now unsafe, the runtime no longer checks the boundaries of my array and I can access memory outside my allowed space.

What would be cool is if I was able to write that:

        public struct MyStruct
        {
            // hey C# compiler, create 10 int fields in my struct (from A0 to A9) and translate S0.A[i] to S0.Ai for me
            public int A[10];
        }

Btw I realize this wouldn’t work for some cases like, what should happen if we pass this A as a parameter for a method call expecting a regular array? If we try to store the A in a local int[], what would be in that variable? A new copy of this array? The address of that array in the struct that might be allocated on the stack? How should we track that reference?

But anyway, we can dream 🙂

In-depth look at WinRT

March 28, 2013

A little article I found Yesterday. It’s quite old but very interesting to read 🙂

Turning to the past to power Windows’ future: An in-depth look at WinRT

Turning to the past to power Windows’ future: An in-depth look at WinRT

There is one beautiful thing with the current .NET Framework and Windows 8 Apps : running your code asynchronously without blocking your UI thread.

You simply have to have a function like that, and it “magically” works:

private async void StartButton_Click(object sender, RoutedEventArgs e)
{
    try
    {
         textBox1.Text = 
         await httpClient.GetStringAsync
         ("http://msdn.microsoft.com");
    } catch (Exception) { // Process the exception. . . . }
}

Using that, you get a code that is running from the UI thread, runs into StartButton_Click, launch a task for the GetStringAsync and returns. When the GetStringAsync is finally over, the “textBox1.Text = thing” part get executed, and it works because we are still on the UI Thread. Doing so, we don’t violate the constraint of accessing UI elements from the thread that created it.

But how does it work really ? How does the Framework knows which thread is targeted and where to run the remaining of the method ?

Read the rest of this entry »

When you build an Editor, there’s always one thing you are going to need : a good property editor.

For that, I’ve chosen the one in Extended WPF Toolkit and it behaves quite nicely. But then it got tricky. In my engine, one does not simply walk set a property like that. I have that kind of structure:

 /// <summary>
 /// ...
 /// </summary>
 public GeometryMaterial GetGlobalMaterialOverride(ModifierReference reference)
 {
...
 }

/// <summary>
 /// ...
 /// </summary>
 public void SetGlobalMaterialOverride(ModifierReference reference, GeometryMaterial material)
 {
...
 }

Thus, giving it to the property grid produces no result.

Read the rest of this entry »

Y U NO speak japanese ?

February 29, 2012

While developing my game for ImagineCup (the next deadlines are respectively 9th March for France and 13rd March for the World), there is an even bigger challenge for me now.

Read the rest of this entry »