2 min read

Extending the Content Pipeline - Part 7

Building the Type Reader

The reader is the part that reads the .xnb file back in when the game tries to load it. Essentially, this will just do what the writer did, but in reverse. It should be pretty easy to do, but be sure to put it in the game library (LevelLibrary), not the content pipeline extension library!

Add the class by right-clicking on the game library (LevelLibrary) and choose Add > New Item from the popup menu. In the dialog that appears, choose the Content Type Reader template and give the reader a name (I’ve called mine “LevelReader.cs”). Click OK to create the file.

Like before, the first thing to do is to change the output type near the top. Locate the line that says:

using TRead = System.String;

and change it to say:

using TRead = LevelLibrary.Level;

Then we need to read in the .xnb file and give the user back a Level to use. Go to the Read() method and replace the code that is in there with the following:

int rows = input.ReadInt32();
int columns = input.ReadInt32();

int[,] levelData = new int[rows, columns];

for (int row = 0; row < rows; row++)
{
    for (int column = 0; column < columns; column++)
    {
        levelData[row, column] = input.ReadInt32();
    }
}

return new Level(levelData);

This just reads in the data in the same order that we wrote it when we made the level writer. This completes the entire content pipeline extension, and we are ready to use it! The full code for the level reader should look like this:

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;

using TRead = LevelLibrary.Level;

namespace LevelLibrary
{
    public class LevelReader : ContentTypeReader<TRead>
    {
        protected override TRead Read(ContentReader input, TRead existingInstance)
        {
            int rows = input.ReadInt32();
            int columns = input.ReadInt32();

            int[,] levelData = new int[rows, columns];

            for (int row = 0; row < rows; row++)
            {
                for (int column = 0; column < columns; column++)
                {
                    levelData[row, column] = input.ReadInt32();
                }
            }

            return new Level(levelData);
        }
    }
}