[gbrainy] Configurable assembly load plus separate domain for compiler service
- From: Jordi Mas <jmas src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gbrainy] Configurable assembly load plus separate domain for compiler service
- Date: Sat, 26 Feb 2011 19:45:20 +0000 (UTC)
commit ae34615b717859ba904840e7ef7cfcd5a48c05fb
Author: Jordi Mas <jmas softcatala org>
Date: Sat Feb 26 20:47:06 2011 +0100
Configurable assembly load plus separate domain for compiler service
src/Clients/Classical/gbrainy.cs | 5 ++
src/Clients/WebForms/Defines.cs | 2 +-
src/Clients/WebForms/Download.aspx | 2 +-
src/Clients/WebForms/Game.aspx.cs | 8 ++-
src/Clients/WebForms/Global.asax.cs | 8 ++-
src/Clients/WebForms/LanguageSupport.cs | 5 +-
src/Clients/WebForms/MasterPage.master | 31 +++++----
src/Clients/WebForms/MasterPage.master.cs | 17 +++++-
src/Clients/WebForms/MasterPage.master.designer.cs | 2 +
src/Clients/WebForms/Status.aspx.cs | 12 +++-
src/Clients/WebForms/TranslationsWeb.cs | 10 +++-
src/Clients/WebForms/package.sh | 1 +
src/Clients/WebForms/web.config | 6 ++
src/Core/Main/GameManager.cs | 30 ++++++---
src/Core/Main/Xml/CodeEvaluation.cs | 68 ++++++++++++++++++--
src/Core/Main/Xml/GameXml.cs | 8 ++-
src/Core/Services/IConfiguration.cs | 1 +
17 files changed, 174 insertions(+), 42 deletions(-)
---
diff --git a/src/Clients/Classical/gbrainy.cs b/src/Clients/Classical/gbrainy.cs
index 31d7940..6f37fd0 100755
--- a/src/Clients/Classical/gbrainy.cs
+++ b/src/Clients/Classical/gbrainy.cs
@@ -23,6 +23,7 @@ using Gtk;
using Mono.Unix;
using System.Diagnostics;
using Gdk;
+using System.Reflection;
using gbrainy.Core.Main;
using gbrainy.Core.Platform;
@@ -789,6 +790,10 @@ namespace gbrainy.Clients.Classical
ServiceLocator.Instance.GetService <IConfiguration> ().Set (ConfigurationKeys.GamesDefinitions, Defines.DATA_DIR);
ServiceLocator.Instance.GetService <IConfiguration> ().Set (ConfigurationKeys.GamesGraphics, Defines.DATA_DIR);
ServiceLocator.Instance.GetService <IConfiguration> ().Set (ConfigurationKeys.ThemesDir, Defines.DATA_DIR);
+
+ string assemblies_dir;
+ assemblies_dir = System.IO.Path.GetDirectoryName (Assembly.GetExecutingAssembly ().Location);
+ ServiceLocator.Instance.GetService <IConfiguration> ().Set (ConfigurationKeys.AssembliesDir, assemblies_dir);
}
public static void Main (string [] args)
diff --git a/src/Clients/WebForms/Defines.cs b/src/Clients/WebForms/Defines.cs
index 1ee76ab..4cbb90e 100644
--- a/src/Clients/WebForms/Defines.cs
+++ b/src/Clients/WebForms/Defines.cs
@@ -28,7 +28,7 @@ namespace gbrainy.Clients.WebForms
public const string THEMES_DIR = "themes/";
public const string VERBAL_ANALOGIES = "verbal_analogies.xml";
- public const string GAME_ASSEMBLY = "bin/gbrainy.Games.dll";
+ public const string GAME_ASSEMBLY = "gbrainy.Games.dll";
public const string GAMES_FILE = "games.xml";
}
}
diff --git a/src/Clients/WebForms/Download.aspx b/src/Clients/WebForms/Download.aspx
index 5764f7a..10b2a81 100644
--- a/src/Clients/WebForms/Download.aspx
+++ b/src/Clients/WebForms/Download.aspx
@@ -7,7 +7,7 @@
<p>You can download gbrainy from the following links:</p>
<ul>
<li><a href="http://live.gnome.org/gbrainy#Download">Linux</a></li>
-<li><a href="http://live.gnome.org/gbrainy/Windows">Windows</a></li>
+<li><a href="https://sourceforge.net/projects/gbrainy/files/gbrainy/">Windows</a></li>
</ul>
</asp:Content>
diff --git a/src/Clients/WebForms/Game.aspx.cs b/src/Clients/WebForms/Game.aspx.cs
index 74d7537..a9520c9 100644
--- a/src/Clients/WebForms/Game.aspx.cs
+++ b/src/Clients/WebForms/Game.aspx.cs
@@ -48,6 +48,7 @@ namespace gbrainy.Clients.WebForms
manager = new GameManager ();
manager.LoadAssemblyGames (Defines.GAME_ASSEMBLY);
manager.LoadVerbalAnalogies (System.IO.Path.Combine ("data/", Defines.VERBAL_ANALOGIES));
+ manager.LoadGamesFromXml (System.IO.Path.Combine ("data/", "games.xml"));
manager.Difficulty = gbrainy.Core.Main.GameDifficulty.Medium;
manager.GameType = gbrainy.Core.Main.GameSession.Types.LogicPuzzles |
@@ -97,7 +98,7 @@ namespace gbrainy.Clients.WebForms
Logger.Debug ("Game.Page_Load. Page load starts. Session ID {0}, IsPostBack {1}", Session.SessionID,
IsPostBack);
- HtmlForm form = (HtmlForm) Master.FindControl("main_form");
+ HtmlForm form = (HtmlForm) Master.FindControl ("main_form");
form.DefaultButton = answer_button.UniqueID;
if (WebSession.GameState == null)
@@ -107,6 +108,7 @@ namespace gbrainy.Clients.WebForms
session.GameManager = CreateManager ();
session.New ();
WebSession.GameState = session;
+ Global.TotalGamesSessions++;
_game = GetNextGame ();
UpdateGame ();
@@ -142,7 +144,7 @@ namespace gbrainy.Clients.WebForms
void InitPage ()
{
TranslationsWeb service = (TranslationsWeb) ServiceLocator.Instance.GetService <ITranslations> ();
- service.GetLanguageFromSession = GetLanguageFromSessionHandler;
+ service.OnGetLanguageFromSession = GetLanguageFromSessionHandler;
game_image.Width = image_width;
game_image.Height = image_height;
@@ -302,7 +304,7 @@ namespace gbrainy.Clients.WebForms
if (session != null)
session.End ();
- Global.TotalGamesSessions++;
+ Global.TotalEndedSessions++;
Global.TotalGames += session.History.GamesPlayed;
Global.TotalTimeSeconds += session.GameTime.Seconds;
diff --git a/src/Clients/WebForms/Global.asax.cs b/src/Clients/WebForms/Global.asax.cs
index ca55153..109b6f2 100644
--- a/src/Clients/WebForms/Global.asax.cs
+++ b/src/Clients/WebForms/Global.asax.cs
@@ -16,6 +16,7 @@ namespace gbrainy.Clients.WebForms
{
// Application counters
static public int TotalSessions { get; set; }
+ static public int TotalEndedSessions { get; set; }
static public int TotalGamesSessions { get; set; }
static public int TotalGames { get; set; }
static public int TotalTimeSeconds { get; set; }
@@ -39,9 +40,14 @@ namespace gbrainy.Clients.WebForms
Logger.LogDevice = new ConsoleLogger ();
}
- // Setup core services
+ // Register services
ServiceLocator.Instance.RegisterService <ITranslations> (new TranslationsWeb ());
+ ServiceLocator.Instance.RegisterService <IConfiguration> (new MemoryConfiguration ());
ThemeManager.ConfigPath = Defines.THEMES_DIR;
+
+ // Configuration
+ ServiceLocator.Instance.GetService <IConfiguration> ().Set (ConfigurationKeys.GamesGraphics, "images/");
+ ServiceLocator.Instance.GetService <IConfiguration> ().Set (ConfigurationKeys.AssembliesDir, "bin/");
Logger.Info ("Global.Application_Start.gbrainy web starting");
}
diff --git a/src/Clients/WebForms/LanguageSupport.cs b/src/Clients/WebForms/LanguageSupport.cs
index 1b2448b..d9faa75 100644
--- a/src/Clients/WebForms/LanguageSupport.cs
+++ b/src/Clients/WebForms/LanguageSupport.cs
@@ -60,7 +60,7 @@ namespace gbrainy.Clients.WebForms
// List of exposed locales
static Language [] languages =
{
- new Language ("English", "en_US.utf8"),
+ new Language ("English", "en_US.utf8"), // English always the first one, used as default
new Language ("Afrikaans", "af_ZA.utf8"),
new Language ("Catalan", "ca_ES.utf8"),
new Language ("Czech", "cs_CZ.utf8"),
@@ -88,6 +88,9 @@ namespace gbrainy.Clients.WebForms
static public Language GetFromCode (string code)
{
+ if (langmap.ContainsKey (code) == false)
+ return languages [0];
+
return langmap [code];
}
}
diff --git a/src/Clients/WebForms/MasterPage.master b/src/Clients/WebForms/MasterPage.master
index 09279b4..6524b74 100644
--- a/src/Clients/WebForms/MasterPage.master
+++ b/src/Clients/WebForms/MasterPage.master
@@ -6,21 +6,24 @@
<link href="styles.css" rel="stylesheet" type="text/css"/>
<link rel="shortcut icon" href="images/gbrainy.ico" />
- <script type="text/javascript">
-
- var _gaq = _gaq || [];
- _gaq.push(['_setAccount', 'UA-619579-3']);
- _gaq.push(['_trackPageview']);
+ <asp:ContentPlaceHolder Id="analytics" runat="server" Visible = "false">
+ <script type="text/javascript">
+
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-619579-3']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type =
+ 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' :
+ 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0];
+ s.parentNode.insertBefore(ga, s);
+ })();
+ </script>
+ </asp:ContentPlaceHolder>
- (function() {
- var ga = document.createElement('script'); ga.type =
- 'text/javascript'; ga.async = true;
- ga.src = ('https:' == document.location.protocol ? 'https://ssl' :
- 'http://www') + '.google-analytics.com/ga.js';
- var s = document.getElementsByTagName('script')[0];
- s.parentNode.insertBefore(ga, s);
- })();
- </script>
</head>
<body>
<form runat="server" id = "main_form">
diff --git a/src/Clients/WebForms/MasterPage.master.cs b/src/Clients/WebForms/MasterPage.master.cs
index c232f25..9c5d06d 100644
--- a/src/Clients/WebForms/MasterPage.master.cs
+++ b/src/Clients/WebForms/MasterPage.master.cs
@@ -19,11 +19,14 @@
using System;
using System.Web;
+using System.Configuration;
namespace gbrainy.Clients.WebForms
{
public partial class MasterPage : System.Web.UI.MasterPage
{
+ static string PRODUCTION = "production";
+ static bool ?includeGoogleAnalytics = null;
// Instead of Page_Load we do Page_Init (Executed before)
// To make sure that this code is executed before Page_Load the first page load
@@ -33,8 +36,20 @@ namespace gbrainy.Clients.WebForms
if (IsPostBack == true)
return;
-
+ analytics.Visible = IncludeGoogleAnalytics;
+ }
+
+ public bool IncludeGoogleAnalytics {
+ get {
+ if (includeGoogleAnalytics != null)
+ return includeGoogleAnalytics == true;
+
+ var content = ConfigurationSettings.AppSettings [PRODUCTION];
+
+ includeGoogleAnalytics = (content == "1");
+ return includeGoogleAnalytics == true;
+ }
}
}
}
diff --git a/src/Clients/WebForms/MasterPage.master.designer.cs b/src/Clients/WebForms/MasterPage.master.designer.cs
index feef474..9bd4b47 100644
--- a/src/Clients/WebForms/MasterPage.master.designer.cs
+++ b/src/Clients/WebForms/MasterPage.master.designer.cs
@@ -13,6 +13,8 @@ namespace gbrainy.Clients.WebForms {
public partial class MasterPage {
+ protected System.Web.UI.WebControls.ContentPlaceHolder analytics;
+
protected System.Web.UI.HtmlControls.HtmlForm main_form;
protected System.Web.UI.WebControls.ContentPlaceHolder main_placeholder;
diff --git a/src/Clients/WebForms/Status.aspx.cs b/src/Clients/WebForms/Status.aspx.cs
index 2d1cea7..8996bce 100644
--- a/src/Clients/WebForms/Status.aspx.cs
+++ b/src/Clients/WebForms/Status.aspx.cs
@@ -87,9 +87,19 @@ namespace gbrainy.Clients.WebForms
application_table.Rows.Add (r);
r = new TableRow ();
- AddCell (r, "Total sessions");
+ AddCell (r, "Total sessions (as assigned by .Net)");
AddCell (r, Global.TotalSessions.ToString ());
application_table.Rows.Add (r);
+
+ r = new TableRow ();
+ AddCell (r, "Total started game sessions");
+ AddCell (r, Global.TotalGamesSessions.ToString ());
+ application_table.Rows.Add (r);
+
+ r = new TableRow ();
+ AddCell (r, "Total ended game sessions");
+ AddCell (r, Global.TotalEndedSessions.ToString ());
+ application_table.Rows.Add (r);
r = new TableRow ();
AddCell (r, "Total games played");
diff --git a/src/Clients/WebForms/TranslationsWeb.cs b/src/Clients/WebForms/TranslationsWeb.cs
index 36e0c2b..bd036cc 100644
--- a/src/Clients/WebForms/TranslationsWeb.cs
+++ b/src/Clients/WebForms/TranslationsWeb.cs
@@ -30,12 +30,20 @@ namespace gbrainy.Clients.WebForms
public delegate string GetLanguageFromSessionHandler ();
static readonly object sync = new object ();
- public GetLanguageFromSessionHandler GetLanguageFromSession;
+ public GetLanguageFromSessionHandler OnGetLanguageFromSession;
public void Init (string package, string localedir)
{
Catalog.Init (package, localedir);
}
+
+ string GetLanguageFromSession ()
+ {
+ if (OnGetLanguageFromSession == null)
+ return LanguageSupport.Languages [0].LangCode;
+
+ return OnGetLanguageFromSession ();
+ }
public string GetString (string s)
{
diff --git a/src/Clients/WebForms/package.sh b/src/Clients/WebForms/package.sh
index ca5ee47..a92047a 100755
--- a/src/Clients/WebForms/package.sh
+++ b/src/Clients/WebForms/package.sh
@@ -20,6 +20,7 @@ cp ../*.asax .
cp ../web.config .
cp ../bin/*.dll bin
+cp ../bin/*.config bin
cp ../../../../data/*.xml data
cp ../../../../data/game-graphics/* images
cp ../../../../data/app-graphics/* images
diff --git a/src/Clients/WebForms/web.config b/src/Clients/WebForms/web.config
index e5d367d..7065a94 100644
--- a/src/Clients/WebForms/web.config
+++ b/src/Clients/WebForms/web.config
@@ -30,4 +30,10 @@ http://msdn2.microsoft.com/en-us/library/b5ysx397.aspx
<pages>
</pages>
</system.web>
+
+ <!-- Used to decide if Google Analytics is shown -->
+ <appSettings>
+ <add key="Production" value="1" />
+ </appSettings>
+
</configuration>
diff --git a/src/Core/Main/GameManager.cs b/src/Core/Main/GameManager.cs
index b40e61f..35e5361 100644
--- a/src/Core/Main/GameManager.cs
+++ b/src/Core/Main/GameManager.cs
@@ -152,6 +152,17 @@ namespace gbrainy.Core.Main
public GameLocator [] AvailableGames {
get { return available_games.ToArray (); }
}
+
+ // Gives the Assembly.Load used in GamaManager the right path to load the application assemblies
+ static Assembly ResolveAssemblyLoad (object sender, ResolveEventArgs args)
+ {
+ IConfiguration config = ServiceLocator.Instance.GetService <IConfiguration> ();
+ string asm_dir = config.Get <string> (ConfigurationKeys.AssembliesDir);
+ string full_name = System.IO.Path.Combine (asm_dir, args.Name);
+ return Assembly.LoadFile (full_name);
+ }
+
+ static bool domain_load;
// Dynamic load of the gbrainy.Games.Dll assembly
public void LoadAssemblyGames (string file)
@@ -168,17 +179,14 @@ namespace gbrainy.Core.Main
try
{
- // Expects the assembly to be in the same dir than this assembly
- Assembly asm = Assembly.GetExecutingAssembly ();
- string asm_dir = System.IO.Path.GetDirectoryName (asm.Location);
-#if _ASPNET_
- string s = System.IO.Path.GetFileName (file);
- AssemblyName aname = AssemblyName.GetAssemblyName (file);
- asem = Assembly.Load (aname);
-#else
- asem = Assembly.LoadFrom (System.IO.Path.Combine (asm_dir, file));
-#endif
-
+ if (domain_load == false)
+ {
+ AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler (ResolveAssemblyLoad);
+ domain_load = true;
+ }
+
+ asem = Assembly.Load (file);
+
foreach (Type t in asem.GetTypes())
{
if (t.FullName == CLASS)
diff --git a/src/Core/Main/Xml/CodeEvaluation.cs b/src/Core/Main/Xml/CodeEvaluation.cs
index 1ea211a..df4b79b 100644
--- a/src/Core/Main/Xml/CodeEvaluation.cs
+++ b/src/Core/Main/Xml/CodeEvaluation.cs
@@ -22,15 +22,27 @@ using System.Text;
using System.Text.RegularExpressions;
using Mono.CSharp;
+using System.Reflection;
+using gbrainy.Core.Services;
namespace gbrainy.Core.Main.Xml
{
- // Code evaluation functions
- public static class CodeEvaluation
+ // This class proxys data from one domain to another
+ public class CrossDomainProxy : MarshalByRefObject
{
- static bool? monofix_needed;
-
- static public void EvaluateVariables (string code)
+ string code;
+
+ public void SetCode (string c)
+ {
+ code = c;
+ }
+
+ public string GetVars ()
+ {
+ return Evaluator.GetVars ();
+ }
+
+ public void EvaluateVariables ()
{
string eval;
@@ -53,7 +65,51 @@ namespace gbrainy.Core.Main.Xml
Console.WriteLine ("GameXml. Error in games.xml: {0} when evaluating variable definition [{1}]", e.Message, code);
}
}
+ }
+ // Code evaluation functions
+ public static class CodeEvaluation
+ {
+ static bool? monofix_needed;
+ static string stored_vars;
+ static int unload_domain = 0;
+ static AppDomain tempDomain;
+ const int maximum_uses = 5;
+
+ static public void EvaluateVariables (string c)
+ {
+ if (tempDomain == null)
+ tempDomain = AppDomain.CreateDomain ("MonoCSharpDomain");
+
+ // Load the Mono Compiler service in a separate domain then
+ // we can recycle it to reduce memory consumption
+ //
+ // After Mono 2.12 this is no longer need
+ // http://tirania.org/blog/archive/2011/Feb-24.html
+ IConfiguration config = ServiceLocator.Instance.GetService <IConfiguration> ();
+ string asm_dir = config.Get <string> (ConfigurationKeys.AssembliesDir);
+ string full_name = System.IO.Path.Combine (asm_dir, "gbrainy.Core.dll");
+ AssemblyName aname = AssemblyName.GetAssemblyName (full_name);
+ Assembly asem = tempDomain.Load (aname);
+
+ CrossDomainProxy proxy = (CrossDomainProxy) tempDomain.CreateInstanceAndUnwrap(asem.FullName,
+ typeof (CrossDomainProxy).FullName);
+
+ proxy.SetCode (c);
+ tempDomain.DoCallBack (proxy.EvaluateVariables);
+ stored_vars = proxy.GetVars ();
+
+
+ if (unload_domain > maximum_uses)
+ {
+ AppDomain.Unload (tempDomain);
+ unload_domain = 0;
+ tempDomain = null;
+ }
+ else
+ unload_domain++;
+ }
+
static public string ReplaceVariables (string str)
{
const string exp = "\\[[a-z_]+\\]+";
@@ -67,7 +123,7 @@ namespace gbrainy.Core.Main.Xml
regex = new Regex (exp, RegexOptions.IgnoreCase);
match = regex.Match (str);
- vars = Evaluator.GetVars ();
+ vars = stored_vars;
vars = FixGetVars (vars);
while (String.IsNullOrEmpty (match.Value) == false)
diff --git a/src/Core/Main/Xml/GameXml.cs b/src/Core/Main/Xml/GameXml.cs
index 0230f6b..f2fce4f 100644
--- a/src/Core/Main/Xml/GameXml.cs
+++ b/src/Core/Main/Xml/GameXml.cs
@@ -452,7 +452,13 @@ namespace gbrainy.Core.Main.Xml
if (String.IsNullOrEmpty (image.Filename) == false)
{
- gr.DrawImageFromFile (Path.Combine (Defines.DATA_DIR, image.Filename),
+ string dir;
+ IConfiguration config;
+
+ config = ServiceLocator.Instance.GetService <IConfiguration> ();
+ dir = config.Get <string> (ConfigurationKeys.GamesGraphics);
+
+ gr.DrawImageFromFile (Path.Combine (dir, image.Filename),
image.X, image.Y, image.Width, image.Height);
}
}
diff --git a/src/Core/Services/IConfiguration.cs b/src/Core/Services/IConfiguration.cs
index 694165b..4e9e053 100644
--- a/src/Core/Services/IConfiguration.cs
+++ b/src/Core/Services/IConfiguration.cs
@@ -24,6 +24,7 @@ namespace gbrainy.Core.Services
GamesDefinitions, // Analogies.xml and games.xml
GamesGraphics,
ThemesDir,
+ AssembliesDir,
};
public interface IConfiguration : IService
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]