Skip to content

Commit

Permalink
Started investigating adding support for EverOasis.
Browse files Browse the repository at this point in the history
  • Loading branch information
MeltyPlayer committed Jan 13, 2024
1 parent 5f638a6 commit 78a8545
Show file tree
Hide file tree
Showing 22 changed files with 369 additions and 129 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using System;
using System.Collections;
using System.Collections.Generic;

namespace fin.data.dictionaries {
public class CaseInvariantStringDictionary<T> : IFinDictionary<string, T> {
private readonly Dictionary<string, T> impl_ = new(StringComparer.InvariantCultureIgnoreCase);

public void Clear() => this.impl_.Clear();

public int Count => this.impl_.Count;
public IEnumerable<string> Keys => this.impl_.Keys;
public IEnumerable<T> Values => this.impl_.Values;
public bool ContainsKey(string key) => this.impl_.ContainsKey(key);

public bool TryGetValue(string key, out T value) => this.impl_.TryGetValue(key, out value);

public T this[string key] {
get => this.impl_[key];
set => this.impl_[key] = value;
}

IEnumerator IEnumerable.GetEnumerator() => this.GetEnumerator();

public IEnumerator<(string Key, T Value)> GetEnumerator() {
foreach (var (key, value) in this.impl_) {
yield return (key, value);
}
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ namespace fin.data.dictionaries {
/// <summary>
/// A dictionary that accepts null keys.
/// </summary>
public class NullFriendlyDictionary<TKey, TValue>
: IFinDictionary<TKey, TValue> {
public class NullFriendlyDictionary<TKey, TValue> : IFinDictionary<TKey, TValue> {
private readonly ConcurrentDictionary<TKey, TValue> impl_ = new();

private bool hasNull_;
Expand Down
32 changes: 32 additions & 0 deletions FinModelUtility/Fin/Fin/src/data/dictionaries/SimpleDictionary.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;

namespace fin.data.dictionaries {
public class SimpleDictionary<TKey, TValue>(IDictionary<TKey, TValue>? impl = null)
: IFinDictionary<TKey, TValue> {
private readonly IDictionary<TKey, TValue> impl_ = impl ?? new ConcurrentDictionary<TKey, TValue>();

public void Clear() => this.impl_.Clear();

public int Count => this.impl_.Count;
public IEnumerable<TKey> Keys => this.impl_.Keys;
public IEnumerable<TValue> Values => this.impl_.Values;
public bool ContainsKey(TKey key) => this.impl_.ContainsKey(key);

public bool TryGetValue(TKey key, out TValue value) => this.impl_.TryGetValue(key, out value);

public TValue this[TKey key] {
get => this.impl_[key];
set => this.impl_[key] = value;
}
IEnumerator IEnumerable.GetEnumerator() => this.GetEnumerator();

public IEnumerator<(TKey Key, TValue Value)> GetEnumerator() {
foreach (var (key, value) in this.impl_) {
yield return (key, value);
}
}

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;

using fin.data.dictionaries;

namespace fin.data.lazy {
public class LazyCaseInvariantStringDictionary<TValue> : ILazyDictionary<string, TValue> {
private readonly ILazyDictionary<string, TValue> impl_;

public LazyCaseInvariantStringDictionary(Func<string, TValue> handler) {
this.impl_ = new LazyDictionary<string, TValue>(
handler,
new SimpleDictionary<string, TValue>(new ConcurrentDictionary<string, TValue>(StringComparer.OrdinalIgnoreCase)));
}

public LazyCaseInvariantStringDictionary(Func<LazyDictionary<string, TValue>, string, TValue> handler) {
this.impl_ = new LazyDictionary<string, TValue>(
handler,
new SimpleDictionary<string, TValue>(new ConcurrentDictionary<string, TValue>(StringComparer.OrdinalIgnoreCase)));
}

public void Clear() => this.impl_.Clear();

IEnumerator IEnumerable.GetEnumerator() => this.GetEnumerator();
public IEnumerator<(string Key, TValue Value)> GetEnumerator() => this.impl_.GetEnumerator();

public int Count => this.impl_.Count;
public IEnumerable<string> Keys => this.impl_.Keys;
public IEnumerable<TValue> Values => this.impl_.Values;

public bool ContainsKey(string key) => this.impl_.ContainsKey(key);
public bool TryGetValue(string key, out TValue value) => this.impl_.TryGetValue(key, out value);

public TValue this[string key] {
get => this.impl_[key];
set => this.impl_[key] = value;
}
}
}
14 changes: 8 additions & 6 deletions FinModelUtility/Fin/Fin/src/data/lazy/LazyDictionary.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,19 @@ namespace fin.data.lazy {
/// Dictionary implementation that lazily populates its entries when
/// accessed.
/// </summary>
public class LazyDictionary<TKey, TValue> : ILazyDictionary<TKey, TValue> {
private readonly NullFriendlyDictionary<TKey, TValue> impl_ = new();
public class LazyDictionary<TKey, TValue>
: ILazyDictionary<TKey, TValue> {
private readonly IFinDictionary<TKey, TValue> impl_;
private readonly Func<TKey, TValue> handler_;

public LazyDictionary(Func<TKey, TValue> handler) {
public LazyDictionary(Func<TKey, TValue> handler, IFinDictionary<TKey, TValue>? impl = null) {
this.handler_ = handler;
this.impl_ = impl ?? new NullFriendlyDictionary<TKey, TValue>();
}

public LazyDictionary(
Func<LazyDictionary<TKey, TValue>, TKey, TValue> handler) {
this.handler_ = (TKey key) => handler(this, key);
public LazyDictionary(Func<LazyDictionary<TKey, TValue>, TKey, TValue> handler, IFinDictionary<TKey, TValue>? impl = null) {
this.handler_ = key => handler(this, key);
this.impl_ = impl ?? new NullFriendlyDictionary<TKey, TValue>();
}

public int Count => this.impl_.Count;
Expand Down
6 changes: 3 additions & 3 deletions FinModelUtility/Fin/Fin/src/io/FileHierarchy.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Collections;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO.Abstractions;
using System.Linq;
Expand Down Expand Up @@ -286,11 +287,10 @@ public bool TryToGetExistingFileWithFileType(

public IEnumerable<IFileHierarchyFile> GetFilesWithNameRecursive(
string name) {
name = name.ToLower();
var stack = new FinStack<IFileHierarchyDirectory>(this);
while (stack.TryPop(out var next)) {
var match = next.GetExistingFiles()
.FirstOrDefault(file => file.Name.ToLower() == name);
.FirstOrDefault(file => file.Name.Equals(name, StringComparison.OrdinalIgnoreCase));
if (match != null) {
yield return match;
}
Expand Down
12 changes: 4 additions & 8 deletions FinModelUtility/Fin/Fin/src/io/FileLinq.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Linq;

namespace fin.io {
Expand All @@ -13,18 +14,13 @@ public static IEnumerable<TFile> WithName<TFile>(
public static IEnumerable<TFile> WithFileType<TFile>(
this IEnumerable<TFile> files,
string fileType) where TFile : IReadOnlyTreeFile {
fileType = fileType.ToLower();
return files.Where(file => file.FileType.ToLower() == fileType);
return files.Where(file => file.FileType.Equals(fileType, StringComparison.OrdinalIgnoreCase));
}

public static IEnumerable<TFile> WithFileTypes<TFile>(
this IEnumerable<TFile> files,
params string[] fileTypes) where TFile : IReadOnlyTreeFile {
for (var i = 0; i < fileTypes.Length; ++i) {
fileTypes[i] = fileTypes[i].ToLower();
}

return files.Where(file => fileTypes.Contains(file.FileType.ToLower()));
return files.Where(file => fileTypes.Any(fileType => fileType.Equals(file.FileType, StringComparison.OrdinalIgnoreCase)));
}
}
}
25 changes: 22 additions & 3 deletions FinModelUtility/Fin/Fin/src/io/archive/ArchiveInterfaces.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,35 @@ public enum ArchiveExtractionResult {
NEWLY_EXTRACTED,
}

public interface IArchiveExtractor {
delegate void ArchiveFileProcessor(string archiveFileName, ref string relativeFileName, out bool relativeToRoot);
}

public interface IArchiveExtractor<TArchiveContentFile>
where TArchiveContentFile : IArchiveContentFile {
ArchiveExtractionResult TryToExtractIntoNewDirectory<TArchiveReader>(
IReadOnlyGenericFile archive,
ISystemDirectory newDirectory)
IReadOnlyTreeFile archive,
ISystemDirectory targetDirectory)
where TArchiveReader : IArchiveReader<TArchiveContentFile>, new();

ArchiveExtractionResult TryToExtractIntoNewDirectory<TArchiveReader>(
Stream archive,
ISystemDirectory targetDirectory)
where TArchiveReader : IArchiveReader<TArchiveContentFile>, new();

ArchiveExtractionResult TryToExtractIntoNewDirectory<TArchiveReader>(
IReadOnlyTreeFile archive,
ISystemDirectory rootDirectory,
ISystemDirectory targetDirectory,
IArchiveExtractor.ArchiveFileProcessor? archiveFileNameProcessor = null)
where TArchiveReader : IArchiveReader<TArchiveContentFile>, new();

ArchiveExtractionResult TryToExtractIntoNewDirectory<TArchiveReader>(
string archiveName,
Stream archive,
ISystemDirectory newDirectory)
ISystemDirectory rootDirectory,
ISystemDirectory targetDirectory,
IArchiveExtractor.ArchiveFileProcessor? archiveFileNameProcessor = null)
where TArchiveReader : IArchiveReader<TArchiveContentFile>, new();
}
}
54 changes: 39 additions & 15 deletions FinModelUtility/Fin/Fin/src/io/archive/SubArchive.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,41 +49,58 @@ public void CopyContentFileInto(SubArchiveContentFile archiveContentFile,
}

public class SubArchiveExtractor : IArchiveExtractor<SubArchiveContentFile> {
public ArchiveExtractionResult TryToExtractIntoNewDirectory<TArchiveReader>(IReadOnlyTreeFile archive,
ISystemDirectory targetDirectory) where TArchiveReader : IArchiveReader<SubArchiveContentFile>, new()
=> this.TryToExtractIntoNewDirectory<TArchiveReader>(archive, null, targetDirectory);

public ArchiveExtractionResult TryToExtractIntoNewDirectory<TArchiveReader>(Stream archive, ISystemDirectory targetDirectory) where TArchiveReader : IArchiveReader<SubArchiveContentFile>, new()
=> this.TryToExtractIntoNewDirectory<TArchiveReader>(null, archive, null, targetDirectory);

public ArchiveExtractionResult TryToExtractIntoNewDirectory<TArchiveReader>(
IReadOnlyGenericFile archive,
ISystemDirectory systemDirectory)
IReadOnlyTreeFile archive,
ISystemDirectory rootDirectory,
ISystemDirectory targetDirectory,
IArchiveExtractor.ArchiveFileProcessor? archiveFileNameProcessor = null)
where TArchiveReader : IArchiveReader<SubArchiveContentFile>, new() {
if (systemDirectory is { Exists: true, IsEmpty: false }) {
if (targetDirectory is { Exists: true, IsEmpty: false }) {
return ArchiveExtractionResult.ALREADY_EXISTS;
}

systemDirectory.Create();

using var fs = archive.OpenRead();
return this.TryToExtractIntoExistingDirectory_<TArchiveReader>(
return this.TryToExtractIntoNewDirectory<TArchiveReader>(
archive.NameWithoutExtension,
fs,
systemDirectory);
rootDirectory,
targetDirectory,
archiveFileNameProcessor);
}

public ArchiveExtractionResult TryToExtractIntoNewDirectory<TArchiveReader>(
string archiveName,
Stream archive,
ISystemDirectory systemDirectory)
ISystemDirectory rootDirectory,
ISystemDirectory targetDirectory,
IArchiveExtractor.ArchiveFileProcessor? archiveFileNameProcessor = null)
where TArchiveReader : IArchiveReader<SubArchiveContentFile>, new() {
if (systemDirectory.Exists) {
if (targetDirectory is { Exists: true, IsEmpty: false }) {
return ArchiveExtractionResult.ALREADY_EXISTS;
}

systemDirectory.Create();

return this.TryToExtractIntoExistingDirectory_<TArchiveReader>(
archiveName,
archive,
systemDirectory);
rootDirectory,
targetDirectory,
archiveFileNameProcessor);
}

private ArchiveExtractionResult TryToExtractIntoExistingDirectory_<
TArchiveReader>(
string archiveName,
Stream archive,
ISystemDirectory systemDirectory)
ISystemDirectory rootDirectory,
ISystemDirectory targetDirectory,
IArchiveExtractor.ArchiveFileProcessor? archiveFileNameProcessor = null)
where TArchiveReader : IArchiveReader<SubArchiveContentFile>, new() {
var archiveReader = new TArchiveReader();
if (!archiveReader.IsValidArchive(archive)) {
Expand All @@ -96,8 +113,15 @@ private ArchiveExtractionResult TryToExtractIntoExistingDirectory_<

var createdDirectories = new HashSet<string>();
foreach (var archiveContentFile in archiveContentFiles) {
var dstFile = new FinFile(Path.Join(systemDirectory.FullPath,
archiveContentFile.RelativeName));
var relativeToRoot = false;

var relativeName = archiveContentFile.RelativeName;
if (archiveFileNameProcessor != null) {
archiveFileNameProcessor(archiveName, ref relativeName, out relativeToRoot);
}

var dstDir = relativeToRoot ? rootDirectory : targetDirectory;
var dstFile = new FinFile(Path.Join(dstDir.FullPath, relativeName));

var dstDirectory = dstFile.GetParentFullPath()!;
if (createdDirectories.Add(dstDirectory)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public unsafe IModel ImportModel(AssimpModelFileBundle modelFileBundle) {
var assScene = ctx.ImportFile(mainFile.FullPath);

// Adds materials
var lazyFinSatelliteImages = new LazyDictionary<string, IImage>(
var lazyFinSatelliteImages = new LazyCaseInvariantStringDictionary<IImage>(
path => mainFile.AssertGetParent()
.TryToGetExistingFile(path, out var imageFile)
? FinImage.FromFile(imageFile)
Expand Down
Loading

0 comments on commit 78a8545

Please sign in to comment.