Unstatic GlobalFileSystem and rename it to FileSystem

Add a ModFiles field on ModData and move all access to the file system to go through that.
This commit is contained in:
Pavel Penev
2015-10-09 13:55:08 +03:00
parent 5684bcec1c
commit 1b88d24cfa
46 changed files with 154 additions and 172 deletions

View File

@@ -39,14 +39,14 @@ namespace OpenRA.FileSystem
// Build the index and dispose the stream, it is no longer needed after this
List<IdxEntry> entries;
using (var indexStream = GlobalFileSystem.Open(indexFilename))
using (var indexStream = Game.ModData.ModFiles.Open(indexFilename))
entries = new IdxReader(indexStream).Entries;
index = entries.ToDictionaryWithConflictLog(x => x.Hash,
"{0} (bag format)".F(filename),
null, x => "(offs={0}, len={1})".F(x.Offset, x.Length));
s = GlobalFileSystem.Open(filename);
s = Game.ModData.ModFiles.Open(filename);
}
public int Priority { get { return 1000 + bagFilePriority; } }
@@ -159,9 +159,9 @@ namespace OpenRA.FileSystem
public IEnumerable<string> AllFileNames()
{
var lookup = new Dictionary<uint, string>();
if (GlobalFileSystem.Exists("global mix database.dat"))
if (Game.ModData.ModFiles.Exists("global mix database.dat"))
{
var db = new XccGlobalDatabase(GlobalFileSystem.Open("global mix database.dat"));
var db = new XccGlobalDatabase(Game.ModData.ModFiles.Open("global mix database.dat"));
foreach (var e in db.Entries)
{
var hash = IdxEntry.HashFilename(e, PackageHashType.CRC32);
@@ -175,7 +175,7 @@ namespace OpenRA.FileSystem
public void Write(Dictionary<string, byte[]> contents)
{
GlobalFileSystem.Unmount(this);
Game.ModData.ModFiles.Unmount(this);
throw new NotImplementedException("Updating bag files unsupported");
}

View File

@@ -27,7 +27,7 @@ namespace OpenRA.FileSystem
Name = filename;
Priority = priority;
s = GlobalFileSystem.Open(filename);
s = Game.ModData.ModFiles.Open(filename);
try
{
if (s.ReadASCII(4) != "BIGF")

View File

@@ -29,7 +29,7 @@ namespace OpenRA.FileSystem
this.filename = filename;
this.priority = priority;
s = GlobalFileSystem.Open(filename);
s = Game.ModData.ModFiles.Open(filename);
try
{
filenames = new List<string>();

View File

@@ -17,34 +17,16 @@ using OpenRA.Primitives;
namespace OpenRA.FileSystem
{
public static class GlobalFileSystem
public class FileSystem
{
public static List<IFolder> MountedFolders = new List<IFolder>();
static Cache<uint, List<IFolder>> classicHashIndex = new Cache<uint, List<IFolder>>(_ => new List<IFolder>());
static Cache<uint, List<IFolder>> crcHashIndex = new Cache<uint, List<IFolder>>(_ => new List<IFolder>());
public readonly List<string> FolderPaths = new List<string>();
public readonly List<IFolder> MountedFolders = new List<IFolder>();
public static List<string> FolderPaths = new List<string>();
static readonly Dictionary<string, Assembly> AssemblyCache = new Dictionary<string, Assembly>();
static void MountInner(IFolder folder)
{
MountedFolders.Add(folder);
foreach (var hash in folder.ClassicHashes())
{
var l = classicHashIndex[hash];
if (!l.Contains(folder))
l.Add(folder);
}
foreach (var hash in folder.CrcHashes())
{
var l = crcHashIndex[hash];
if (!l.Contains(folder))
l.Add(folder);
}
}
static int order = 0;
int order;
Cache<uint, List<IFolder>> crcHashIndex = new Cache<uint, List<IFolder>>(_ => new List<IFolder>());
Cache<uint, List<IFolder>> classicHashIndex = new Cache<uint, List<IFolder>>(_ => new List<IFolder>());
public static IFolder CreatePackage(string filename, int order, Dictionary<string, byte[]> content)
{
@@ -99,7 +81,13 @@ namespace OpenRA.FileSystem
return new Folder(filename, order);
}
public static void Mount(string name, string annotation = null)
public void Mount(IFolder mount)
{
if (!MountedFolders.Contains(mount))
MountedFolders.Add(mount);
}
public void Mount(string name, string annotation = null)
{
var optional = name.StartsWith("~");
if (optional)
@@ -117,7 +105,34 @@ namespace OpenRA.FileSystem
a();
}
public static void UnmountAll()
void MountInner(IFolder folder)
{
MountedFolders.Add(folder);
foreach (var hash in folder.ClassicHashes())
{
var folderList = classicHashIndex[hash];
if (!folderList.Contains(folder))
folderList.Add(folder);
}
foreach (var hash in folder.CrcHashes())
{
var folderList = crcHashIndex[hash];
if (!folderList.Contains(folder))
folderList.Add(folder);
}
}
public bool Unmount(IFolder mount)
{
if (MountedFolders.Contains(mount))
mount.Dispose();
return MountedFolders.RemoveAll(f => f == mount) > 0;
}
public void UnmountAll()
{
foreach (var folder in MountedFolders)
folder.Dispose();
@@ -128,20 +143,7 @@ namespace OpenRA.FileSystem
crcHashIndex = new Cache<uint, List<IFolder>>(_ => new List<IFolder>());
}
public static bool Unmount(IFolder mount)
{
if (MountedFolders.Contains(mount))
mount.Dispose();
return MountedFolders.RemoveAll(f => f == mount) > 0;
}
public static void Mount(IFolder mount)
{
if (!MountedFolders.Contains(mount)) MountedFolders.Add(mount);
}
public static void LoadFromManifest(Manifest manifest)
public void LoadFromManifest(Manifest manifest)
{
UnmountAll();
foreach (var dir in manifest.Folders)
@@ -151,7 +153,7 @@ namespace OpenRA.FileSystem
Mount(pkg.Key, pkg.Value);
}
static Stream GetFromCache(PackageHashType type, string filename)
Stream GetFromCache(PackageHashType type, string filename)
{
var index = type == PackageHashType.CRC32 ? crcHashIndex : classicHashIndex;
var folder = index[PackageEntry.HashFilename(filename, type)]
@@ -164,7 +166,7 @@ namespace OpenRA.FileSystem
return null;
}
public static Stream Open(string filename)
public Stream Open(string filename)
{
Stream s;
if (!TryOpen(filename, out s))
@@ -173,7 +175,7 @@ namespace OpenRA.FileSystem
return s;
}
public static bool TryOpen(string name, out Stream s)
public bool TryOpen(string name, out Stream s)
{
var filename = name;
var foldername = string.Empty;
@@ -217,7 +219,7 @@ namespace OpenRA.FileSystem
return false;
}
public static bool Exists(string name)
public bool Exists(string name)
{
var explicitFolder = name.Contains(':') && !Directory.Exists(Path.GetDirectoryName(name));
if (explicitFolder)
@@ -231,8 +233,6 @@ namespace OpenRA.FileSystem
return MountedFolders.Any(f => f.Exists(name));
}
static Dictionary<string, Assembly> assemblyCache = new Dictionary<string, Assembly>();
public static Assembly ResolveAssembly(object sender, ResolveEventArgs e)
{
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
@@ -243,15 +243,15 @@ namespace OpenRA.FileSystem
var filename = frags[0] + ".dll";
Assembly a;
if (assemblyCache.TryGetValue(filename, out a))
if (AssemblyCache.TryGetValue(filename, out a))
return a;
if (Exists(filename))
using (var s = Open(filename))
if (Game.ModData.ModFiles.Exists(filename))
using (var s = Game.ModData.ModFiles.Open(filename))
{
var buf = s.ReadBytes((int)s.Length);
a = Assembly.Load(buf);
assemblyCache.Add(filename, a);
AssemblyCache.Add(filename, a);
return a;
}

View File

@@ -14,11 +14,10 @@ using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using ICSharpCode.SharpZipLib.Zip.Compression;
using ICSharpCode.SharpZipLib.Zip.Compression.Streams;
namespace OpenRA.FileSystem
{
public class InstallShieldCABExtractor : IDisposable, IFolder
public class InstallShieldCABExtractor : IFolder
{
const uint FileSplit = 0x1;
const uint FileObfuscated = 0x2;
@@ -277,7 +276,7 @@ namespace OpenRA.FileSystem
cabFile.Dispose();
++volumeNumber;
cabFile = GlobalFileSystem.Open("{0}{1}.cab".F(commonName, volumeNumber));
cabFile = Game.ModData.ModFiles.Open("{0}{1}.cab".F(commonName, volumeNumber));
if (cabFile.ReadUInt32() != 0x28635349)
throw new InvalidDataException("Not an Installshield CAB package");
@@ -341,7 +340,7 @@ namespace OpenRA.FileSystem
var fileGroupOffsets = new List<uint>();
this.priority = priority;
hdrFile = GlobalFileSystem.Open(hdrFilename);
hdrFile = Game.ModData.ModFiles.Open(hdrFilename);
// Strips archive number AND file extension
commonName = Regex.Replace(hdrFilename, @"\d*\.[^\.]*$", "");

View File

@@ -31,7 +31,7 @@ namespace OpenRA.FileSystem
filenames = new List<string>();
s = GlobalFileSystem.Open(filename);
s = Game.ModData.ModFiles.Open(filename);
try
{
// Parse package header

View File

@@ -57,7 +57,7 @@ namespace OpenRA.FileSystem
this.priority = priority;
this.type = type;
s = GlobalFileSystem.Open(filename);
s = Game.ModData.ModFiles.Open(filename);
try
{
// Detect format type
@@ -223,9 +223,9 @@ namespace OpenRA.FileSystem
}
}
if (GlobalFileSystem.Exists("global mix database.dat"))
if (Game.ModData.ModFiles.Exists("global mix database.dat"))
{
var db = new XccGlobalDatabase(GlobalFileSystem.Open("global mix database.dat"));
var db = new XccGlobalDatabase(Game.ModData.ModFiles.Open("global mix database.dat"));
foreach (var e in db.Entries)
{
var hash = PackageEntry.HashFilename(e, type);
@@ -249,7 +249,7 @@ namespace OpenRA.FileSystem
{
// Cannot modify existing mixfile - rename existing file and
// create a new one with original content plus modifications
GlobalFileSystem.Unmount(this);
Game.ModData.ModFiles.Unmount(this);
// TODO: Add existing data to the contents list
if (index.Count > 0)

View File

@@ -34,7 +34,7 @@ namespace OpenRA.FileSystem
this.priority = priority;
index = new Dictionary<string, Entry>();
stream = GlobalFileSystem.Open(filename);
stream = Game.ModData.ModFiles.Open(filename);
try
{
index = new Dictionary<string, Entry>();