Skip to content

Commit

Permalink
Start abstracting away List<T>
Browse files Browse the repository at this point in the history
  • Loading branch information
joelverhagen committed Jan 19, 2024
1 parent a77fc96 commit e8a1b5c
Show file tree
Hide file tree
Showing 5 changed files with 153 additions and 22 deletions.
5 changes: 5 additions & 0 deletions Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@
<DefineConstants Condition="$(UseBitArray) == 'true'">$(DefineConstants);USE_BITARRAY</DefineConstants>
</PropertyGroup>

<PropertyGroup>
<UseArray Condition="'$(UseArray)' == ''">$(UseDefines)</UseArray>
<DefineConstants Condition="$(UseArray) == 'true'">$(DefineConstants);USE_ARRAY</DefineConstants>
</PropertyGroup>

<PropertyGroup>
<LocationAsStruct Condition="'$(LocationAsStruct)' == ''">$(UseDefines)</LocationAsStruct>
<DefineConstants Condition="$(LocationAsStruct) == 'true'">$(DefineConstants);LOCATION_AS_STRUCT</DefineConstants>
Expand Down
16 changes: 8 additions & 8 deletions src/FactorioTools/CollectionExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@ public static ILocationDictionary<TValue> ToDictionary<TItem, TValue>(
return dictionary;
}

public static List<Location> Distinct(this IReadOnlyCollection<Location> locations, Context context)
public static IItemList<Location> Distinct(this IReadOnlyCollection<Location> locations, Context context)
{
var set = context.GetLocationSet(locations.Count);
var output = new List<Location>(locations.Count);
var output = Collection.List<Location>(locations.Count);
foreach (var location in locations)
{
if (set.Add(location))
Expand All @@ -57,9 +57,9 @@ public static ILocationSet ToReadOnlySet(this IReadOnlyCollection<Location> loca
}

#if ENABLE_VISUALIZER
public static List<DelaunatorSharp.IPoint> ToDelaunatorPoints(this ILocationSet set)
public static IItemList<DelaunatorSharp.IPoint> ToDelaunatorPoints(this ILocationSet set)
{
var points = new List<DelaunatorSharp.IPoint>();
var points = Collection.List<DelaunatorSharp.IPoint>();
foreach (var item in set.EnumerateItems())
{
points.Add(new DelaunatorSharp.Point(item.X, item.Y));
Expand All @@ -68,9 +68,9 @@ public static ILocationSet ToReadOnlySet(this IReadOnlyCollection<Location> loca
return points;
}

public static List<DelaunatorSharp.IPoint> ToDelaunatorPoints<T>(this ILocationDictionary<T> dictionary)
public static IItemList<DelaunatorSharp.IPoint> ToDelaunatorPoints<T>(this ILocationDictionary<T> dictionary)
{
var points = new List<DelaunatorSharp.IPoint>();
var points = Collection.List<DelaunatorSharp.IPoint>();
foreach (var item in dictionary.Keys)
{
points.Add(new DelaunatorSharp.Point(item.X, item.Y));
Expand Down Expand Up @@ -186,9 +186,9 @@ public static ILocationSet ToReadOnlySet(this IReadOnlyCollection<Location> loca
return min;
}

public static List<TSource> ToList<TSource>(this IReadOnlyCollection<TSource> source)
public static IItemList<TSource> ToList<TSource>(this IReadOnlyCollection<TSource> source)
{
var output = new List<TSource>(source.Count);
var output = Collection.List<TSource>(source.Count);
output.AddRange(source);
return output;
}
Expand Down
126 changes: 126 additions & 0 deletions src/FactorioTools/OilField/Containers/DictionaryList.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
using System;
using System.Collections;
using System.Collections.Generic;

namespace Knapcode.FactorioTools.OilField;

public static class Collection
{
public static IItemList<T> List<T>()
{
#if USE_ARRAY
return new StandardList<T>();
#else
return new DictionaryList<T>();
#endif
}

public static IItemList<T> List<T>(int capacity)
{
#if USE_ARRAY
return new StandardList<T>(capacity);
#else
return new DictionaryList<T>(capacity);
#endif
}
}

public interface IItemList<T>
{
T this[int index] { get; set; }
int Count { get; }

void Add(T item);
void AddRange(IReadOnlyCollection<T> collection);
void Sort(Comparer<T> comparer);
}

public class StandardList<T> : IItemList<T>
{
private readonly List<T> _list;

public StandardList()
{
_list = new List<T>();
}

public StandardList(int capacity)
{
_list = new List<T>(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<T> collection)
{
_list.AddRange(collection);
}

public void Sort(Comparer<T> comparer)
{
_list.Sort(comparer);
}
}

public class DictionaryList<T> : IItemList<T>

Check failure on line 76 in src/FactorioTools/OilField/Containers/DictionaryList.cs

View workflow job for this annotation

GitHub Actions / Build and deploy

'DictionaryList<T>' does not implement interface member 'IItemList<T>.Sort(Comparer<T>)'

Check failure on line 76 in src/FactorioTools/OilField/Containers/DictionaryList.cs

View workflow job for this annotation

GitHub Actions / Build and deploy

'DictionaryList<T>' does not implement interface member 'IItemList<T>.Sort(Comparer<T>)'
{
private readonly Dictionary<int, T> _dictionary;

public DictionaryList()
{
_dictionary = new Dictionary<int, T>();
}

public DictionaryList(int capacity)
{
_dictionary = new Dictionary<int, T>(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<T> collection)
{
foreach (var item in collection)
{
_dictionary.Add(_dictionary.Count, item);
}
}
}
20 changes: 10 additions & 10 deletions src/FactorioTools/OilField/Helpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,22 +72,22 @@ public static void PopulateCenterToTerminals(ILocationDictionary<List<TerminalLo
}
}

public static ILocationDictionary<List<TerminalLocation>> GetLocationToTerminals(Context context, ILocationDictionary<List<TerminalLocation>> centerToTerminals)
public static ILocationDictionary<IItemList<TerminalLocation>> GetLocationToTerminals(Context context, ILocationDictionary<List<TerminalLocation>> centerToTerminals)
{
var locationToTerminals = context.GetLocationDictionary<List<TerminalLocation>>();
var locationToTerminals = context.GetLocationDictionary<IItemList<TerminalLocation>>();
PopulateLocationToTerminals(locationToTerminals, centerToTerminals);
return locationToTerminals;
}

public static void PopulateLocationToTerminals(ILocationDictionary<List<TerminalLocation>> locationToTerminals, ILocationDictionary<List<TerminalLocation>> centerToTerminals)
public static void PopulateLocationToTerminals(ILocationDictionary<IItemList<TerminalLocation>> locationToTerminals, ILocationDictionary<List<TerminalLocation>> centerToTerminals)
{
foreach (var terminals in centerToTerminals.Values)
{
foreach (var terminal in terminals)
{
if (!locationToTerminals.TryGetValue(terminal.Terminal, out var list))
{
list = new List<TerminalLocation>(2);
list = Collection.List<TerminalLocation>(2);
locationToTerminals.Add(terminal.Terminal, list);
}

Expand All @@ -98,7 +98,7 @@ public static void PopulateLocationToTerminals(ILocationDictionary<List<Terminal

public static (ILocationDictionary<TInfo> CandidateToInfo, CountedBitArray CoveredEntities, ILocationDictionary<BeaconCenter> Providers) GetBeaconCandidateToCovered<TInfo>(
Context context,
List<ProviderRecipient> recipients,
IItemList<ProviderRecipient> recipients,
ICandidateFactory<TInfo> candidateFactory,
bool removeUnused)
where TInfo : CandidateInfo
Expand All @@ -118,7 +118,7 @@ public static (ILocationDictionary<TInfo> CandidateToInfo, CountedBitArray Cover

public static (ILocationDictionary<TInfo> CandidateToInfo, CountedBitArray CoveredEntities, ILocationDictionary<ElectricPoleCenter> Providers) GetElectricPoleCandidateToCovered<TInfo>(
Context context,
List<ProviderRecipient> recipients,
IItemList<ProviderRecipient> recipients,
ICandidateFactory<TInfo> candidateFactory,
bool removeUnused)
where TInfo : CandidateInfo
Expand All @@ -138,7 +138,7 @@ public static (ILocationDictionary<TInfo> CandidateToInfo, CountedBitArray Cover

private static (ILocationDictionary<TInfo> CandidateToInfo, CountedBitArray CoveredEntities, ILocationDictionary<TProvider> Providers) GetCandidateToCovered<TProvider, TInfo>(
Context context,
List<ProviderRecipient> recipients,
IItemList<ProviderRecipient> recipients,
ICandidateFactory<TInfo> candidateFactory,
int providerWidth,
int providerHeight,
Expand Down Expand Up @@ -443,7 +443,7 @@ public static bool DoesProviderFit(
return true;
}

public static double GetEntityDistance(List<ProviderRecipient> poweredEntities, Location candidate, CountedBitArray covered)
public static double GetEntityDistance(IItemList<ProviderRecipient> poweredEntities, Location candidate, CountedBitArray covered)
{
double sum = 0;
for (var i = 0; i < poweredEntities.Count; i++)
Expand Down Expand Up @@ -1119,15 +1119,15 @@ public static List<Location> MakeStraightLine(Location a, Location b)
throw new ArgumentException("The two points must be one the same line either horizontally or vertically.");
}

public static List<Endpoints> PointsToLines(IReadOnlyCollection<Location> nodes)
public static IItemList<Endpoints> PointsToLines(IReadOnlyCollection<Location> nodes)
{
return PointsToLines(nodes.ToList(), sort: true);
}

/// <summary>
/// Source: https://github.com/teoxoy/factorio-blueprint-editor/blob/21ab873d8316a41b9a05c719697d461d3ede095d/packages/editor/src/core/generators/util.ts#L62
/// </summary>
public static List<Endpoints> PointsToLines(IReadOnlyList<Location> nodes, bool sort)
public static IItemList<Endpoints> PointsToLines(IReadOnlyList<Location> nodes, bool sort)
{
IReadOnlyList<Location> filteredNodes;
if (sort)
Expand Down
8 changes: 4 additions & 4 deletions src/FactorioTools/OilField/Steps/AddElectricPoles.cs
Original file line number Diff line number Diff line change
Expand Up @@ -312,9 +312,9 @@ public ElectricPoleCandidateInfo Create(CountedBitArray covered)
}
}

private static (List<Location>? ElectricPoleList, CountedBitArray CoveredEntities) AddElectricPolesAroundEntities(
private static (IItemList<Location>? ElectricPoleList, CountedBitArray CoveredEntities) AddElectricPolesAroundEntities(
Context context,
List<ProviderRecipient> poweredEntities,
IItemList<ProviderRecipient> poweredEntities,
CountedBitArray? entitiesToPowerFirst)
{
(var allCandidateToInfo, var coveredEntities, var electricPoles2) = GetElectricPoleCandidateToCovered(
Expand Down Expand Up @@ -472,8 +472,8 @@ private static void PopulateCandidateToInfo(
Context context,
ILocationDictionary<ElectricPoleCandidateInfo> candidateToInfo,
CountedBitArray? entitiesToPowerFirst,
List<ProviderRecipient> poweredEntities,
List<Location> electricPoleList)
IItemList<ProviderRecipient> poweredEntities,
IItemList<Location> electricPoleList)
{
foreach ((var candidate, var info) in candidateToInfo.EnumeratePairs())
{
Expand Down

0 comments on commit e8a1b5c

Please sign in to comment.