11package mekanism .common .content .transporter ;
22
3+ import com .google .common .collect .ImmutableList ;
34import it .unimi .dsi .fastutil .longs .Long2ObjectMap ;
45import it .unimi .dsi .fastutil .longs .Long2ObjectOpenHashMap ;
56import it .unimi .dsi .fastutil .objects .Object2DoubleOpenHashMap ;
1617import mekanism .common .content .network .InventoryNetwork .AcceptorData ;
1718import mekanism .common .content .network .transmitter .LogisticalTransporterBase ;
1819import mekanism .common .content .transporter .PathfinderCache .CachedPath ;
19- import mekanism .common .content .transporter .PathfinderCache .PathData ;
20- import mekanism .common .content .transporter .TransporterPathfinder .Pathfinder .DestChecker ;
2120import mekanism .common .content .transporter .TransporterStack .Path ;
2221import mekanism .common .lib .SidedBlockPos ;
2322import mekanism .common .lib .inventory .IAdvancedTransportEjector ;
3029import net .minecraft .core .BlockPos ;
3130import net .minecraft .core .Direction ;
3231import net .minecraft .core .GlobalPos ;
32+ import net .minecraft .world .item .ItemStack ;
3333import net .minecraft .world .level .Level ;
3434import net .minecraft .world .level .block .entity .BlockEntity ;
3535import net .minecraft .world .level .chunk .ChunkAccess ;
@@ -82,19 +82,13 @@ private static Destination getPath(InventoryNetwork network, AcceptorData data,
8282 BlockPos dest = data .getLocation ();
8383 CachedPath test = PathfinderCache .getCache (start , dest , data .getSides ());
8484 if (test != null && checkPath (network , test .path (), stack )) {
85- return new Destination (test . path (), false , response , test . cost () );
85+ return new Destination (test , response );
8686 }
87- Pathfinder p = new Pathfinder (new DestChecker () {
88- @ Override
89- public boolean isValid (Level level , BlockPos pos , @ Nullable BlockEntity tile , TransporterStack stack , Direction side ) {
90- return TransporterUtils .canInsert (level , pos , tile , stack .color , response .getStack (), side , false );
91- }
92- }, network , start .getLevel (), dest , start .getBlockPos (), stack );
87+ Pathfinder p = new Pathfinder (network , start .getLevel (), dest , start .getBlockPos (), stack , response .getStack (),
88+ (level , pos , tile , s , resp , side ) -> TransporterUtils .canInsert (level , pos , tile , s .color , resp , side , false ));
9389 p .find (chunkMap );
94- List <BlockPos > path = p .getPath ();
95- if (path .size () >= 2 ) {
96- PathfinderCache .addCachedPath (start , new PathData (start .getBlockPos (), dest , p .getSide ()), path , p .finalScore );
97- return new Destination (path , false , response , p .finalScore );
90+ if (p .hasPath ()) {
91+ return new Destination (PathfinderCache .addCachedPath (start , dest , p ), response );
9892 }
9993 }
10094 return null ;
@@ -177,16 +171,12 @@ public static IdlePathData getIdlePath(LogisticalTransporterBase start, Transpor
177171 }
178172 if (stack .homeLocation != null ) {
179173 Long2ObjectMap <ChunkAccess > chunkMap = new Long2ObjectOpenHashMap <>();
180- Pathfinder p = new Pathfinder (new DestChecker () {
181- @ Override
182- public boolean isValid (Level level , BlockPos pos , @ Nullable BlockEntity tile , TransporterStack stack , Direction side ) {
183- return TransporterUtils .canInsert (level , pos , tile , stack .color , stack .itemStack , side , true );
184- }
185- }, network , start .getLevel (), stack .homeLocation , start .getBlockPos (), stack );
174+ //We are idling use the base stack
175+ Pathfinder p = new Pathfinder (network , start .getLevel (), stack .homeLocation , start .getBlockPos (), stack , stack .itemStack ,
176+ (level , pos , tile , s , resp , side ) -> TransporterUtils .canInsert (level , pos , tile , s .color , resp , side , true ));
186177 p .find (chunkMap );
187- List <BlockPos > path = p .getPath ();
188- if (path .size () >= 2 ) {
189- return new IdlePathData (path , Path .HOME );
178+ if (p .hasPath ()) {
179+ return new IdlePathData (p .getPath (), Path .HOME );
190180 }
191181 stack .homeLocation = null ;
192182 }
@@ -212,7 +202,7 @@ public IdlePath(InventoryNetwork network, BlockPos start, TransporterStack stack
212202 }
213203
214204 public Destination find () {
215- ArrayList <BlockPos > ret = new ArrayList <>();
205+ List <BlockPos > ret = new ArrayList <>();
216206 ret .add (start );
217207 LogisticalTransporterBase startTransmitter = network .getTransmitter (start );
218208 if (transportStack .idleDir == null ) {
@@ -221,7 +211,7 @@ public Destination find() {
221211 LogisticalTransporterBase transmitter = network .getTransmitter (start .relative (transportStack .idleDir ));
222212 if (transportStack .canInsertToTransporter (transmitter , transportStack .idleDir , startTransmitter )) {
223213 loopSide (ret , transportStack .idleDir , startTransmitter );
224- return new Destination (ret , true , null , 0 ). setPathType ( Path . NONE );
214+ return createDestination (ret );
225215 }
226216 TransitRequest request = TransitRequest .simple (transportStack .itemStack );
227217 if (startTransmitter != null ) {
@@ -251,15 +241,21 @@ private Destination getDestination(List<BlockPos> ret, @Nullable LogisticalTrans
251241 // is gracefully handled
252242 transportStack .idleDir = side ;
253243 ret .add (start .relative (side ));
254- return new Destination (ret , true , null , 0 ). setPathType ( Path . NONE );
244+ return createDestination (ret );
255245 }
256246 }
257247 }
258248 return null ;
259249 }
260250 transportStack .idleDir = newSide ;
261251 loopSide (ret , newSide , startTransmitter );
262- return new Destination (ret , true , null , 0 ).setPathType (Path .NONE );
252+ return createDestination (ret );
253+ }
254+
255+ private Destination createDestination (List <BlockPos > ret ) {
256+ List <BlockPos > path = new ArrayList <>(ret );
257+ Collections .reverse (path );
258+ return new Destination (Collections .unmodifiableList (path ), null , 0 );
263259 }
264260
265261 private void loopSide (List <BlockPos > list , Direction side , @ Nullable LogisticalTransporterBase startTransmitter ) {
@@ -304,16 +300,22 @@ public static class Destination implements Comparable<Destination> {
304300
305301 private final TransitResponse response ;
306302 private final List <BlockPos > path ;
303+ private final int cachedHash ;
307304 private final double score ;
308- private Path pathType ;
305+ private Path pathType = Path . NONE ;
309306
310- public Destination (List <BlockPos > list , boolean inv , TransitResponse ret , double gScore ) {
311- path = new ArrayList <>(list );
312- if (inv ) {
313- Collections .reverse (path );
314- }
315- response = ret ;
316- score = gScore ;
307+ public Destination (CachedPath path , TransitResponse ret ) {
308+ this (path .path (), ret , path .cost ());
309+ }
310+
311+ /**
312+ * @apiNote Expects list to be unmodifiable/immutable (at the very least not mutated after being passed).
313+ */
314+ public Destination (List <BlockPos > path , TransitResponse ret , double gScore ) {
315+ this .path = path ;
316+ this .cachedHash = this .path .hashCode ();
317+ this .response = ret ;
318+ this .score = gScore ;
317319 }
318320
319321 public Destination setPathType (Path type ) {
@@ -323,9 +325,7 @@ public Destination setPathType(Path type) {
323325
324326 @ Override
325327 public int hashCode () {
326- int code = 1 ;
327- code = 31 * code + path .hashCode ();
328- return code ;
328+ return cachedHash ;
329329 }
330330
331331 @ Override
@@ -367,19 +367,21 @@ public static class Pathfinder {
367367 private final BlockPos start ;
368368 private final BlockPos finalNode ;
369369 private final TransporterStack transportStack ;
370+ private final ItemStack data ;
370371 private final DestChecker destChecker ;
371372 private final Level world ;
372373 private double finalScore ;
373374 private Direction side ;
374375 private List <BlockPos > results = new ArrayList <>();
375376
376- public Pathfinder (DestChecker checker , InventoryNetwork network , Level world , BlockPos finalNode , BlockPos start , TransporterStack stack ) {
377+ public Pathfinder (InventoryNetwork network , Level world , BlockPos finalNode , BlockPos start , TransporterStack stack , ItemStack data , DestChecker checker ) {
377378 destChecker = checker ;
378379 this .network = network ;
379380 this .world = world ;
380381 this .finalNode = finalNode ;
381382 this .start = start ;
382383 transportStack = stack ;
384+ this .data = data ;
383385 }
384386
385387 public boolean find (Long2ObjectMap <ChunkAccess > chunkMap ) {
@@ -469,7 +471,7 @@ private boolean isValidDestination(BlockPos start, @Nullable LogisticalTransport
469471 //Check to make sure that it is the destination
470472 if (startTransporter != null && neighbor .equals (finalNode )) {
471473 BlockEntity neighborTile = WorldUtils .getTileEntity (world , chunkMap , neighbor );
472- if (destChecker .isValid (world , neighbor , neighborTile , transportStack , direction )) {
474+ if (destChecker .isValid (world , neighbor , neighborTile , transportStack , data , direction )) {
473475 if (startTransporter .canEmitTo (direction ) || (finalNode .equals (transportStack .homeLocation ) && startTransporter .canConnect (direction ))) {
474476 //If it is, and we can emit to it (normal or push mode),
475477 // or it is the home location of the stack (it is returning due to not having been able to get to its destination) and
@@ -494,22 +496,29 @@ private List<BlockPos> reconstructPath(Map<BlockPos, BlockPos> navMap, BlockPos
494496 return path ;
495497 }
496498
499+ public boolean hasPath () {
500+ return !results .isEmpty ();
501+ }
502+
497503 public List <BlockPos > getPath () {
498- List <BlockPos > path = new ArrayList <> ();
504+ ImmutableList . Builder <BlockPos > path = ImmutableList . builder ();
499505 path .add (finalNode );
500506 path .addAll (results );
501- return path ;
507+ return path .build ();
508+ }
509+
510+ public double getFinalScore () {
511+ return finalScore ;
502512 }
503513
504514 public Direction getSide () {
505515 return side ;
506516 }
507517
508- public static class DestChecker {
518+ @ FunctionalInterface
519+ public interface DestChecker {
509520
510- public boolean isValid (Level level , BlockPos pos , @ Nullable BlockEntity tile , TransporterStack stack , Direction side ) {
511- return false ;
512- }
521+ boolean isValid (Level level , BlockPos pos , @ Nullable BlockEntity tile , TransporterStack stack , ItemStack data , Direction side );
513522 }
514523 }
515524}
0 commit comments