From b2755e026052cb88957902f1e002418daabc163e Mon Sep 17 00:00:00 2001 From: chrisf Date: Sat, 23 Jun 2007 17:59:13 +0000 Subject: [PATCH] wow, its like resource management! git-svn-id: svn://svn.ijw.co.nz/svn/OpenRa@1063 993157c7-ee19-0410-b2c4-bb4e9862e678 --- OpenRa.Core/FileSystem.cs | 29 +++++++++++++ OpenRa.Core/IMountable.cs | 12 ++++++ OpenRa.Core/OpenRa.Core.csproj | 53 ++++++++++++++++++++++++ OpenRa.Core/Properties/AssemblyInfo.cs | 17 ++++++++ OpenRa.Core/Reflect.cs | 18 ++++++++ OpenRa.Core/Resource.cs | 17 ++++++++ OpenRa.Core/ResourceBindingAttribute.cs | 16 +++++++ OpenRa.Core/ResourceCache.cs | 41 ++++++++++++++++++ OpenRa.Core/ResourceLoader.cs | 55 +++++++++++++++++++++++++ OpenRa.sln | 12 ++++++ 10 files changed, 270 insertions(+) create mode 100644 OpenRa.Core/FileSystem.cs create mode 100644 OpenRa.Core/IMountable.cs create mode 100644 OpenRa.Core/OpenRa.Core.csproj create mode 100644 OpenRa.Core/Properties/AssemblyInfo.cs create mode 100644 OpenRa.Core/Reflect.cs create mode 100644 OpenRa.Core/Resource.cs create mode 100644 OpenRa.Core/ResourceBindingAttribute.cs create mode 100644 OpenRa.Core/ResourceCache.cs create mode 100644 OpenRa.Core/ResourceLoader.cs diff --git a/OpenRa.Core/FileSystem.cs b/OpenRa.Core/FileSystem.cs new file mode 100644 index 0000000000..f0bd1b5e04 --- /dev/null +++ b/OpenRa.Core/FileSystem.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; + +namespace OpenRa.Core +{ + public static class FileSystem + { + static List packages = new List(); + + public static void Mount(IMountable package) + { + packages.Add(package); + } + + internal static Stream GetItem(string filename) + { + foreach (IMountable package in packages) + { + Stream s = package.GetItem(filename); + if (s != null) + return s; + } + + return null; + } + } +} diff --git a/OpenRa.Core/IMountable.cs b/OpenRa.Core/IMountable.cs new file mode 100644 index 0000000000..d041fe2072 --- /dev/null +++ b/OpenRa.Core/IMountable.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; + +namespace OpenRa.Core +{ + public interface IMountable + { + Stream GetItem(string filename); + } +} diff --git a/OpenRa.Core/OpenRa.Core.csproj b/OpenRa.Core/OpenRa.Core.csproj new file mode 100644 index 0000000000..be422579ce --- /dev/null +++ b/OpenRa.Core/OpenRa.Core.csproj @@ -0,0 +1,53 @@ + + + Debug + AnyCPU + 8.0.50727 + 2.0 + {1B60782F-B2DD-43F1-B51D-B798485F317C} + Library + Properties + OpenRa.Core + OpenRa.Core + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/OpenRa.Core/Properties/AssemblyInfo.cs b/OpenRa.Core/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..2827833515 --- /dev/null +++ b/OpenRa.Core/Properties/AssemblyInfo.cs @@ -0,0 +1,17 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +[assembly: AssemblyTitle("OpenRa.Core")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("OpenRa.Core")] +[assembly: AssemblyCopyright("Copyright © 2007")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +[assembly: ComVisible(false)] + +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenRa.Core/Reflect.cs b/OpenRa.Core/Reflect.cs new file mode 100644 index 0000000000..09a5d4bb5e --- /dev/null +++ b/OpenRa.Core/Reflect.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace OpenRa.Core +{ + static class Reflect + { + public static T GetAttribute(Type t) + where T : Attribute + { + T[] attribs = (T[])t.GetCustomAttributes(typeof(T), false); + if (attribs == null || attribs.Length == 0) + return null; + return attribs[0]; + } + } +} diff --git a/OpenRa.Core/Resource.cs b/OpenRa.Core/Resource.cs new file mode 100644 index 0000000000..5dbd559f91 --- /dev/null +++ b/OpenRa.Core/Resource.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace OpenRa.Core +{ + public interface IResource { } + + public abstract class Resource : IResource + where T : Resource + { + public static T Get(string filename) + { + return (T)ResourceCache.Get(filename); + } + } +} diff --git a/OpenRa.Core/ResourceBindingAttribute.cs b/OpenRa.Core/ResourceBindingAttribute.cs new file mode 100644 index 0000000000..f6c950c015 --- /dev/null +++ b/OpenRa.Core/ResourceBindingAttribute.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace OpenRa.Core +{ + public class ResourceBindingAttribute : Attribute + { + internal readonly string[] Extensions; + + public ResourceBindingAttribute(params string[] extensions) + { + Extensions = extensions; + } + } +} diff --git a/OpenRa.Core/ResourceCache.cs b/OpenRa.Core/ResourceCache.cs new file mode 100644 index 0000000000..b1748344ba --- /dev/null +++ b/OpenRa.Core/ResourceCache.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; + +namespace OpenRa.Core +{ + static class ResourceCache + { + static Dictionary items = new Dictionary(); + + public static void Flush() + { + items.Clear(); + } + + public static IResource Get(string filename) + { + IResource r; + if (!items.TryGetValue(filename, out r)) + items.Add(filename, r = Load(filename)); + return r; + } + + static IResource Load(string filename) + { + Converter loader = + ResourceLoader.GetLoader(Path.GetExtension(filename)); + + if (loader == null) + return null; + + Stream s = FileSystem.GetItem(filename); + + if (s == null) + return null; + + return loader(s); + } + } +} diff --git a/OpenRa.Core/ResourceLoader.cs b/OpenRa.Core/ResourceLoader.cs new file mode 100644 index 0000000000..c15b4bc447 --- /dev/null +++ b/OpenRa.Core/ResourceLoader.cs @@ -0,0 +1,55 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; +using System.Reflection; + +namespace OpenRa.Core +{ + static class ResourceLoader + { + static Dictionary> loaders = + new Dictionary>(); + + static ResourceLoader() + { + foreach (Assembly a in AppDomain.CurrentDomain.GetAssemblies()) + BindTypes(a); + + AppDomain.CurrentDomain.AssemblyLoad += + delegate(object unused, AssemblyLoadEventArgs e) { BindTypes(e.LoadedAssembly); }; + } + + static void BindTypes(Assembly a) + { + foreach (Type t in a.GetTypes()) + BindType(t); + } + + static void BindType(Type t) + { + ResourceBindingAttribute a = Reflect.GetAttribute(t); + if (a == null) + return; + + ConstructorInfo ctor = t.GetConstructor(new Type[] { typeof(Stream) }); + if (ctor == null) + return; + + Converter loader = delegate(Stream s) + { + return (IResource)ctor.Invoke(new object[] { s }); + }; + + foreach (string extension in a.Extensions) + loaders.Add(extension, loader); + } + + public static Converter GetLoader(string extension) + { + Converter result; + loaders.TryGetValue(extension.ToLowerInvariant(), out result); + return result; + } + } +} diff --git a/OpenRa.sln b/OpenRa.sln index 96f2c5c7a9..e3e91cdf7a 100644 --- a/OpenRa.sln +++ b/OpenRa.sln @@ -9,6 +9,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ShpViewer", "ShpViewer\ShpV EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenRa.FileFormats", "OpenRa.FileFormats\OpenRa.FileFormats.csproj", "{BDAEAB25-991E-46A7-AF1E-4F0E03358DAA}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenRa.Core", "OpenRa.Core\OpenRa.Core.csproj", "{1B60782F-B2DD-43F1-B51D-B798485F317C}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -59,6 +61,16 @@ Global {BDAEAB25-991E-46A7-AF1E-4F0E03358DAA}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU {BDAEAB25-991E-46A7-AF1E-4F0E03358DAA}.Release|Mixed Platforms.Build.0 = Release|Any CPU {BDAEAB25-991E-46A7-AF1E-4F0E03358DAA}.Release|Win32.ActiveCfg = Release|Any CPU + {1B60782F-B2DD-43F1-B51D-B798485F317C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1B60782F-B2DD-43F1-B51D-B798485F317C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1B60782F-B2DD-43F1-B51D-B798485F317C}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {1B60782F-B2DD-43F1-B51D-B798485F317C}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {1B60782F-B2DD-43F1-B51D-B798485F317C}.Debug|Win32.ActiveCfg = Debug|Any CPU + {1B60782F-B2DD-43F1-B51D-B798485F317C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1B60782F-B2DD-43F1-B51D-B798485F317C}.Release|Any CPU.Build.0 = Release|Any CPU + {1B60782F-B2DD-43F1-B51D-B798485F317C}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {1B60782F-B2DD-43F1-B51D-B798485F317C}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {1B60782F-B2DD-43F1-B51D-B798485F317C}.Release|Win32.ActiveCfg = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE