diff --git a/Directory.Build.props b/Directory.Build.props index 5068e67a..ffbcc1df 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -14,6 +14,11 @@ $(DefineConstants);USE_BITARRAY + + $(UseDefines) + $(DefineConstants);USE_ARRAY + + $(UseDefines) $(DefineConstants);LOCATION_AS_STRUCT diff --git a/src/FactorioTools/CollectionExtensions.cs b/src/FactorioTools/CollectionExtensions.cs index 5523321e..7c3eeaf0 100644 --- a/src/FactorioTools/CollectionExtensions.cs +++ b/src/FactorioTools/CollectionExtensions.cs @@ -27,10 +27,10 @@ public static ILocationDictionary ToDictionary( return dictionary; } - public static List Distinct(this IReadOnlyCollection locations, Context context) + public static IItemList Distinct(this IReadOnlyCollection locations, Context context) { var set = context.GetLocationSet(locations.Count); - var output = new List(locations.Count); + var output = Collection.List(locations.Count); foreach (var location in locations) { if (set.Add(location)) @@ -57,9 +57,9 @@ public static ILocationSet ToReadOnlySet(this IReadOnlyCollection loca } #if ENABLE_VISUALIZER - public static List ToDelaunatorPoints(this ILocationSet set) + public static IItemList ToDelaunatorPoints(this ILocationSet set) { - var points = new List(); + var points = Collection.List(); foreach (var item in set.EnumerateItems()) { points.Add(new DelaunatorSharp.Point(item.X, item.Y)); @@ -68,9 +68,9 @@ public static ILocationSet ToReadOnlySet(this IReadOnlyCollection loca return points; } - public static List ToDelaunatorPoints(this ILocationDictionary dictionary) + public static IItemList ToDelaunatorPoints(this ILocationDictionary dictionary) { - var points = new List(); + var points = Collection.List(); foreach (var item in dictionary.Keys) { points.Add(new DelaunatorSharp.Point(item.X, item.Y)); @@ -186,9 +186,9 @@ public static ILocationSet ToReadOnlySet(this IReadOnlyCollection loca return min; } - public static List ToList(this IReadOnlyCollection source) + public static IItemList ToList(this IReadOnlyCollection source) { - var output = new List(source.Count); + var output = Collection.List(source.Count); output.AddRange(source); return output; } diff --git a/src/FactorioTools/OilField/Containers/DictionaryList.cs b/src/FactorioTools/OilField/Containers/DictionaryList.cs new file mode 100644 index 00000000..bba42c53 --- /dev/null +++ b/src/FactorioTools/OilField/Containers/DictionaryList.cs @@ -0,0 +1,126 @@ +using System; +using System.Collections; +using System.Collections.Generic; + +namespace Knapcode.FactorioTools.OilField; + +public static class Collection +{ + public static IItemList List() + { +#if USE_ARRAY + return new StandardList(); +#else + return new DictionaryList(); +#endif + } + + public static IItemList List(int capacity) + { +#if USE_ARRAY + return new StandardList(capacity); +#else + return new DictionaryList(capacity); +#endif + } +} + +public interface IItemList +{ + T this[int index] { get; set; } + int Count { get; } + + void Add(T item); + void AddRange(IReadOnlyCollection collection); + void Sort(Comparer comparer); +} + +public class StandardList : IItemList +{ + private readonly List _list; + + public StandardList() + { + _list = new List(); + } + + public StandardList(int capacity) + { + _list = new List(capacity); + } + + public T this[int index] + { + get => _list[index]; + set => _list[index] = value; + } + + public int Count => _list.Count; + + public void Add(T item) + { + _list.Add(item); + } + + public void AddRange(IReadOnlyCollection collection) + { + _list.AddRange(collection); + } + + public void Sort(Comparer comparer) + { + _list.Sort(comparer); + } +} + +public class DictionaryList : IItemList +{ + private readonly Dictionary _dictionary; + + public DictionaryList() + { + _dictionary = new Dictionary(); + } + + public DictionaryList(int capacity) + { + _dictionary = new Dictionary(capacity); + } + + public T this[int index] + { + get + { + if (index >= _dictionary.Count) + { + throw new IndexOutOfRangeException(); + } + + return _dictionary[index]; + } + set + { + if (index >= _dictionary.Count) + { + throw new IndexOutOfRangeException(); + } + + _dictionary[index] = value; + } + } + + public int Count => _dictionary.Count; + + public void Add(T item) + { + _dictionary.Add(_dictionary.Count, item); + } + + public void AddRange(IReadOnlyCollection collection) + { + foreach (var item in collection) + { + _dictionary.Add(_dictionary.Count, item); + } + } +} diff --git a/src/FactorioTools/OilField/Helpers.cs b/src/FactorioTools/OilField/Helpers.cs index fddb8d2a..ffa283d0 100644 --- a/src/FactorioTools/OilField/Helpers.cs +++ b/src/FactorioTools/OilField/Helpers.cs @@ -72,14 +72,14 @@ public static void PopulateCenterToTerminals(ILocationDictionary> GetLocationToTerminals(Context context, ILocationDictionary> centerToTerminals) + public static ILocationDictionary> GetLocationToTerminals(Context context, ILocationDictionary> centerToTerminals) { - var locationToTerminals = context.GetLocationDictionary>(); + var locationToTerminals = context.GetLocationDictionary>(); PopulateLocationToTerminals(locationToTerminals, centerToTerminals); return locationToTerminals; } - public static void PopulateLocationToTerminals(ILocationDictionary> locationToTerminals, ILocationDictionary> centerToTerminals) + public static void PopulateLocationToTerminals(ILocationDictionary> locationToTerminals, ILocationDictionary> centerToTerminals) { foreach (var terminals in centerToTerminals.Values) { @@ -87,7 +87,7 @@ public static void PopulateLocationToTerminals(ILocationDictionary(2); + list = Collection.List(2); locationToTerminals.Add(terminal.Terminal, list); } @@ -98,7 +98,7 @@ public static void PopulateLocationToTerminals(ILocationDictionary CandidateToInfo, CountedBitArray CoveredEntities, ILocationDictionary Providers) GetBeaconCandidateToCovered( Context context, - List recipients, + IItemList recipients, ICandidateFactory candidateFactory, bool removeUnused) where TInfo : CandidateInfo @@ -118,7 +118,7 @@ public static (ILocationDictionary CandidateToInfo, CountedBitArray Cover public static (ILocationDictionary CandidateToInfo, CountedBitArray CoveredEntities, ILocationDictionary Providers) GetElectricPoleCandidateToCovered( Context context, - List recipients, + IItemList recipients, ICandidateFactory candidateFactory, bool removeUnused) where TInfo : CandidateInfo @@ -138,7 +138,7 @@ public static (ILocationDictionary CandidateToInfo, CountedBitArray Cover private static (ILocationDictionary CandidateToInfo, CountedBitArray CoveredEntities, ILocationDictionary Providers) GetCandidateToCovered( Context context, - List recipients, + IItemList recipients, ICandidateFactory candidateFactory, int providerWidth, int providerHeight, @@ -443,7 +443,7 @@ public static bool DoesProviderFit( return true; } - public static double GetEntityDistance(List poweredEntities, Location candidate, CountedBitArray covered) + public static double GetEntityDistance(IItemList poweredEntities, Location candidate, CountedBitArray covered) { double sum = 0; for (var i = 0; i < poweredEntities.Count; i++) @@ -1119,7 +1119,7 @@ public static List MakeStraightLine(Location a, Location b) throw new ArgumentException("The two points must be one the same line either horizontally or vertically."); } - public static List PointsToLines(IReadOnlyCollection nodes) + public static IItemList PointsToLines(IReadOnlyCollection nodes) { return PointsToLines(nodes.ToList(), sort: true); } @@ -1127,7 +1127,7 @@ public static List PointsToLines(IReadOnlyCollection nodes) /// /// Source: https://github.com/teoxoy/factorio-blueprint-editor/blob/21ab873d8316a41b9a05c719697d461d3ede095d/packages/editor/src/core/generators/util.ts#L62 /// - public static List PointsToLines(IReadOnlyList nodes, bool sort) + public static IItemList PointsToLines(IReadOnlyList nodes, bool sort) { IReadOnlyList filteredNodes; if (sort) diff --git a/src/FactorioTools/OilField/Steps/AddElectricPoles.cs b/src/FactorioTools/OilField/Steps/AddElectricPoles.cs index b5149098..58b8d5e0 100644 --- a/src/FactorioTools/OilField/Steps/AddElectricPoles.cs +++ b/src/FactorioTools/OilField/Steps/AddElectricPoles.cs @@ -312,9 +312,9 @@ public ElectricPoleCandidateInfo Create(CountedBitArray covered) } } - private static (List? ElectricPoleList, CountedBitArray CoveredEntities) AddElectricPolesAroundEntities( + private static (IItemList? ElectricPoleList, CountedBitArray CoveredEntities) AddElectricPolesAroundEntities( Context context, - List poweredEntities, + IItemList poweredEntities, CountedBitArray? entitiesToPowerFirst) { (var allCandidateToInfo, var coveredEntities, var electricPoles2) = GetElectricPoleCandidateToCovered( @@ -472,8 +472,8 @@ private static void PopulateCandidateToInfo( Context context, ILocationDictionary candidateToInfo, CountedBitArray? entitiesToPowerFirst, - List poweredEntities, - List electricPoleList) + IItemList poweredEntities, + IItemList electricPoleList) { foreach ((var candidate, var info) in candidateToInfo.EnumeratePairs()) {