I have updated the Awesomium XNA component to use Awesomium 1.7.1. The most noticeable changes are: improved performance, syntax changes for various tasks, and the lack of smooth fonts over transparent backgrounds.
For performance, my credits screen no longer jerks (at least on my computer), and the performance graph isn’t causing performance issues. Yay!
Creating shared JavaScript objects that persist across pages has changed. Instead of this:
// Awesomium 1.6
awesomium.WebView.CreateObject("xna");
awesomium.WebView.SetObjectCallback("xna", "StartWorld", StartWorld);
awesomium.WebView.SetObjectCallback("xna", "Exit", Exit);
You do this:
// Awesomium 1.7.1
JSObject jsXNA = awesomium.WebView.CreateGlobalJavascriptObject("xna");
jsXNA.Bind("StartWorld", false, StartWorld);
jsXNA.Bind("Exit", false, Exit);
On that note, you’d think that you could create a persistent JavaScript object at any time, with or without the DOM for your page being ready because this JS object isn’t page-specific. But that’s not the case, Awesomium will throw an error if you try to create a persistent JS object before the DOM is ready. I don’t know about you, but I have two modes for my web-GUI to run in: Web Browser mode, and XNA mode. In web browser mode, the most notable change is the background, it is not transparent, I use a still of the background I use in game. In order to automatically detect if I’m in XNA or not, I check for the existence of the global JS object “xna”. But if making the persistent JS object needs the DOM ready, and onDomReady checks for the existence of this object, I have a bit of a catch 22. If I can guarantee that there is a moment between when the DOM is ready and when JavaScript’s onDomReady fires, I can safely create the shared object before anyone notices, but Awesomium doesn’t provide such a method. I tried the event DocumentReady, but it didn’t do the trick. To work around this, I’ve had to register to the DocumentReady event, load a dummy page, when the event triggers, deregister from the event, then create my persistent JS object(s), then finally load the page I actually want.
private void Init()
{
// Load some dummy page
awesomium.WebView.DocumentReady += WebView_DocumentReady;
awesomium.WebView.LoadHTML("<html><head><title>Loading...</title></head><body></body></html>");
}
void WebView_DocumentReady(object sender, UrlEventArgs e)
{
// Call this only once
awesomium.WebView.DocumentReady -= WebView_DocumentReady;
// Create callbacks for Awesomium content to communicate with the game
JSObject jsXNA = awesomium.WebView.CreateGlobalJavascriptObject("xna");
jsXNA.Bind("StartWorld", false, StartWorld);
jsXNA.Bind("Exit", false, Exit);
awesomium.WebView.Source = (Environment.CurrentDirectory + @"\..\UI\MainMenu.html").ToUri();
}
Not pretty, but it works. If you know of a better way, leave it in the comments.
Next major change is how pages are loaded. In Awesomium 1.6, you could do this:
WebCore.BaseDirectory = @"..\UI\";
awesomium.WebView.LoadFile("MainMenu.html");
And in 1.7.1 they’re pushing for people to use DataSources, but you can still get by using:
awesomium.WebView.Source = (Environment.CurrentDirectory + @"\..\UI\MainMenu.html").ToUri();
Last but not least, fonts are rendered opaquely over transparent backgrounds. This ends up making the soft edges of letters render black. Not great. There are ways around this, but I haven’t looked in to them too much.