DCSIMG
October 2011 - Posts - Pavel's Blog
Sign in | Join | Help

Pavel's Blog

Pavel is a software guy that is interested in almost everything
software related... way too much for too little time

October 2011 - Posts

Windows Phone: Combining Silverlight & XNA in a Single Page

Published at Oct 26 2011, 09:30 PM by pavely

There are two very distinct ways to program on Windows Phone 7.x: Silverlight & XNA. Silverlight is about UI, retained graphics and is event driven. XNA is about immediate mode graphics, based on a timer and polling; Very different models indeed. Each has its strengths and weaknesses. One of the new features in WP7.1 (“mango”) is the ability to combine the two to get the best of both worlds.

Here’s a typical scenario where this need may come up: suppose you’re developing an XNA game (2D or 3D). In a typical game you need to allow some configuration, such as setting volume, level of play or simply showing a high score table. XNA is not built for that. Although you could some up with your own controls such as buttons, list, etc. implemented in XNA, that would be a lot of work, and might not look like the “native” Silverlight counterparts. If you could combine a Silverlight page with some controls and some XNA content – you would have a nice solution to the problem.

Here’s how to do that. First, we’ll start with a project template that is part of the latest Mango tools for Visual Studio 2010 called “Silverlight and XNA Application”:

image

This template sets up some tedious boilerplate code for things to start actually working. The main project has two pages: the first, MainPage.xaml is a Silverlight only page. It just hosts a single button that causes navigation to the other page, GamePage.xaml. Since the main page is not useful for our purposes, I’ll remove it and set the start page to be GamePage.xaml in WMAppManifest.xml:

  1.   <Tasks>
  2.       <DefaultTaskName ="_default" NavigationPage="GamePage.xaml"/>
  3.   </Tasks>

Next, we want to create some Silverlight UI that should function correctly along with some XNA content. This is what I added in GamePage.xaml:

  1. <Grid LayoutUpdated="Grid_LayoutUpdated" x:Name="_mainGrid">
  2.     <Grid.RowDefinitions>
  3.         <RowDefinition />
  4.         <RowDefinition Height="Auto" />
  5.     </Grid.RowDefinitions>
  6.     <Rectangle x:Name="_rect" Stroke="Transparent" Fill="Transparent" />
  7.     <StackPanel Grid.Row="1" Orientation="Horizontal" Background="Black">
  8.         <Button Content="Reset" Click="OnReset"/>
  9.         <TextBlock Text="Balls:" Margin="10,0,0,0" VerticalAlignment="Center" />
  10.         <Slider Value="1" Minimum="1" Maximum="30" Width="280" Margin="10,0,0,0"
  11.                 ValueChanged="OnChangeBalls"/>
  12.     </StackPanel>
  13. </Grid>

Disregard the event handlers for now. This is how it looks in the designer:

image

Let’s try running the application as it stands. The result (in the emulator) is pretty disappointing:

SNAGHTML5b676b

The UI we just created is nowhere to be found. In actuality, it’s all there. I can even press the button if I can guess where it is. The problem is that XNA “takes over” and draws itself on top of everything, including the Silverlight generated UI.

How do we deal with that? I just want the XNA part to be above the controls I’ve placed. For this, we have to render the Silverlight UI into a texture, and then render that texture with the XNA scene, just like any other texture.

The key class here is UIElementRenderer. We’ll add a reference of that type to the GamePage class and create one in the LayoutUpdated event of the page:

  1. private void Grid_LayoutUpdated(object sender, EventArgs e) {
  2.     if(_uiRenderer == null)
  3.         _uiRenderer = new UIElementRenderer(_mainGrid, (int)_mainGrid.ActualWidth, (int)_mainGrid.ActualHeight);
  4. }

This UIElementRenderer can render the supplied element (via its Render method) (the main Grid in our example) into a texture. Then, we can render the texture like any other in XNA using a SpriteBatch – all this in the OnDraw supplied method, called each and every frame:

  1. private void OnDraw(object sender, GameTimerEventArgs e) {
  2.     SharedGraphicsDeviceManager.Current.GraphicsDevice.Clear(Color.LightBlue);
  3.  
  4.     _uiRenderer.Render();
  5.     spriteBatch.Begin();
  6.     spriteBatch.Draw(_uiRenderer.Texture, new Vector2(0, 0), Color.White);
  7.     spriteBatch.End();
  8. }

Note that we don’t actually need to create that texture. It’s created internally by the UIElementRenderer. If we run the app now, we should see the Silverlight UI on top of the light blue background:

SNAGHTMLce342d

Now that the hard part is out of the way, let’s add some interesting XNA content to be rendered within the area reserved for it.

I’ve added a colored “ball” texture, created a Texture2D field to hold it, and load it in the OnNavigatedTo override (if it hasn’t been loaded already):

  1. protected override void OnNavigatedTo(NavigationEventArgs e) {
  2.     // Set the sharing mode of the graphics device to turn on XNA rendering
  3.     SharedGraphicsDeviceManager.Current.GraphicsDevice.SetSharingMode(true);
  4.  
  5.     // Create a new SpriteBatch, which can be used to draw textures.
  6.     spriteBatch = new SpriteBatch(SharedGraphicsDeviceManager.Current.GraphicsDevice);
  7.     if(_ballTexture == null)
  8.         _ballTexture = contentManager.Load<Texture2D>("colorwheel");
  9.  
  10.     // Start the timer
  11.     timer.Start();
  12.  
  13.     base.OnNavigatedTo(e);
  14. }

I’ve created a simple class to hold some state of a ball object. I’d like to create several of those, and move them around the light blue area. Here’s the simple Ball class:

  1. public class Ball {
  2.     public Vector2 Speed { get; set; }
  3.     public Vector2 Position { get; set; }
  4.     public float RotationAngle { get; set; }
  5.     public float RotationSpeed { get; set; }
  6. }

Every ball has its own position, speed, rotation angle and rotation speed (around its own axis). Now let’s add a List<Ball>  field (_balls) to hold those, create one when the page is loaded and add or remove balls whenever the slider’s value change:

First, a general method to create a new, randomized ball:

 

  1. Ball CreateNewBall() {
  2.     var ball = new Ball {
  3.         Position = new Vector2(_rnd.Next((int)_rect.ActualWidth - _ballTexture.Width / 2), _rnd.Next((int)_rect.ActualHeight - _ballTexture.Height / 2)),
  4.         Speed = new Vector2((float)_rnd.NextDouble() * 8 - 4, (float)_rnd.NextDouble() * 8 - 4),
  5.         RotationAngle = (float)_rnd.NextDouble() * 360,
  6.         RotationSpeed = (float)_rnd.NextDouble() * 1.5f - .75f
  7.     };
  8.     return ball;
  9. }

_rnd is a Random instance, created at construction time, and _rect is a transparent Rectangle that is stretched to the first row of our grid (where the XNA content resides).

When the page is loaded, create a single ball (in the GamePage constructor):

  1. Loaded += delegate {
  2.     _balls.Add(CreateNewBall());
  3. };

Whenever the slider value changes, we’ll update the number of balls (in the _balls object):

  1. private void OnChangeBalls(object sender, RoutedPropertyChangedEventArgs<double> e) {
  2.     if(_rect == null) return;
  3.     int value = (int)e.NewValue;
  4.  
  5.     if(value < _balls.Count)
  6.         _balls.RemoveRange(value, _balls.Count - value);
  7.     else {
  8.         int count = _balls.Count;
  9.         for(int i = 0; i < value - count; i++)
  10.             _balls.Add(CreateNewBall());
  11.     }
  12. }

Now we need to update the balls position (and speed, if a ball hits the boundaries of the “game field”). This is done in the OnUpdate method, supplied by the project template (similar to a classic XNA Update method). I’ve also added some code that allows the user to touch a ball and swirl it to some direction based on finger drag:

  1. private void OnUpdate(object sender, GameTimerEventArgs e) {
  2.         if(TouchPanel.IsGestureAvailable) {
  3.             var sample = TouchPanel.ReadGesture();
  4.             foreach(var ball in _balls) {
  5.                 if(Math.Abs(sample.Position.X - ball.Position.X) < _ballTexture.Width / 2
  6.                     && Math.Abs(sample.Position.Y - ball.Position.Y) < _ballTexture.Height / 2) {
  7.                     // found ball
  8.                     ball.Speed = new Vector2(Math.Min(25, sample.Delta.X), Math.Min(25, sample.Delta.Y));
  9.                     break;
  10.                 }
  11.             }
  12.         }
  13.  
  14.         foreach(var ball in _balls) {
  15.             // update ball position
  16.             Vector2 pos = ball.Position + ball.Speed;
  17.             if(pos.X < _ballTexture.Width / 2) {
  18.                 pos.X = _ballTexture.Width / 2;
  19.                 ball.Speed = new Vector2(-ball.Speed.X, ball.Speed.Y);
  20.             }
  21.             else if(pos.X > (float)_rect.ActualWidth - _ballTexture.Width / 2) {
  22.                 pos.X = (float)_rect.ActualWidth - _ballTexture.Width / 2;
  23.                 ball.Speed = new Vector2(-ball.Speed.X, ball.Speed.Y);
  24.             }
  25.             else
  26.                 pos.X += ball.Speed.X;
  27.  
  28.             if(pos.Y < _ballTexture.Height / 2) {
  29.                 pos.Y = _ballTexture.Height / 2;
  30.                 ball.Speed = new Vector2(ball.Speed.X, -ball.Speed.Y);
  31.             }
  32.             else if(pos.Y > (float)_rect.ActualHeight - _ballTexture.Height / 2) {
  33.                 pos.Y = (float)_rect.ActualHeight - _ballTexture.Height / 2;
  34.                 ball.Speed = new Vector2(ball.Speed.X, -ball.Speed.Y);
  35.             }
  36.             else
  37.                 pos.Y += ball.Speed.Y;
  38.  
  39.             ball.Position = pos;
  40.  
  41.             ball.RotationAngle += ball.RotationSpeed;
  42.         }
  43.     }

The next step is drawing the balls, as they’re simply updating positions for now. This is done in another project-supplied method, OnDraw (where we rendered our Silverlight UI):

  1. private void OnDraw(object sender, GameTimerEventArgs e) {
  2.     SharedGraphicsDeviceManager.Current.GraphicsDevice.Clear(Color.LightBlue);
  3.  
  4.     _uiRenderer.Render();
  5.     spriteBatch.Begin();
  6.     spriteBatch.Draw(_uiRenderer.Texture, new Vector2(0, 0), Color.White);
  7.     foreach(var ball in _balls)
  8.         spriteBatch.Draw(_ballTexture, ball.Position, null, Color.White, ball.RotationAngle, new Vector2(_ballTexture.Width / 2, _ballTexture.Height / 2), 1.0f, SpriteEffects.None, 0);
  9.     spriteBatch.End();
  10. }

That’s basically it. I’ve also added a handler for the “Reset” button that creates randomly a new set of balls (you can look it up in attached code). This is how it looks with several balls all bouncing at different speeds, directions and rotations:

SNAGHTMLd9dd48

You can simply watch, or catch & drag some ball to change its direction or speed…

The Roslyn Project CTP is Available for Download

Published at Oct 19 2011, 11:54 PM by pavely

The so called “Roslyn” project from Microsoft has been finally released with this early CTP. What is “Roslyn”? It’s an attempt to make the internals of a C# or VB compiler exposed. The usual way we think about a compiler is as a black box – some input goes in – some output comes out. During the compilation process, the compiler builds various tables and gathers a lot of information on the input. After the output is generated, the compiler throws everything away. That’s really too bad.

In today’s world of sophisticated tools, with intellisense and refactoring, it would be really nice to tap in to that compiler knowledge without the need of creating our own C# or VB parsers. Although non-Microsoft tools had to do that (e.g. ReSharper), it would be better to get a first hand look at what the compiler knows. This is exactly what Roslyn is about. Tapping the internal knowledge of the compiler.

This idea is pretty exciting, as it opens up a lot of opportunities to enhance development tools and runtime behavior as well, such as Aspect Oriented Programming (AOP) features.

The CTP can be downloaded here. More information can be found on the Roslyn page on MSDN.

Some of My Favorite Small C++11 Features

Published at Oct 13 2011, 04:25 PM by pavely

The new C++11 standard, finally finalized (pun intended) contains dozens of features, both in the language and in the libraries. Some of those features are pretty complex (or at least less often used), but some are practically essential, and have been sorely missed (at least by me) since forever. Here’s a quick list of those small, simple, features that I like. it’s sometimes surprising to C# or Java developers that some of these features didn’t exist in C++ prior to C++11 (technically, C++03 or C++98; I’ll refer to this as “classic C++”). I will indicate which version of Visual Studio implements each feature (if at all): VS 2010 or VS 11.

1. nullptr

This is one of those features, that is not really a feature – it’s a necessity. In classic C++, a pointer pointing nowhere is written as the value NULL, which is a macro, typically defined as 0, although it doesn’t have to. This is unfortunate for a number of reasons: first, from a purist standpoint, we need to include some header file to get this definition; a definition for something so basic in a language that uses pointers as much as C++. Sure, this may have come from the C standard, but that’s no excuse. Second, this causes some surprising behavior. Consider this simple function overloads:

  1. void foo(int x) {
  2.     cout << "foo(int)" << endl;
  3. }
  4.  
  5. void foo(const char* s) {
  6.     cout << "foo(const char*)" << endl;
  7. }

What happens if we make the following call:

foo(NULL);

Which function should execute? I would expect the second one, because NULL is supposed to represent a pointer pointing nowhere, and some compilers define that as (void*)0. But some simply use 0. In Visual Studio, this calls the foo(int) version.

C++11 introduces the nullptr keyword. This really means a null pointer – pointer that points nowhere. Now this code

foo(nullptr);

calls the expected function foo(const char*). Visual Studio 2010 implements this feature.

 

2. auto

The audo keyword (which always existed, but was redundant and meant a stack-based variable) now means the compiler infers the type of a variable based on its intialization. This feature shortens code, usually making it more readable, especially when templates are concerned. For all you C# developers, It’s roughly equivalent to the C# var keyword. Here are some examples:

  1. auto x = 5;        // avoid
  2. auto name = "hello";        // avoid as well
  3. string name2 = "hello";
  4. auto len = name2.size();
  5.  
  6. map<int, string> dic;
  7. dic.insert(make_pair(1, "one"));
  8. dic.insert(make_pair(5, "five"));
  9. dic.insert(make_pair(100, "hundred"));
  10.  
  11. for(auto it = dic.begin(); it != dic.end(); ++it)
  12.     cout << it->second << endl;
  13.  
  14. auto element = dic.find(5);
  15. if(element == dic.end())
  16.     cout << "not found" << endl;
  17. else
  18.     cout << "found: " << element->second << endl;

Line 1 says x is an int. The compiler infers that from the right hand side. (5 is an int. 5.0 is double, etc.). This example is an abuse of the feature, so don’t do it.

The second example (line 2) is a little tricky. What is the actual type of name? is it std::string? Nope. It’s a const char*. Line 3 makes this right. Again, don’t use.

The real power of auto comes in line 11. The type if the variable it is something like map<int, string>::iterator. Really verbose to write and adds nothing of value to the code. I know it’s an iterator: why should I care about the exact type? As an iterator, it must support the operators ++ and * (dereferencing) and that’s all I care about.

Line 14 is similar. the find member function returns a map<int, string>::const_iterator. I don’t need to specify that exact type.

Note that auto does not mean “variant”, “object”, “void*” or any such fluid type. It’s a static type just as if I had specified the entire declaration by hand. This means that statements like:

auto x;

auto y = nullptr;

have no meaning and will not compile. The compiler can’t deduce the types of x or y.

This feature is implemented in VS 2010.

 

3. enum class

Enums have a “bug” in classic C++. Consider this code fragment:

  1. enum X {
  2.     A, B, C
  3. };
  4.  
  5. enum Y {
  6.     W, A, P
  7. };

This code does not compile, because in C++, enum values have outer scope. This means A defined by X collides with A defined by Y. This also means that setting a value like the following fails:

X x = A;

The compiler can’t distinguish between the two A’s. Perhaps we can write is like so:

X x = X::A;

This is, unfortunately not part of classic C++, although Visual Studio supports this syntax, but issues a warning, saying it’s a non-standard extension.

How can we solve all this? Here’s one idea:

  1. namespace X {
  2.     enum {
  3.         A, B, C
  4.     };
  5. }
  6.  
  7. namespace Y {
  8.     enum {
  9.         W, A, P
  10.     };
  11. };
  12.  
  13. void f() {
  14.     int x = X::A;
  15.     int y = Y::A;
  16. }

I use an anonymous enum nested inside a namespace. This works, but we lose some type safety. I now have to use an int to represent the enum value. Here’s another option:

  1. struct X {
  2.     enum {
  3.         A, B, C
  4.     };
  5. };
  6.  
  7. struct Y {
  8.     enum {
  9.         W, A, P
  10.     };
  11. };

This is similar, with the potential benefit of not being able to do a “using namespace” to re-introduce outer scope.

C++11 has a new feature, called enum class, that solves the above problem:

  1. enum class X {
  2.     A, B, C
  3. };
  4.  
  5. enum class Y {
  6.     W, A, P
  7. };
  8.  
  9. void f() {
  10.     X x = X::A;
  11.     Y y = Y::A;
  12. }

Now the code is clear and precise. enum class values don’t have outer scope, so the following would not compile:

X x = B;

This feature is not implemented in VS 2010, but is implemented in VS 11.

 

4. Class member initialization

In classic C++, only static const integral types can be initialized in a class definition like so:

  1. class Data {
  2.     static const int Count = 10;
  3.  
  4.     int Value;
  5. };

There is no way to do the same for the Value member variable. In C++11, we can write:

  1. class Data {
  2.     static const int Count = 10;
  3.  
  4.     int Value = 6;
  5. };

This effectively initializes the variable in (all) constructors. This is equivalent to this:

  1. class Data {
  2. public:
  3.     Data() : Value(6) {
  4.     }
  5.  
  6. private:
  7.     static const int Count = 10;
  8.     int Value;
  9. };

The C++11 feature will include such code in all constructors of the class.

A similar feature allows one constructor to call another (as C# and Java allow).

This feature (surprisingly) is not implemented in VS 2010 nor in VS 11.

 

5. Lambdas

Lambda functions may not be considered a “simple” feature, but at their simplest, they provide a convenient way to replace functors. “Functors”, or function objects, are objects masquerading as functions. This is essentially a class that overrides the call function operator(). Let’s look at an example using the transform algorithm. First, we can use a simple global function:

  1. int doTransform(int x) {
  2.     return x * 2;
  3. }
  4.  
  5. int _tmain(int argc, _TCHAR* argv[])
  6. {
  7.     vector<int> v;
  8.     for(int i = 1; i <= 5; i++)
  9.         v.push_back(i);
  10.  
  11.     transform(v.begin(), v.end(), v.begin(), doTransform);
  12.  
  13.     for(auto it = v.begin(); it != v.end(); ++it)
  14.         cout << *it << endl;
  15.  
  16.     return 0;
  17. }

transform is an templated function, and simply expects an operator() to exist. This is obvious for a global function like doTransform. We can replace that with a functor, that can store state (which a global function can’t):

  1. struct MyTransform {
  2.     int _factor;
  3.     MyTransform(int factor) : _factor(factor) {
  4.     }
  5.  
  6.     int operator()(int x) {
  7.         return x * _factor;
  8.     }
  9. };
  10.  
  11. int _tmain(int argc, _TCHAR* argv[])
  12. {
  13.     vector<int> v;
  14.     for(int i = 1; i <= 5; i++)
  15.         v.push_back(i);
  16.  
  17.     transform(v.begin(), v.end(), v.begin(), MyTransform(2));
  18.  
  19.     for(auto it = v.begin(); it != v.end(); ++it)
  20.         cout << *it << endl;
  21.  
  22.     return 0;
  23. }

Now we’re passing an object (functor). In C++11, we can pass a lambda function, which is an anonymous function that is placed inline:

  1. transform(v.begin(), v.end(), v.begin(), [](int x) {
  2.     return x * 2;
  3. });

This is really handy. The code is stored “locally”, you don’t have to look around to find the actual function transformation. Lambdas are capable of using outer scope variables, like so:

  1. int factor = 2;
  2. transform(v.begin(), v.end(), v.begin(), [=](int x) {
  3.     return x * factor;
  4. });

The little = sign means “capture by value” (as opposed to an ampersand (&) which means “capture by reference”). Lambdas have other interesting properties, but this is the “simple” part that I’ll tackle here. If you’re familiar with C# lambda expressions, then this should look somewhat familiar.

This feature is supported in VS 2010 and enhanced a bit in VS 11.

 

For an exhaustive list of C++11 features support in VS 2010 & VS 11, check out this post by the VC++ team.

WPF 4.5 New Feature: Live Shaping

Published at Oct 02 2011, 08:39 PM by pavely

The BUILD conference concentrated on the new Windows Runtime (WinRT) component of Windows 8, but .NET 4.5 was also introduced, providing enhancements and new features. WPF & Silverlight seemed to have suffered a blow (some would say a knockout), as the new Windows 8 “Metro” model is not built on the same types, but rather wraps new native C++/COM libraries (that’s WinRT for you). Still, line of business applications will not be “Metro” anytime soon, so I think saying goodbye to WPF is premature.

There are some new features in the preview of WPF 4.5, one of which is really nice, called Live Shaping.

When you bind a collection to a ItemsControl, you can do so indirectly, through a view (with the ICollectionView interface, for example). This allows sorting, grouping and filtering without ever touching the actual data.

Here’s a simple way to create a default view and apply sorting based on some property:

// _items is a collection of some type (e.g. Book)
ICollectionView view = CollectionViewSource.GetDefaultView(_items);
view.SortDescriptions.Add(new SortDescription("BookName", ListSortDirection.Ascending));

When a view is bound to an ItemsControl (via the ItemsSource property), the bound control uses the set sorting, grouping and/or filtering as appropriate. The problem with this in WPF 4, is that if a property (on which sorting is based, for example), changes value, and that change should move the object to a different location, that won’t happen. Here’s a simple example based on a DataGrid. A class named StockQuote is created; objects of that class are bound to a DataGrid, which allows sorting:

<DataGrid x:Name="_grid" AutoGenerateColumns="False" IsReadOnly="True" >
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Name}" Header="Name"  />
<DataGridTextColumn Binding="{Binding Value}" Header="Value" />
</DataGrid.Columns>
</DataGrid
>
 
class StockItem : INotifyPropertyChanged {
   public event PropertyChangedEventHandler PropertyChanged = delegate { };

   public string Name { get; set; }

   double _value;

   public double Value {
      get { return _value; }
      set {
         _value = value;
         PropertyChanged(this, new PropertyChangedEventArgs("Value"));
      }
   }
}
In WPF 4.5, one can request the ICollectionViewLiveShaping interface and provide that as binding source to the control:
ICollectionViewLiveShaping view = (ICollectionViewLiveShaping)CollectionViewSource.GetDefaultView(_items);
view.IsLiveSorting = true;
_grid.ItemsSource = (System.Collections.IEnumerable)view;

 
To test things out, we’ll create a timer that changes a stock value randomly:
_timer.Interval = TimeSpan.FromSeconds(1);
_timer.Tick += (s, e) => {
foreach(var item in _items)
item.Value += rnd.NextDouble() * 10 - 5;
};
_timer.Start();

 
_timer is a DispatcherTimer, and rnd is a Random. Here’s how it looks at runtime:
image

It may not be obvious, but the lines move up & down, depending on the stock price (they are now sorted by the Value column). If we go back to the original ICollectionView interface, the sorting will not be maintained beyond the initial click.

The demo project is attached and can be opened by the Visual Studio 11 Preview (you can download it here).