diff --git a/src/FactorioTools/FactorioTools.csproj b/src/FactorioTools/FactorioTools.csproj index 8cf2a822..9834545b 100644 --- a/src/FactorioTools/FactorioTools.csproj +++ b/src/FactorioTools/FactorioTools.csproj @@ -23,6 +23,11 @@ $(DefineConstants);USE_STACKALLOC + + true + $(DefineConstants);RENT_NEIGHBORS + + $(UseDefines) false diff --git a/src/FactorioTools/OilField/Algorithms/AStar.cs b/src/FactorioTools/OilField/Algorithms/AStar.cs index 2f18e728..7547ddaa 100644 --- a/src/FactorioTools/OilField/Algorithms/AStar.cs +++ b/src/FactorioTools/OilField/Algorithms/AStar.cs @@ -73,10 +73,14 @@ public static AStarResult GetShortestPath(Context context, SquareGrid grid, Loca Location reachedGoal = Location.Invalid; bool success = false; +#if RENT_NEIGHBORS + Location[] neighbors = context.SharedInstances.GetNeighborArray(); +#else #if USE_STACKALLOC && LOCATION_AS_STRUCT Span neighbors = stackalloc Location[4]; #else Span neighbors = new Location[4]; +#endif #endif while (frontier.Count > 0) @@ -132,6 +136,10 @@ public static AStarResult GetShortestPath(Context context, SquareGrid grid, Loca } } +#if RENT_NEIGHBORS + context.SharedInstances.ReturnNeighborArray(neighbors); +#endif + if (!success) { outputList = null; diff --git a/src/FactorioTools/OilField/Algorithms/BreadthFirstFinder.cs b/src/FactorioTools/OilField/Algorithms/BreadthFirstFinder.cs index 50cc38f6..e0eb9e5b 100644 --- a/src/FactorioTools/OilField/Algorithms/BreadthFirstFinder.cs +++ b/src/FactorioTools/OilField/Algorithms/BreadthFirstFinder.cs @@ -20,10 +20,14 @@ public static class BreadthFirstFinder #endif toExplore.Enqueue(start); +#if RENT_NEIGHBORS + Location[] neighbors = context.SharedInstances.GetNeighborArray(); +#else #if USE_STACKALLOC && LOCATION_AS_STRUCT Span neighbors = stackalloc Location[4]; #else Span neighbors = new Location[4]; +#endif #endif while (toExplore.Count > 0) @@ -62,6 +66,10 @@ public static class BreadthFirstFinder } } +#if RENT_NEIGHBORS + context.SharedInstances.ReturnNeighborArray(neighbors); +#endif + return null; #if USE_SHARED_INSTANCES } diff --git a/src/FactorioTools/OilField/Algorithms/Dijkstras.cs b/src/FactorioTools/OilField/Algorithms/Dijkstras.cs index 6dbb9fd9..342edb9b 100644 --- a/src/FactorioTools/OilField/Algorithms/Dijkstras.cs +++ b/src/FactorioTools/OilField/Algorithms/Dijkstras.cs @@ -27,10 +27,14 @@ public static DijkstrasResult GetShortestPaths(Context context, SquareGrid grid, priorityQueue.Enqueue(start, 0); inQueue.Add(start); +#if RENT_NEIGHBORS + Location[] neighbors = context.SharedInstances.GetNeighborArray(); +#else #if USE_STACKALLOC && LOCATION_AS_STRUCT Span neighbors = stackalloc Location[4]; #else Span neighbors = new Location[4]; +#endif #endif while (priorityQueue.Count > 0) @@ -80,6 +84,11 @@ public static DijkstrasResult GetShortestPaths(Context context, SquareGrid grid, } } } + +#if RENT_NEIGHBORS + context.SharedInstances.ReturnNeighborArray(neighbors); +#endif + #if USE_SHARED_INSTANCES } finally diff --git a/src/FactorioTools/OilField/Models/SharedInstances.cs b/src/FactorioTools/OilField/Models/SharedInstances.cs index c5130693..0f430b3f 100644 --- a/src/FactorioTools/OilField/Models/SharedInstances.cs +++ b/src/FactorioTools/OilField/Models/SharedInstances.cs @@ -22,6 +22,25 @@ public SharedInstances(SquareGrid grid) #endif } +#if RENT_NEIGHBORS + private Queue _neighborArrays = new Queue(); + + public Location[] GetNeighborArray() + { + if (_neighborArrays.Count > 0) + { + return _neighborArrays.Dequeue(); + } + + return new Location[4]; + } + + public void ReturnNeighborArray(Location[] array) + { + _neighborArrays.Enqueue(array); + } +#endif + #if USE_SHARED_INSTANCES public Queue LocationQueue = new(); public Location[] LocationArray = Array.Empty(); diff --git a/src/FactorioTools/OilField/Steps/AddElectricPoles.cs b/src/FactorioTools/OilField/Steps/AddElectricPoles.cs index b5149098..1e4958fe 100644 --- a/src/FactorioTools/OilField/Steps/AddElectricPoles.cs +++ b/src/FactorioTools/OilField/Steps/AddElectricPoles.cs @@ -688,10 +688,14 @@ private static void AddSinglePoleForConnection(Context context, ILocationDiction candidates.Enqueue(idealPoint); attempted.Add(idealPoint); +#if RENT_NEIGHBORS + Location[] neighbors = context.SharedInstances.GetNeighborArray(); +#else #if USE_STACKALLOC && LOCATION_AS_STRUCT Span neighbors = stackalloc Location[4]; #else Span neighbors = new Location[4]; +#endif #endif while (candidates.Count > 0) diff --git a/src/FactorioTools/OilField/Steps/RotateOptimize.cs b/src/FactorioTools/OilField/Steps/RotateOptimize.cs index 9606afac..1cbcd41f 100644 --- a/src/FactorioTools/OilField/Steps/RotateOptimize.cs +++ b/src/FactorioTools/OilField/Steps/RotateOptimize.cs @@ -313,10 +313,14 @@ private static void ExplorePipes(ChildContext context, Location start, ILocation toExplore.Enqueue(start); pipes.Add(start); +#if RENT_NEIGHBORS + Location[] neighbors = context.ParentContext.SharedInstances.GetNeighborArray(); +#else #if USE_STACKALLOC && LOCATION_AS_STRUCT Span neighbors = stackalloc Location[4]; #else Span neighbors = new Location[4]; +#endif #endif while (toExplore.Count > 0) @@ -332,6 +336,11 @@ private static void ExplorePipes(ChildContext context, Location start, ILocation } } } + +#if RENT_NEIGHBORS + context.ParentContext.SharedInstances.ReturnNeighborArray(neighbors); +#endif + #if USE_SHARED_INSTANCES } finally @@ -354,10 +363,14 @@ private static ExploredPaths ExplorePaths(ChildContext context, Location start) var cameFrom = context.ParentContext.GetLocationDictionary(); cameFrom[start] = start; +#if RENT_NEIGHBORS + Location[] neighbors = context.ParentContext.SharedInstances.GetNeighborArray(); +#else #if USE_STACKALLOC && LOCATION_AS_STRUCT Span neighbors = stackalloc Location[4]; #else Span neighbors = new Location[4]; +#endif #endif var reachedGoals = new List(); @@ -385,6 +398,10 @@ private static ExploredPaths ExplorePaths(ChildContext context, Location start) } } +#if RENT_NEIGHBORS + context.ParentContext.SharedInstances.ReturnNeighborArray(neighbors); +#endif + return new ExploredPaths(start, cameFrom, reachedGoals); #if USE_SHARED_INSTANCES } diff --git a/src/lua/FactorioTools/AStar.lua b/src/lua/FactorioTools/AStar.lua index 3466ae8a..28b326d8 100644 --- a/src/lua/FactorioTools/AStar.lua +++ b/src/lua/FactorioTools/AStar.lua @@ -47,7 +47,9 @@ System.namespace("Knapcode.FactorioTools.OilField", function (namespace) local reachedGoal = KnapcodeOilField.Location.getInvalid() local success = false - local neighbors = SpanLocation.ctorArray(ArrayLocation(4)) + + local neighbors = context.SharedInstances:GetNeighborArray() + while #frontier > 0 do @@ -64,8 +66,8 @@ System.namespace("Knapcode.FactorioTools.OilField", function (namespace) local previous = cameFrom:get(current) local currentCost = costSoFar:get(current) - grid:GetNeighbors(neighbors, current) - for i = 0, neighbors:getLength() - 1 do + grid:GetNeighbors(SpanLocation.ctorArray(neighbors), current) + for i = 0, #neighbors - 1 do local continue repeat local next = neighbors:get(i) @@ -106,6 +108,10 @@ System.namespace("Knapcode.FactorioTools.OilField", function (namespace) end end + + context.SharedInstances:ReturnNeighborArray(neighbors) + + if not success then outputList = nil elseif outputList ~= nil then diff --git a/src/lua/FactorioTools/AddElectricPoles.lua b/src/lua/FactorioTools/AddElectricPoles.lua index 37fba3f8..d6da9cf8 100644 --- a/src/lua/FactorioTools/AddElectricPoles.lua +++ b/src/lua/FactorioTools/AddElectricPoles.lua @@ -5,7 +5,6 @@ local KnapcodeFactorioTools local KnapcodeOilField local KnapcodeAddElectricPoles local SpanLocation -local ArrayLocation local QueueLocation local ListILocationSet local QueueElectricPoleCenter @@ -18,7 +17,6 @@ System.import(function (out) KnapcodeOilField = Knapcode.FactorioTools.OilField KnapcodeAddElectricPoles = Knapcode.FactorioTools.OilField.AddElectricPoles SpanLocation = System.Span(KnapcodeOilField.Location) - ArrayLocation = System.Array(KnapcodeOilField.Location) QueueLocation = System.Queue(KnapcodeOilField.Location) ListILocationSet = System.List(KnapcodeOilField.ILocationSet) QueueElectricPoleCenter = System.Queue(KnapcodeOilField.ElectricPoleCenter) @@ -631,7 +629,9 @@ System.namespace("Knapcode.FactorioTools.OilField", function (namespace) candidates:Enqueue(idealPoint) attempted:Add(idealPoint) - local neighbors = SpanLocation.ctorArray(ArrayLocation(4)) + + local neighbors = context.SharedInstances:GetNeighborArray() + while #candidates > 0 do @@ -642,8 +642,8 @@ System.namespace("Knapcode.FactorioTools.OilField", function (namespace) break end - context.Grid:GetAdjacent(neighbors, candidate) - for i = 0, neighbors:getLength() - 1 do + context.Grid:GetAdjacent(SpanLocation.ctorArray(neighbors), candidate) + for i = 0, #neighbors - 1 do if neighbors:get(i).IsValid and AreElectricPolesConnected(idealLine:get(0), neighbors:get(i), context.Options) and attempted:Add(neighbors:get(i)) then candidates:Enqueue(neighbors:get(i)) end diff --git a/src/lua/FactorioTools/BreadthFirstFinder.lua b/src/lua/FactorioTools/BreadthFirstFinder.lua index 0451850c..0a102c41 100644 --- a/src/lua/FactorioTools/BreadthFirstFinder.lua +++ b/src/lua/FactorioTools/BreadthFirstFinder.lua @@ -3,13 +3,11 @@ local System = System local KnapcodeOilField local ListLocation local SpanLocation -local ArrayLocation local QueueLocation System.import(function (out) KnapcodeOilField = Knapcode.FactorioTools.OilField ListLocation = System.List(KnapcodeOilField.Location) SpanLocation = System.Span(KnapcodeOilField.Location) - ArrayLocation = System.Array(KnapcodeOilField.Location) QueueLocation = System.Queue(KnapcodeOilField.Location) end) System.namespace("Knapcode.FactorioTools.OilField", function (namespace) @@ -21,7 +19,9 @@ System.namespace("Knapcode.FactorioTools.OilField", function (namespace) local visited = context:GetLocationSet1() toExplore:Enqueue(start) - local neighbors = SpanLocation.ctorArray(ArrayLocation(4)) + + local neighbors = context.SharedInstances:GetNeighborArray() + while #toExplore > 0 do @@ -50,8 +50,8 @@ System.namespace("Knapcode.FactorioTools.OilField", function (namespace) return output end - context.Grid:GetNeighbors(neighbors, current) - for i = 0, neighbors:getLength() - 1 do + context.Grid:GetNeighbors(SpanLocation.ctorArray(neighbors), current) + for i = 0, #neighbors - 1 do local continue repeat local next = neighbors:get(i) @@ -74,6 +74,10 @@ System.namespace("Knapcode.FactorioTools.OilField", function (namespace) end end + + context.SharedInstances:ReturnNeighborArray(neighbors) + + return nil end return { diff --git a/src/lua/FactorioTools/Dijkstras.lua b/src/lua/FactorioTools/Dijkstras.lua index 5cd0fad5..8b06a25a 100644 --- a/src/lua/FactorioTools/Dijkstras.lua +++ b/src/lua/FactorioTools/Dijkstras.lua @@ -2,12 +2,10 @@ local System = System local KnapcodeOilField local SpanLocation -local ArrayLocation local PriorityQueueLocationDouble System.import(function (out) KnapcodeOilField = Knapcode.FactorioTools.OilField SpanLocation = System.Span(KnapcodeOilField.Location) - ArrayLocation = System.Array(KnapcodeOilField.Location) PriorityQueueLocationDouble = System.PriorityQueue(KnapcodeOilField.Location, System.Double) end) System.namespace("Knapcode.FactorioTools.OilField", function (namespace) @@ -28,7 +26,9 @@ System.namespace("Knapcode.FactorioTools.OilField", function (namespace) priorityQueue:Enqueue(start, 0) inQueue:Add(start) - local neighbors = SpanLocation.ctorArray(ArrayLocation(4)) + + local neighbors = context.SharedInstances:GetNeighborArray() + while #priorityQueue > 0 do @@ -46,8 +46,8 @@ System.namespace("Knapcode.FactorioTools.OilField", function (namespace) end end - grid:GetNeighbors(neighbors, current) - for i = 0, neighbors:getLength() - 1 do + grid:GetNeighbors(SpanLocation.ctorArray(neighbors), current) + for i = 0, #neighbors - 1 do local continue repeat local neighbor = neighbors:get(i) @@ -86,6 +86,11 @@ System.namespace("Knapcode.FactorioTools.OilField", function (namespace) end end + + context.SharedInstances:ReturnNeighborArray(neighbors) + + + return KnapcodeOilField.DijkstrasResult(cameFrom, reachedGoals) end return { diff --git a/src/lua/FactorioTools/RotateOptimize.lua b/src/lua/FactorioTools/RotateOptimize.lua index 0760e3ce..24582bf4 100644 --- a/src/lua/FactorioTools/RotateOptimize.lua +++ b/src/lua/FactorioTools/RotateOptimize.lua @@ -4,7 +4,6 @@ local KnapcodeFactorioTools local KnapcodeOilField local ListLocation local SpanLocation -local ArrayLocation local QueueLocation local ListTerminalLocation System.import(function (out) @@ -12,7 +11,6 @@ System.import(function (out) KnapcodeOilField = Knapcode.FactorioTools.OilField ListLocation = System.List(KnapcodeOilField.Location) SpanLocation = System.Span(KnapcodeOilField.Location) - ArrayLocation = System.Array(KnapcodeOilField.Location) QueueLocation = System.Queue(KnapcodeOilField.Location) ListTerminalLocation = System.List(KnapcodeOilField.TerminalLocation) end) @@ -332,19 +330,26 @@ System.namespace("Knapcode.FactorioTools.OilField", function (namespace) toExplore:Enqueue(start) pipes:Add(start) - local neighbors = SpanLocation.ctorArray(ArrayLocation(4)) + + local neighbors = context.ParentContext.SharedInstances:GetNeighborArray() + while #toExplore > 0 do local current = toExplore:Dequeue() - context.ExistingPipeGrid:GetNeighbors(neighbors, current) - for i = 0, neighbors:getLength() - 1 do + context.ExistingPipeGrid:GetNeighbors(SpanLocation.ctorArray(neighbors), current) + for i = 0, #neighbors - 1 do if neighbors:get(i).IsValid and pipes:Add(neighbors:get(i)) then toExplore:Enqueue(neighbors:get(i)) end end end + + + context.ParentContext.SharedInstances:ReturnNeighborArray(neighbors) + + end ExplorePaths = function (context, start) local toExplore = QueueLocation() @@ -352,7 +357,9 @@ System.namespace("Knapcode.FactorioTools.OilField", function (namespace) local cameFrom = context.ParentContext:GetLocationDictionary(KnapcodeOilField.Location) cameFrom:set(start, start) - local neighbors = SpanLocation.ctorArray(ArrayLocation(4)) + + local neighbors = context.ParentContext.SharedInstances:GetNeighborArray() + local reachedGoals = ListLocation() @@ -368,8 +375,8 @@ System.namespace("Knapcode.FactorioTools.OilField", function (namespace) break end - context.ExistingPipeGrid:GetNeighbors(neighbors, current) - for i = 0, neighbors:getLength() - 1 do + context.ExistingPipeGrid:GetNeighbors(SpanLocation.ctorArray(neighbors), current) + for i = 0, #neighbors - 1 do local continue repeat if not neighbors:get(i).IsValid or cameFrom:ContainsKey(neighbors:get(i)) then @@ -392,6 +399,10 @@ System.namespace("Knapcode.FactorioTools.OilField", function (namespace) end end + + context.ParentContext.SharedInstances:ReturnNeighborArray(neighbors) + + return class.ExploredPaths(start, cameFrom, reachedGoals) end class = { diff --git a/src/lua/FactorioTools/SharedInstances.lua b/src/lua/FactorioTools/SharedInstances.lua index 0d168f10..1cb7513a 100644 --- a/src/lua/FactorioTools/SharedInstances.lua +++ b/src/lua/FactorioTools/SharedInstances.lua @@ -1,11 +1,32 @@ -- Generated by CSharp.lua Compiler local System = System +local KnapcodeOilField +local ArrayLocation +local QueueArrayLocation +System.import(function (out) + KnapcodeOilField = Knapcode.FactorioTools.OilField + ArrayLocation = System.Array(KnapcodeOilField.Location) + QueueArrayLocation = System.Queue(ArrayLocation) +end) System.namespace("Knapcode.FactorioTools.OilField", function (namespace) namespace.class("SharedInstances", function (namespace) - local __ctor__ + local GetNeighborArray, ReturnNeighborArray, __ctor__ __ctor__ = function (this, grid) + this._neighborArrays = QueueArrayLocation() + end + GetNeighborArray = function (this) + if #this._neighborArrays > 0 then + return this._neighborArrays:Dequeue() + end + + return ArrayLocation(4) + end + ReturnNeighborArray = function (this, array) + this._neighborArrays:Enqueue(array) end return { + GetNeighborArray = GetNeighborArray, + ReturnNeighborArray = ReturnNeighborArray, __ctor__ = __ctor__ } end) diff --git a/src/lua/Invoke-LuaBuild.ps1 b/src/lua/Invoke-LuaBuild.ps1 index a6403bbf..1441b554 100644 --- a/src/lua/Invoke-LuaBuild.ps1 +++ b/src/lua/Invoke-LuaBuild.ps1 @@ -75,7 +75,7 @@ function Publish-CompiledLua($projectDir, $referenceNames, $filesFirst) { $libArg = if ($references) { @("-l"; $references -join ";") } else { @() } $sourceList = ($files | ForEach-Object { $_.FullName } | Sort-Object) -join ";" - dotnet run --no-build --configuration Release --project $compilerDir -- -c -p -csc "-define:ENABLE_GRID_TOSTRING" @libArg -s $sourceList -d $outputDir + dotnet run --no-build --configuration Release --project $compilerDir -- -c -p -csc "-define:ENABLE_GRID_TOSTRING -define:RENT_NEIGHBORS" @libArg -s $sourceList -d $outputDir if ($LASTEXITCODE -ne 0) { throw "The CSharp.lua compiler failed with exit code $LASTEXITCODE." }