WIP
DirectOutput framework for virtual pinball cabinets WIP
Go to:
Overview 
GlobalConfig.cs
Go to the documentation of this file.
1 using System;
2 using System.Collections.Generic;
3 using System.IO;
4 using System.Reflection;
5 using System.Text;
6 using System.Xml;
7 using System.Xml.Serialization;
8 using System.Linq;
10 
11 
12 namespace DirectOutput.GlobalConfiguration
13 {
14 
18  public class GlobalConfig
19  {
20 
21 
22 
23  #region IniFiles
24 
25 
26 
27  private int _LedWizDefaultMinCommandIntervalMs = 1;
28 
39  public int LedWizDefaultMinCommandIntervalMs
40  {
41  get { return _LedWizDefaultMinCommandIntervalMs; }
42  set { _LedWizDefaultMinCommandIntervalMs = value.Limit(0, 1000); }
43  }
44 
45 
46  private int _LedControlMinimumEffectDurationMs = 60;
47 
56  public int LedControlMinimumEffectDurationMs
57  {
58  get { return _LedControlMinimumEffectDurationMs; }
59  set { _LedControlMinimumEffectDurationMs = value; }
60  }
61 
62  private int _LedControlMinimumRGBEffectDurationMs = 120;
63 
72  public int LedControlMinimumRGBEffectDurationMs
73  {
74  get { return _LedControlMinimumRGBEffectDurationMs; }
75  set { _LedControlMinimumRGBEffectDurationMs = value; }
76  }
77 
78 
79 
80  private string _IniFilesPath="";
81 
88  public string IniFilesPath
89  {
90  get { return _IniFilesPath; }
91  set { _IniFilesPath = value; }
92  }
93 
94 
100  public Dictionary<int, FileInfo> GetIniFilesDictionary(string TableFilename = "")
101  {
102  //Build the array of possible paths for the ini files
103 
104  List<string> LookupPaths = new List<string>();
105 
106  if (!IniFilesPath.IsNullOrWhiteSpace())
107  {
108  try
109  {
110  DirectoryInfo DI = new DirectoryInfo(IniFilesPath);
111  if (DI.Exists)
112  {
113  LookupPaths.Add(DI.FullName);
114  }
115  } catch (Exception E) {
116  Log.Exception("The specified IniFilesPath {0} could not be used due to a exception.".Build(IniFilesPath),E);
117  } ;
118  }
119 
120 
121  if (!TableFilename.IsNullOrWhiteSpace())
122  {
123  try
124  {
125  if (new FileInfo(TableFilename).Directory.Exists)
126  {
127  LookupPaths.Add(new FileInfo(TableFilename).Directory.FullName);
128  }
129  }
130  catch { }
131  }
132 
133 
134  LookupPaths.AddRange(new string[] { GetGlobalConfigDirectory().FullName, Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) });
135 
136  //Build the dictionary of ini files
137 
138  Dictionary<int, FileInfo> IniFiles = new Dictionary<int, FileInfo>();
139 
140  bool FoundIt = false;
141  string[] LedControlFilenames = { "directoutputconfig", "ledcontrol" };
142 
143  foreach (string LedControlFilename in LedControlFilenames)
144  {
145  foreach (string P in LookupPaths)
146  {
147  DirectoryInfo DI = new DirectoryInfo(P);
148 
149  List<FileInfo> Files = new List<FileInfo>();
150  foreach (FileInfo FI in DI.EnumerateFiles())
151  {
152  if (FI.Name.ToLower().StartsWith(LedControlFilename.ToLower()) && FI.Name.ToLower().EndsWith(".ini"))
153  {
154  Files.Add(FI);
155  }
156  }
157 
158 
159  foreach (FileInfo FI in Files)
160  {
161  if (string.Equals(FI.Name, "{0}.ini".Build(LedControlFilename), StringComparison.OrdinalIgnoreCase))
162  {
163  if (!IniFiles.ContainsKey(1))
164  {
165  IniFiles.Add(1, FI);
166  FoundIt = true;
167  }
168  else
169  {
170  Log.Warning("Found more than one ini file with for number 1. Likely you have a ini file without a number and and a second one with number 1.");
171  }
172  }
173  else
174  {
175  string F = FI.Name.Substring(LedControlFilename.Length, FI.Name.Length - LedControlFilename.Length - 4);
176  if (F.IsInteger())
177  {
178  int LedWizNr = -1;
179  if (int.TryParse(F, out LedWizNr))
180  {
181  if (!IniFiles.ContainsKey(LedWizNr))
182  {
183  IniFiles.Add(LedWizNr, FI);
184  FoundIt = true;
185  }
186  else
187  {
188  Log.Warning("Found more than one ini file with number {0}.".Build(LedWizNr));
189  }
190 
191  }
192 
193  }
194 
195  }
196  };
197  if (FoundIt) break;
198  }
199  if (FoundIt) break;
200  }
201 
202 
203 
204  return IniFiles;
205 
206  }
207 
213  public FileInfo GetTableMappingFile(string TableFilename="")
214  {
215  Dictionary<int,FileInfo> IniFileDict = GetIniFilesDictionary(TableFilename);
216 
217  if (IniFileDict != null && IniFileDict.Count > 0)
218  {
219  DirectoryInfo DI = IniFileDict.First().Value.Directory;
220 
221  FileInfo FI = DI.GetFiles("tablemappings.*").FirstOrDefault();
222 
223  return FI;
224  }
225  else
226  {
227  return null;
228  }
229 
230 
231 
232  }
233 
234 
235  #endregion
236 
237 
238  private FilePattern _ShapeDefinitionFilePattern = null;
239 
246  public FilePattern ShapeDefintionFilePattern
247  {
248  get { return _ShapeDefinitionFilePattern; }
249  set { _ShapeDefinitionFilePattern = value; }
250  }
251 
256  public FileInfo GetShapeDefinitionFile(string TableFilename="", string RomName="")
257  {
258  if (ShapeDefintionFilePattern!=null && !ShapeDefintionFilePattern.Pattern.IsNullOrWhiteSpace() && ShapeDefintionFilePattern.IsValid)
259  {
260  return ShapeDefintionFilePattern.GetFirstMatchingFile(GetReplaceValuesDictionary(TableFilename, RomName));
261  }
262  Dictionary<int, FileInfo> IniFilesDict = GetIniFilesDictionary(TableFilename);
263  if (IniFilesDict.Count > 0)
264  {
265  FileInfo FI=new FileInfo(Path.Combine(IniFilesDict.Select(KV=>KV.Value).First().Directory.FullName,"DirectOutputShapes.xml"));
266  if (FI.Exists)
267  {
268  return FI;
269  }
270  }
271  FileInfo FII = new FilePattern("{DllDir}\\DirectOutputShapes.xml").GetFirstMatchingFile(GetReplaceValuesDictionary(TableFilename, RomName));
272  if (FII.Exists)
273  {
274  return FII;
275  }
276 
277 
278  return null;
279  }
280 
281 
282 
283 
284  #region Cabinet
285 
286  #region Cabinet config file
287 
288 
289  private FilePattern _CabinetConfigFilePattern=new FilePattern();
290 
297  public FilePattern CabinetConfigFilePattern
298  {
299  get { return _CabinetConfigFilePattern; }
300  set { _CabinetConfigFilePattern = value; }
301  }
302 
303 
304 
305 
310  public FileInfo GetCabinetConfigFile()
311  {
312  if (!CabinetConfigFilePattern.Pattern.IsNullOrWhiteSpace() && CabinetConfigFilePattern.IsValid)
313  {
314  return CabinetConfigFilePattern.GetFirstMatchingFile(GetReplaceValuesDictionary());
315  }
316 
317  return null;
318  }
319 
320 
325  public DirectoryInfo GetCabinetConfigDirectory()
326  {
327  FileInfo CC = GetCabinetConfigFile();
328  if (CC != null)
329  {
330  return CC.Directory;
331  }
332  return null;
333  }
334  #endregion
335 
336 
337  #endregion
338 
339 
340  #region Table
341 
342 
343 
344 
345 
346 
347  #region Table Config
348  private FilePatternList _TableConfigFilePatterns = new FilePatternList();
349 
356  public FilePatternList TableConfigFilePatterns
357  {
358  get { return _TableConfigFilePatterns; }
359  set { _TableConfigFilePatterns = value; }
360  }
361 
369  public FileInfo GetTableConfigFile(string FullTableFilename)
370  {
371  return TableConfigFilePatterns.GetFirstMatchingFile(GetReplaceValuesDictionary(FullTableFilename));
372  }
373 
374  #endregion
375 
376 
377  #endregion
378 
379 
380 
381  #region Logging
382  private bool _EnableLog = true;
383 
384 
391  public bool EnableLogging
392  {
393  get { return _EnableLog; }
394  set { _EnableLog = value; }
395  }
396 
397  private bool _ClearLogOnSessionStart=true;
398 
405  public bool ClearLogOnSessionStart
406  {
407  get { return _ClearLogOnSessionStart; }
408  set { _ClearLogOnSessionStart = value; }
409  }
410 
411 
412 
413 
414  private FilePattern _LogFilePattern = new FilePattern(".\\DirectOutput.log");
415 
416 
434  public FilePattern LogFilePattern
435  {
436  get { return _LogFilePattern; }
437  set { _LogFilePattern = value; }
438  }
439 
446  public string GetLogFilename(string TableFilename = "", string RomName = "")
447  {
448  Dictionary<string, string> R = GetReplaceValuesDictionary(TableFilename, RomName);
449  R.Add("DateTime", DateTime.Now.ToString("yyyyMMdd_hhmmss"));
450  R.Add("Date", DateTime.Now.ToString("yyyyMMdd"));
451  R.Add("Time", DateTime.Now.ToString("hhmmss"));
452 
453  return LogFilePattern.ReplacePlaceholders(R);
454  }
455 
456  #endregion
457 
458 
459 
460  internal Dictionary<string, string> GetReplaceValuesDictionary(string TableFileName = null, string RomName = "")
461  {
462  Dictionary<string, string> D = new Dictionary<string, string>();
463  if (GetGlobalConfigFile() != null)
464  {
465  D.Add("GlobalConfigDirectory", GetGlobalConfigDirectory().FullName);
466  D.Add("GlobalConfigDir", GetGlobalConfigDirectory().FullName);
467  }
468 
469  FileInfo FI = new FileInfo(Assembly.GetExecutingAssembly().Location);
470  D.Add("DllDirectory", FI.Directory.FullName);
471  D.Add("DllDir", FI.Directory.FullName);
472  D.Add("AssemblyDirectory", FI.Directory.FullName);
473  D.Add("AssemblyDir", FI.Directory.FullName);
474  if (!TableFileName.IsNullOrWhiteSpace())
475  {
476  FI = new FileInfo(TableFileName);
477  if (FI.Directory.Exists)
478  {
479  D.Add("TableDirectory", FI.Directory.FullName);
480  D.Add("TableDir", FI.Directory.FullName);
481  D.Add("TableDirectoryName", FI.Directory.Name);
482  D.Add("TableDirName", FI.Directory.Name);
483  }
484 
485  D.Add("TableName", Path.GetFileNameWithoutExtension(FI.FullName));
486  }
487  if (!RomName.IsNullOrWhiteSpace())
488  {
489  D.Add("RomName", RomName);
490  }
491 
492 
493  return D;
494 
495  }
496 
497 
498 
499  #region Global config properties
500 
501 
507  {
508  DirectoryInfo DI = GetGlobalConfigDirectory();
509  if (DI == null) return null;
510  return DI.FullName;
511  }
512 
519  public DirectoryInfo GetGlobalConfigDirectory()
520  {
521  FileInfo FI = GetGlobalConfigFile();
522  if (FI == null) return null;
523  return FI.Directory;
524 
525  }
526 
527 
528  private string _GlobalConfigFilename = "";
529 
536  [XmlIgnore]
537  public string GlobalConfigFilename
538  {
539  get { return _GlobalConfigFilename; }
540  set { _GlobalConfigFilename = value; }
541  }
542 
543 
548  public FileInfo GetGlobalConfigFile()
549  {
550  if (GlobalConfigFilename.IsNullOrWhiteSpace()) { return null; }
551  return new FileInfo(GlobalConfigFilename);
552  }
553  #endregion
554 
555 
556  #region Serialization
557  public string GetGlobalConfigXml()
562  {
563 
564  XmlSerializerNamespaces Namespaces = new XmlSerializerNamespaces();
565  Namespaces.Add(string.Empty, string.Empty);
566  XmlSerializer Serializer = new XmlSerializer(typeof(GlobalConfig));
567  MemoryStream Stream = new MemoryStream();
568  XmlWriterSettings Settings = new XmlWriterSettings();
569  Settings.Indent = true;
570  Settings.NewLineOnAttributes = true;
571 
572  XmlWriter Writer = XmlWriter.Create(Stream, Settings);
573  Writer.WriteStartDocument();
574  Writer.WriteComment("Global configuration for the DirectOutput framework.");
575  Writer.WriteComment("Saved by DirectOutput Version {1}: {0}".Build(DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss"), System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString()));
576  Serializer.Serialize(Writer, this, Namespaces);
577  Writer.WriteEndDocument();
578  Writer.Flush();
579  Stream.Position = 0;
580  string XML;
581  using (StreamReader sr = new StreamReader(Stream, Encoding.Default))
582  {
583  XML = sr.ReadToEnd();
584  sr.Dispose();
585  }
586  Stream.Dispose();
587 
588  return XML;
589  }
590 
591 
592 
599  public static GlobalConfig GetGlobalConfigFromConfigXmlFile(string GlobalConfigFileName)
600  {
601 
602  try
603  {
604  if (File.Exists(GlobalConfigFileName))
605  {
606 
607 
608  string Xml = General.FileReader.ReadFileToString(GlobalConfigFileName);
609 
610  GlobalConfig GC = GetGlobalConfigFromGlobalConfigXml(Xml);
611  if (GC != null)
612  {
613  GC.GlobalConfigFilename = GlobalConfigFileName;
614  }
615  return GC;
616 
617  }
618  else
619  {
620 
621  return null;
622  }
623  }
624  catch
625  {
626 
627  return null;
628  }
629  }
630 
631 
637  public static GlobalConfig GetGlobalConfigFromGlobalConfigXml(string ConfigXml)
638  {
639  try
640  {
641 
642  byte[] xmlBytes = Encoding.Default.GetBytes(ConfigXml);
643  using (MemoryStream ms = new MemoryStream(xmlBytes))
644  {
645  return (GlobalConfig)new XmlSerializer(typeof(GlobalConfig)).Deserialize(ms);
646  }
647  }
648  catch { return null; }
649 
650  }
651 
657  public void SaveGlobalConfig(string GlobalConfigFilename = "")
658  {
659  string GCFileName = (GlobalConfigFilename.IsNullOrWhiteSpace() ? this.GlobalConfigFilename : GlobalConfigFilename);
660  if (GCFileName.IsNullOrWhiteSpace())
661  {
662  ArgumentException Ex = new ArgumentException("No filename for GlobalConfig file has been supplied. Looking up the filename from the property GlobalConfigFilename failed as well");
663  throw Ex;
664  }
665  if (File.Exists(GCFileName))
666  {
667  //Create a backup of the current global config file
668  File.Copy(GCFileName, Path.Combine(Path.GetDirectoryName(GCFileName), "{1} old (replaced {0}){2}".Build(DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss"), Path.GetFileNameWithoutExtension(GCFileName), Path.GetExtension(GCFileName))));
669  };
670  DirectoryInfo GCDirectory = new FileInfo(GCFileName).Directory;
671 
672  GCDirectory.CreateDirectoryPath();
673  GetGlobalConfigXml().WriteToFile(GCFileName, false);
674 
675  }
676  #endregion
677 
678 
682  public GlobalConfig()
683  {
684 
685 
686 
687  }
688 
689  }
690 }
string GlobalConfigDirectoryName()
Path to the directory where the global config is stored (readonly).
GlobalConfig()
Initializes a new instance of the GlobalConfig class.
void SaveGlobalConfig(string GlobalConfigFilename="")
Saves the GlobalConfig to the file specified in GlobalConfigFilename. Before saving the current glob...
FileInfo GetCabinetConfigFile()
FileInfo object for the file containing the configuration of the cabinet (outputs, toys and so on).
string GlobalConfigFilename
Gets or sets the global config filename.
FileInfo GetShapeDefinitionFile(string TableFilename="", string RomName="")
Gets the FileInfo object for the xml file defining the shapes to be used by DOF.
static void Warning(string Message)
Writes a warning message to the log.
Definition: Log.cs:134
A simple logger used to record important events and exceptions.
Definition: Log.cs:14
FileInfo GetTableConfigFile(string FullTableFilename)
Gets a FileInfo object for the table config file. The file is lookued up using the list of the prope...
FileInfo GetGlobalConfigFile()
Gets a FileInfo object for the global config file.
DirectoryInfo GetCabinetConfigDirectory()
Gets the cabinet config directory.
FileInfo GetFirstMatchingFile(Dictionary< string, string > ReplaceValues=null)
Gets the first file matching the value of the Pattern property.
Definition: FilePattern.cs:148
string GetLogFilename(string TableFilename="", string RomName="")
Gets the log filename based on the LogFilePattern with replaced placeholders.
static GlobalConfig GetGlobalConfigFromGlobalConfigXml(string ConfigXml)
Instanciates a GlobalConfig object from a global configuration in a XML string.
Dictionary< int, FileInfo > GetIniFilesDictionary(string TableFilename="")
Gets the a dictionary containing all ini files (file) and their number (key).
Global configuration for the DirectOutput framework.
Definition: GlobalConfig.cs:18
DirectoryInfo GetGlobalConfigDirectory()
Gets a DirectoryInfo object for the global config directory.
The namespace DirectOutput.General contains classes for general use.
A file pattern class used to lookup files matching a specified pattern.
Definition: FilePattern.cs:12
FileInfo GetTableMappingFile(string TableFilename="")
Gets a FileInfo object pointing to the table mapping file or null if no table mapping file exists...
static void Exception(string Message, Exception E=null)
Writes a exception message to the log.
Definition: Log.cs:144
static GlobalConfig GetGlobalConfigFromConfigXmlFile(string GlobalConfigFileName)
Instanciates a GlobalConfig object from a global configuration in a XML file. If the global config f...