Hi,
I have recently pulled the latest runtime and noticed a change to the XNA runtime that breaks iOS MonoGame. This is not necessarily a problem because I can easily work around this, however I have also made another small change to my copy of the XNA runtime so that it works with Windows 8 store apps. I will describe the two issues/changes in detail below however I was wondering what your (Nate) thoughts were on how best to proceed. As I see it there are two options...
(1) I issue some pull requests so that the XNA runtime can stay fully compatible with MonoGame for the various platforms - either through "#ifdef directives" or subclassing where appropriate.
(2) or I just maintain my own copy of the XNA runtime which is MonoGame compatible and just continue to pull all your changes into my repo.
What are your thoughts? The advantage of '1' is that your official XNA runtime stays MonoGame compatible, however the disadvantage is that it may be harder, or more of a pain, to maintain. The advantage of option '2' means that the XNA runtime stays 'cleaner', however it means that anyone else wanting to use a MonoGame runtime will potentially have problems, unless they code round it or use my repo. What do you think? Personally I'm quite happy to maintain a separate MonoGame runtime - especially if that makes it easier for you as you develop more features as you don't need to worry about all the MonoGame platforms.
Please let me know your thoughts so I know how best to proceed.
With regards to the two issues I had...
(1) Util.cs was recently changed because there was a problem with the volatile nature of RenderTarget2D objects when the screen resolution changes. This change breaks the iOS MonoGame implementation because the underlying call to GetData is unsupported in OpenGL ES and no workaround has been implemented. Now, iOS probably doesn't need to worry about this change because the screen resolution won't change - so I would just not implement this for iOS, but keep it for other platforms. I imagine using an #ifdef directive to check the platform target at compile time - this is the approach the MonoGame developers have taken with all the MonoGame code.
(2) The Util.cs class (and also SkeletonJson.cs and Atlas.cs) load objects from streams. I can use this code straight out of the box for iOS MonoGame, however it did not work when developing for a Windows 8 store app because of the restriction around how you must load resources for Windows 8 store apps. Now, it was relatively easy to overcome this by changing the code (although I am by no means an expert in the use of async), however it is Windows 8 specific - hence I imagine I'd use an #ifdef directive or subclass this for different platforms.
Taking Util.cs as the example, the original code (that works for XNA and iOS MonoGame) is as per below...
static public Texture2D LoadTexture (GraphicsDevice device, String path) {
using (Stream input = new FileStream(path, FileMode.Open, FileAccess.Read)) {
try {
return Util.LoadTexture(device, input);
} catch (Exception ex) {
throw new Exception("Error reading texture file: " + path, ex);
}
}
}
..and the code that is required for MonoGame Windows 8 is as per below (and then it is a similar change for SkeletonJson.cs and Atlas.cs) ...
private static async Task<Texture2D> LoadFile(GraphicsDevice device, String path)
{
var folder = Windows.ApplicationModel.Package.Current.InstalledLocation;
var file = await folder.GetFileAsync(path).AsTask().ConfigureAwait(false);
try
{
return Util.LoadTexture(device, await file.OpenStreamForReadAsync().ConfigureAwait(false));
}
catch (Exception ex)
{
throw new Exception("Error reading texture file: " + path, ex);
}
}
static public Texture2D LoadTexture (GraphicsDevice device, String path)
{
return LoadFile(device, path).Result;
}
Let me know your thoughts. Cheers 🙂