1 /* 2 * Copyright (C) 2007-2010 Jordi Mas i Hernàndez <jmas@softcatala.org> 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License as 6 * published by the Free Software Foundation; either version 2 of the 7 * License, or (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public 15 * License along with this program; if not, see <http://www.gnu.org/licenses/>. 16 */ 17 18 using System; 19 using System.Collections.Generic; 20 using System.Reflection; 21 22 using gbrainy.Core.Services; 23 using gbrainy.Core.Main.Verbal; 24 using gbrainy.Core.Main.Xml; 25 26 namespace gbrainy.Core.Main 27 { 28 // Manages all the games available on the system 29 public class GameManager 30 { 31 static Type[] VerbalAnalogiesInternal = new Type[] 32 { 33 typeof (AnalogiesQuestionAnswer), 34 typeof (AnalogiesMultipleOptions), 35 typeof (AnalogiesPairOfWordsOptions), 36 typeof (AnalogiesPairOfWordsCompare), 37 }; 38 39 List <GameLocator> available_games; // List of all available games in the system 40 int cnt_logic, cnt_memory, cnt_calculation, cnt_verbal; 41 static bool domain_load; 42 GameManager()43 public GameManager () 44 { 45 available_games = new List <GameLocator> (); 46 cnt_logic = cnt_memory = cnt_calculation = cnt_verbal = 0; 47 } 48 49 public GameTypes AvailableGameTypes { 50 get { 51 GameTypes types = GameTypes.None; 52 53 if (cnt_logic > 0) 54 types |= GameTypes.LogicPuzzle; 55 56 if (cnt_calculation > 0) 57 types |= GameTypes.Calculation; 58 59 if (cnt_memory > 0) 60 types |= GameTypes.Memory; 61 62 if (cnt_verbal > 0) 63 types |= GameTypes.VerbalAnalogy; 64 65 return types; 66 } 67 } 68 69 // Returns all the games available for playing 70 public GameLocator [] AvailableGames { 71 get { return available_games.ToArray (); } 72 } 73 74 // Gives the Assembly.Load used in GameManager the right path to load the application assemblies ResolveAssemblyLoad(object sender, ResolveEventArgs args)75 static Assembly ResolveAssemblyLoad (object sender, ResolveEventArgs args) 76 { 77 IConfiguration config = ServiceLocator.Instance.GetService <IConfiguration> (); 78 string asm_dir = config.Get <string> (ConfigurationKeys.AssembliesDir); 79 string full_name = System.IO.Path.Combine (asm_dir, args.Name); 80 return Assembly.LoadFile (full_name); 81 } 82 83 // Dynamic load of the gbrainy.Games.Dll assembly LoadAssemblyGames(string file)84 public void LoadAssemblyGames (string file) 85 { 86 const string CLASS = "gbrainy.Games.GameList"; 87 const string LOGIC_METHOD = "LogicPuzzles"; 88 const string CALCULATION_METHOD = "Calculation"; 89 const string MEMORY_METHOD = "Memory"; 90 91 Assembly asem; 92 Type type = null; 93 PropertyInfo prop; 94 object obj; 95 96 try 97 { 98 if (domain_load == false) 99 { 100 AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler (ResolveAssemblyLoad); 101 domain_load = true; 102 } 103 104 asem = Assembly.Load (file); 105 106 foreach (Type t in asem.GetTypes()) 107 { 108 if (t.FullName == CLASS) 109 { 110 type = t; 111 break; 112 } 113 } 114 115 obj = Activator.CreateInstance (type); 116 117 prop = type.GetProperty (LOGIC_METHOD); 118 if (prop != null) 119 cnt_logic += AddGamesAndVariations ((Type []) prop.GetValue (obj, null)); 120 121 prop = type.GetProperty (MEMORY_METHOD); 122 if (prop != null) 123 cnt_memory += AddGamesAndVariations ((Type []) prop.GetValue (obj, null)); 124 125 prop = type.GetProperty (CALCULATION_METHOD); 126 if (prop != null) 127 cnt_calculation += AddGamesAndVariations ((Type []) prop.GetValue (obj, null)); 128 } 129 130 catch (Exception e) 131 { 132 Console.WriteLine ("GameManager.LoadAssemblyGames. Could not load file {0}. Error {1}", file, e); 133 } 134 } 135 136 // XML are stored using the Variant as a pointer to the game + the internal variant LoadGamesFromXml(string file)137 public void LoadGamesFromXml (string file) 138 { 139 // Load defined XML games 140 GamesXmlFactory xml_games; 141 142 xml_games = new GamesXmlFactory (); 143 xml_games.Read (file); 144 145 Type type = typeof (GameXml); 146 int cnt = 0; 147 148 foreach (GameXmlDefinition game in xml_games.Definitions) 149 { 150 // If the game has variants the game definition is used as reference 151 // but only the variants are playable. The first variant is used as game (IsGame = true) 152 available_games.Add (new GameLocator (type, cnt++, game.Type, true)); 153 154 switch (game.Type) { 155 case GameTypes.LogicPuzzle: 156 cnt_logic++; 157 break; 158 case GameTypes.Calculation: 159 cnt_calculation++; 160 break; 161 default: 162 break; 163 } 164 165 for (int i = 1; i < game.Variants.Count; i++) 166 { 167 available_games.Add (new GameLocator (type, cnt++, game.Type, false)); 168 } 169 } 170 } 171 172 // Load an XML file with analogies LoadVerbalAnalogies(string file)173 public void LoadVerbalAnalogies (string file) 174 { 175 AnalogiesFactory.Read (file); 176 cnt_verbal += AddVerbalGamesAndVariations (VerbalAnalogiesInternal); 177 } 178 179 // Unload previous assembly, xml and verbal analogies loaded games ResetAvailableGames()180 public void ResetAvailableGames () 181 { 182 available_games.Clear (); 183 } 184 AddString(String str)185 private String AddString(String str) 186 { 187 return " - " + str + Environment.NewLine; 188 } 189 GetGamesSummary(ITranslations translations)190 public string GetGamesSummary (ITranslations translations) 191 { 192 String s = string.Empty; 193 #if MONO_ADDINS 194 s += translations.GetString ("Extensions database:") + " " + 195 System.IO.Path.Combine (Environment.GetFolderPath (Environment.SpecialFolder.ApplicationData), "gbrainy"); 196 197 s += Environment.NewLine; 198 #endif 199 // Translators: 'Games registered' is the games know to gbrainy (build-in and load from addins-in and external files) 200 int total = cnt_logic + cnt_memory + cnt_calculation + cnt_verbal; 201 s += String.Format (translations.GetPluralString ("{0} game registered:", "{0} games registered:", total) + Environment.NewLine, total); 202 s += AddString (String.Format (translations.GetPluralString ("{0} logic puzzle", "{0} logic puzzles", cnt_logic), cnt_logic)); 203 s += AddString (String.Format (translations.GetPluralString ("{0} calculation trainer", "{0} calculation trainers", cnt_calculation), cnt_calculation)); 204 s += AddString (String.Format (translations.GetPluralString ("{0} memory trainer", "{0} memory trainers", cnt_memory), cnt_memory)); 205 s += AddString (String.Format (translations.GetPluralString ("{0} verbal analogy", "{0} verbal analogies", cnt_verbal), cnt_verbal)); 206 return s; 207 } 208 209 // Adds all the games and its variants into the available games list AddGamesAndVariations(Type [] types)210 int AddGamesAndVariations (Type [] types) 211 { 212 Game game; 213 int cnt = 0; 214 215 foreach (Type type in types) 216 { 217 game = (Game) Activator.CreateInstance (type, true); 218 for (int i = 0; i < game.Variants; i++) 219 { 220 available_games.Add (new GameLocator (type, i, game.Type, game.Variants == 1)); 221 } 222 cnt += game.Variants; 223 } 224 return cnt; 225 } 226 227 // Adds all the games and its variants into the available games list AddVerbalGamesAndVariations(Type [] types)228 int AddVerbalGamesAndVariations (Type [] types) 229 { 230 Game game; 231 int cnt = 0; 232 233 foreach (Type type in types) 234 { 235 game = (Game) Activator.CreateInstance (type, true); 236 for (int i = 0; i < game.Variants; i++) 237 { 238 available_games.Add (new GameLocator (type, i, game.Type, true)); 239 } 240 cnt += game.Variants; 241 } 242 return cnt; 243 } 244 } 245 } 246