void finishRun() {
            RedstonePropagator.currentRun = null;

            if (partChanges.isEmpty() && neighborChanges.isEmpty()) {
                RedstonePropagator.finishingRun = parent;
                clear();
                return;
            }

            RedstonePropagator.finishingRun = this;

            // Notify part changes in bulk
            for (Map.Entry<TileMultipart, Collection<MultiPart>> entry : partChanges.asMap().entrySet()) {
                Collection<MultiPart> parts = entry.getValue();
                for (MultiPart part : parts) {
                    ((IPropagationPart) part).onSignalUpdate();
                }
                entry.getKey().multiPartChange(parts);
            }

            // Notify normal neighbor changes in bulk
            for (Map.Entry<Level, Collection<BlockPos>> entry : neighborChanges.asMap().entrySet()) {
                Level world = entry.getKey();
                Collection<BlockPos> positions = entry.getValue();
                for (BlockPos pos : positions) {
                    world.neighborChanged(pos, CBMultipartModContent.MULTIPART_BLOCK.get(), neighborChangeSources.get(pos));
                }
            }

            RedstonePropagator.finishingRun = parent;
            clear();
        }
Used when the propagator did not change signal, but a new connection may
have been established and signal needs recalculating
core/src/main/java/mrtjp/projectred/core/RedstonePropagator.java