Oct 27, 2013

How to build xnb files with visual studio 2012 for monogame 3

While doing monogame tutorials, I’ve spent a lot of time on a simple thing that could be useful for someone else. The problem is the following – monogame framework can render xnb assets (images, sounds, fonts, etc), but it has no built in way to compile them yet. It looks like monogame team is working on its own implementation of content pipeline, but its not ready yet.

There is another open source gaming platform – cocos-2dx. In order to get his content builder you need a visual studio extension. So start visual studio 2012 extensions and updates, and search for cocos:

Content builder plugin  After installing it, you will have a new project type – Monogame content builder

Content project type

Now after you build project, it will generate xnb file per each asset added in the project. You can add those as linked files for other projects:

2013-10-27_10-41-29

May 30, 2013

Migrating from Castle ActiveRecord

Unfortunately Castle ActiveRecord project is abandoned and not developed anymore. Latest release uses NHibernate 3.0 and is not compatible with last NHibernate due  to the changes in API of dynamic proxy.

So we have decided to remove dead assembly and move on. In order to do that there some major steps that needed to be done:

  1. Rewrite all dependent code that used ActiveRecordMediator class
  2. Implement ISession, ISessionFactory lifetime management
  3. Reconfigure NHibernate without using AR wrappers over configuration
  4. Export existing AR mappings based on attributes to XML
  5. Migrate XML mappings to mapping by code

First two steps are tightly related. Methods in ActiveRecordMediator class are easily translated into appropriate analogs in ISession object. We already had a Repositories layer that was used to encapsulate all NHibernate related code, so it was not a really big problem to inject session to them.

For lifetime management we implemented same solution that was described in my blog earlier – let the IoC container resolve it.

Now about third step. NHibernate has not a lot of configuration in fact. All the new API descriptions can be found here. AR doesn’t add a lot, so nothing fancy here.

Export ActiveRecord mappings to XML

With exporting mappings things are starting to get interesting. I couldn’t find an out of the box way in AR to do that. So in fact I had to copy paste methods and to make something from AR public to support this. So here is a mapper class that allows exporting (btw AR sources that we have used before removing it). Line 21 is a place where you have map as a string and do anything you want with it.

Migration from hbm.xml to code

Sure you can stop migration here and just keep XML mappings. But that is just not good enough. Now there is a task of converting XML mappings to code. What is the best tool to covert XML to anything else?.. Well its XSLT. Sorry for that, but it is as it is. So I’ve created a transformation that is capable to do what is needed. Source is too long to put here, so I’m putting a link to appropriate gist. There are some preparations need for mappings – remove all nhibernate namespaces and wrappers like

<hibernate-mapping  auto-import="true" default-lazy="false" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:nhibernate-mapping-2.2">
    <!-- mapping here should be kept --> 
</hibernate-mapping>

It uses XSLT 2.0 that is not supported by default .net tools. To run it you can use saxonica tool. In order to run it you can use following command line:

c:\Program Files\Saxonica\SaxonPE9.4N\bin\Transform.exe -s:mappings.xml -xsl:nbmToCs.xslt -o:mappings.cs

So after doing that you will have new nice mappings. Not everything that is supported by NHibernate is supported by XSLT, I’ve added only things that we needed. If you need to add something, feel free to contact me.

Apr 5, 2013

Downloading multiple files on Windows Phone 8

What I think is missing from the internet is a posts with examples of solving simple tasks that usually takes longer then they should. So I decided to share some.

What I wanted to do is to download a number of images from the internet, combine them and use it as a background for my app. The simple way to do that is with the help of build in BitmapImage class:

BitmapImage image = new BitmapImage(new Uri("http://test.jpg"));
image.ImageOpened += (sender, args) => {
    Process(); // here we have image downloaded
};

Each time I need to create new Uri I ask myself why there is no constructor that accepts string…

So what went wrong with the code above? The problem is that I needed all images content at the same time to combine them and put results to cache or something. First solution I came up with was using Interlocked.Increment() method. It solved problem in some way. But code became complicated and I didn’t like that. So here a better way to do that. In order to have determined point in time where all images are downloaded I created my file downloader helper:

public class ImageDownloader
{
    public static async Task<MemoryStream> Download(string url)
    {
        var request = (HttpWebRequest)HttpWebRequest.Create(url);

        var response = await Task<WebResponse>.Factory.FromAsync(request.BeginGetResponse, request.EndGetResponse, null);
        var result = new MemoryStream();
        using (var responseStream = response.GetResponseStream())
        {
            responseStream.CopyTo(result);
        }
        result.Position = 0;

        return result;
    }
}

Maybe returning Stream is not the best way to do it, but I think its ok for this example post. So code is simple and self-explanatory. It just downloads any file by provided URL.

Having that helper, we can compose list of tasks and execute processing just after receiving all images:

var imageUrls = new[] {
    string.Format("http://placekitten.com/{0}/{1}", imageWidth, imageHeight), 
    string.Format("http://placekitten.com/g/{0}/{1}", imageWidth, imageHeight)
};

var downloadTasks = new List<Task<MemoryStream>>();
foreach (var image in imageUrls)
{
    downloadTasks.Add(ImageDownloader.Download(image));
}

Task.Factory.ContinueWhenAll(downloadTasks.ToArray(), tasks => {
    WriteableBitmap image1 = new WriteableBitmap(imageWidth, imageHeight);
    image1.LoadJpeg(tasks[0].Result);
    WriteableBitmap image2 = new WriteableBitmap(imageWidth, imageHeight);
    image2.LoadJpeg(tasks[1].Result);

    Image1.Source = image1;
    Image2.Source = image2;
}, 
    CancellationToken.None, 
    TaskContinuationOptions.None, 
    TaskScheduler.FromCurrentSynchronizationContext() // this will make sure we are changing UI in the thread that is allowed to do that.
);

This code uses Task Parallel Library’s method ContinueWhenAll. It allows you to execute task after all other tasks are finished.

So that all what is needed. It is really simple, but took me a while to find the right classes and syntax to solve the problem.

You can download a working example here.