diff --git a/Output/RequiredSkinElements.xml b/Output/RequiredSkinElements.xml new file mode 100644 index 00000000..1d780dc9 --- /dev/null +++ b/Output/RequiredSkinElements.xml @@ -0,0 +1,49 @@ + + + + BG_Default + Menu + Button + CoverTile + SelectSlide + SelectSlidePlayer + SelectSlideArrowLeft + SelectSlideArrowRight + PopupBG + Random + ScrollUp + ScrollDown + Invisible + PlayerSelector + Plus + Minus + + + BG_Video + + + Player1 + Player2 + Player3 + Player4 + Player5 + Player6 + BackgroundColor + StaticColor + StaticWarningColor + ButtonColor + ButtonSColor + ButtonTextColor + ButtonTextSColor + SelectSlideColor + SelectSlideHColor + SelectSlideSColor + ArrowColor + ArrowSColor + TextColor + TextSColor + TextWarningColor + Visible + Invisible + + \ No newline at end of file diff --git a/Vocaluxe/Base/CSettings.cs b/Vocaluxe/Base/CSettings.cs index b5f599de..528b56e1 100644 --- a/Vocaluxe/Base/CSettings.cs +++ b/Vocaluxe/Base/CSettings.cs @@ -94,6 +94,8 @@ namespace Vocaluxe.Base public const string FileNameDebugLog = "Debug.log"; public const string FileNameSongInfoLog = "SongInformation.log"; + public const string FileNameRequiredSkinElements = "RequiredSkinElements.xml"; + public const string FileNameSoundT440 = "440Hz.mp3"; public const string FolderNameSongs = "Songs"; diff --git a/Vocaluxe/Base/ThemeSystem/CSkin.cs b/Vocaluxe/Base/ThemeSystem/CSkin.cs index f4e64ac4..9494d742 100644 --- a/Vocaluxe/Base/ThemeSystem/CSkin.cs +++ b/Vocaluxe/Base/ThemeSystem/CSkin.cs @@ -17,10 +17,13 @@ namespace Vocaluxe.Base.ThemeSystem class CSkin { private const int _SkinSystemVersion = 3; + private static readonly List _RequiredTextures = new List(); + private static readonly List _RequiredVideos = new List(); + private static readonly List _RequiredColors = new List(); private readonly string _Folder; private readonly string _FileName; - public readonly int PartyModeID; + private readonly CTheme _Parent; private SInfo _Info; public String Name @@ -28,7 +31,7 @@ namespace Vocaluxe.Base.ThemeSystem get { return _Info.Name; } } - public readonly Dictionary Textures = new Dictionary(); + private readonly Dictionary _Textures = new Dictionary(); private readonly Dictionary _Videos = new Dictionary(); private readonly Dictionary _ColorSchemes = new Dictionary(); @@ -36,16 +39,35 @@ namespace Vocaluxe.Base.ThemeSystem private bool _IsLoaded; - public CSkin(string folder, string file, int partyModeId) + public static bool InitRequiredElements() + { + string path = Path.Combine(CSettings.ProgramFolder, CSettings.FileNameRequiredSkinElements); + CXMLReader xmlReader = CXMLReader.OpenFile(path); + if (xmlReader == null) + return false; + bool ok = xmlReader.Read("//root/Textures", _RequiredTextures); + ok &= xmlReader.Read("//root/Videos", _RequiredVideos); + ok &= xmlReader.Read("//root/Colors", _RequiredColors); + return ok; + } + + public static void Close() + { + _RequiredTextures.Clear(); + _RequiredVideos.Clear(); + _RequiredColors.Clear(); + } + + public CSkin(string folder, string file, CTheme parent) { _Folder = folder; _FileName = file; - PartyModeID = partyModeId; + _Parent = parent; } public override string ToString() { - return Name; + return _Parent.Name + ":" + Name; } #region Load @@ -62,7 +84,7 @@ namespace Vocaluxe.Base.ThemeSystem if (!ok) { - CLog.LogError("Can't load skin \"" + _FileName + "\". Invalid file!"); + CLog.LogError("Can't load skin file \"" + _FileName + "\". Invalid file!"); return false; } @@ -73,7 +95,7 @@ namespace Vocaluxe.Base.ThemeSystem { if (_IsLoaded) return true; - Debug.Assert(Textures.Count == 0 && _Videos.Count == 0); + Debug.Assert(_Textures.Count == 0 && _Videos.Count == 0); CXMLReader xmlReader = CXMLReader.OpenFile(Path.Combine(_Folder, _FileName)); if (xmlReader == null) return false; @@ -90,7 +112,7 @@ namespace Vocaluxe.Base.ThemeSystem CLog.LogError("Error on loading texture \"" + name + "\": " + fileName, true); return false; } - Textures.Add(name, texture); + _Textures.Add(name, texture); } // load videos @@ -111,19 +133,43 @@ namespace Vocaluxe.Base.ThemeSystem if (!_LoadColors(xmlReader)) return false; + if (!_CheckRequiredElements()) + return false; + _IsLoaded = true; return true; } + private bool _CheckRequiredElements() + { + if (_Parent.PartyModeID >= 0) + return true; + List missingTextures = _RequiredTextures.FindAll(name => !_Textures.ContainsKey(name)); + List missingVideos = _RequiredVideos.FindAll(name => !_Videos.ContainsKey(name)); + SColorF dummyColor; + List missingColors = _RequiredColors.FindAll(name => !GetColor(name, out dummyColor)); + if (missingTextures.Count + missingVideos.Count + missingColors.Count == 0) + return true; + string msg = "The skin \"" + this + "\" is missing the following elements: "; + if (missingTextures.Count > 0) + msg += Environment.NewLine + "Textures: " + string.Join(", ", missingTextures); + if (missingVideos.Count > 0) + msg += Environment.NewLine + "Videos: " + string.Join(", ", missingVideos); + if (missingColors.Count > 0) + msg += Environment.NewLine + "Colors: " + string.Join(", ", missingColors); + CLog.LogError(msg); + return false; + } + public void Unload() { - foreach (CTextureRef tex in Textures.Values) + foreach (CTextureRef tex in _Textures.Values) tex.Dispose(); foreach (CVideoSkinElement vsk in _Videos.Values) CVideo.Close(ref vsk.VideoStream); - Textures.Clear(); + _Textures.Clear(); _Videos.Clear(); _PlayerColors = null; _ColorSchemes.Clear(); @@ -133,7 +179,7 @@ namespace Vocaluxe.Base.ThemeSystem private bool _LoadColors(CXMLReader xmlReader) { - if (PartyModeID == -1) + if (_Parent.PartyModeID == -1) { _PlayerColors = new SColorF[CSettings.MaxNumPlayer]; @@ -160,6 +206,8 @@ namespace Vocaluxe.Base.ThemeSystem public bool GetColor(string colorName, out SColorF color) { + if (_Parent.Name == "Default" && !_RequiredColors.Contains(colorName)) + CLog.LogDebug("Non-Default color: " + colorName); return _ColorSchemes.TryGetValue(colorName, out color) || _GetPlayerColor(colorName, out color); } @@ -191,6 +239,7 @@ namespace Vocaluxe.Base.ThemeSystem public CVideoStream GetVideo(string videoName, bool loop = true) { + Debug.Assert(_Parent.Name != "Default" || _RequiredVideos.Contains(videoName)); CVideoSkinElement sk; if (_Videos.TryGetValue(videoName, out sk)) { @@ -206,8 +255,9 @@ namespace Vocaluxe.Base.ThemeSystem public CTextureRef GetTexture(string name) { + Debug.Assert(_Parent.Name != "Default" || _RequiredTextures.Contains(name)); CTextureRef texture; - Textures.TryGetValue(name, out texture); + _Textures.TryGetValue(name, out texture); return texture; } } diff --git a/Vocaluxe/Base/ThemeSystem/CTheme.cs b/Vocaluxe/Base/ThemeSystem/CTheme.cs index 42e37879..eedb2b85 100644 --- a/Vocaluxe/Base/ThemeSystem/CTheme.cs +++ b/Vocaluxe/Base/ThemeSystem/CTheme.cs @@ -83,7 +83,7 @@ namespace Vocaluxe.Base.ThemeSystem ok = false; foreach (string file in files) { - CSkin skin = new CSkin(path, file, PartyModeID); + CSkin skin = new CSkin(path, file, this); if (skin.Init()) { _Skins.Add(skin.Name, skin); @@ -133,7 +133,7 @@ namespace Vocaluxe.Base.ThemeSystem if (skin.Load()) break; skin.Unload(); - CLog.LogError("Failed to load skin " + Name + ":" + skin + "! Removing...", true); + CLog.LogError("Failed to load skin " + skin + "! Removing...", true); _Skins.Remove(skin.Name); skin = (PartyModeID == -1 || Name == CSettings.DefaultName) ? _Skins.Values.FirstOrDefault() : null; } diff --git a/Vocaluxe/Base/ThemeSystem/CThemes.cs b/Vocaluxe/Base/ThemeSystem/CThemes.cs index d4814313..03a4facc 100644 --- a/Vocaluxe/Base/ThemeSystem/CThemes.cs +++ b/Vocaluxe/Base/ThemeSystem/CThemes.cs @@ -40,13 +40,14 @@ namespace Vocaluxe.Base.ThemeSystem public static bool Init() { - return ReadThemesFromFolder(Path.Combine(CSettings.ProgramFolder, CSettings.FolderNameThemes), -1); + return CSkin.InitRequiredElements() && ReadThemesFromFolder(Path.Combine(CSettings.ProgramFolder, CSettings.FolderNameThemes), -1); } public static void Close() { Unload(); _Themes.Clear(); + CSkin.Close(); } public static void Unload() diff --git a/VocaluxeLib/Xml/CXmlDeserializer.cs b/VocaluxeLib/Xml/CXmlDeserializer.cs index 11a80d87..9d611c54 100644 --- a/VocaluxeLib/Xml/CXmlDeserializer.cs +++ b/VocaluxeLib/Xml/CXmlDeserializer.cs @@ -1,4 +1,7 @@ -using System.Linq; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; namespace VocaluxeLib.Xml { @@ -88,6 +91,17 @@ namespace VocaluxeLib.Xml return result; } + public bool Read(string xPath, List value) + { + Debug.Assert(value != null); + string val; + if (!GetValue(xPath, out val)) + return false; + string[] entries = val.Split(new string[] {"\r\n", "\n"}, StringSplitOptions.RemoveEmptyEntries); + value.AddRange(entries.Select(s => s.Trim()).Where(s => !string.IsNullOrEmpty(s))); + return true; + } + public bool CheckVersion(string xPath, int reqVersion) { int version = 0;