<commit_before>package com.elmakers.mine.bukkit.batch;

import java.util.Arrays;
import java.util.Comparator;
import java.util.Set;

import com.elmakers.mine.bukkit.api.action.CastContext;
import com.elmakers.mine.bukkit.api.spell.Spell;
import org.apache.commons.lang.ArrayUtils;
import org.bukkit.Material;
import org.bukkit.block.Block;

import com.elmakers.mine.bukkit.api.block.BlockData;
import com.elmakers.mine.bukkit.api.magic.Mage;
import com.elmakers.mine.bukkit.api.magic.MageController;
import com.elmakers.mine.bukkit.block.UndoList;

public class UndoBatch implements com.elmakers.mine.bukkit.api.batch.UndoBatch {
    protected final MageController controller;
    private UndoList trackUndoBlocks;
    private static final BlockData[] template = new BlockData[0];
    private final BlockData[] undoBlocks;
    private int undoIndex = 0;
    private boolean finishedAttachables = false;
    protected boolean finished = false;
    protected boolean applyPhysics = false;
    protected UndoList undoList;

    private final Set<Material> attachables;
    private final Set<Material> attachablesWall;
    private final Set<Material> attachablesDouble;
    private final Set<Material> delayed;

    public UndoBatch(UndoList blockList) {
        Mage mage = blockList.getOwner();
        controller = mage.getController();

        // We're going to track the blocks we undo
        // But this doesn't get put back in the undo queue, or
        // it will just flip-flop forever between these two actions.
        // Maybe eventually we'll have a "redo" queue.
        trackUndoBlocks = new UndoList(mage, "Undo");
        trackUndoBlocks.setSpell(blockList.getSpell());
        trackUndoBlocks.setBatch(this);
        trackUndoBlocks.setBypass(true);

        undoList = blockList;
        this.applyPhysics = blockList.getApplyPhysics();
        this.attachables = controller.getMaterialSet("attachable");
        this.attachablesWall = controller.getMaterialSet("attachable_wall");
        this.attachablesDouble = controller.getMaterialSet("attachable_double");
        this.delayed = controller.getMaterialSet("delayed");

        // Sort so attachable items don't break
        this.undoBlocks = blockList.toArray(template);
        ArrayUtils.reverse(this.undoBlocks);
        Arrays.sort(undoBlocks, new Comparator<BlockData>() {
            @Override
            public int compare(BlockData block1, BlockData block2) {
                Material material1 = block1.getMaterial();
                Material material2 = block2.getMaterial();
                boolean attachable1 = attachablesWall.contains(material1) || attachables.contains(material1) || attachablesDouble.contains(material1) || delayed.contains(material1);
                boolean attachable2 = attachablesWall.contains(material2) || attachables.contains(material2) || attachablesDouble.contains(material2) || delayed.contains(material2);
                if (attachable1 && !attachable2) {
                    return 1;
                }
                if (attachable2 && !attachable1) {
                    return -1;
                }
                return block1.getLocation().getBlockY() - block2.getLocation().getBlockY();
            }
        });
    }

    public int size() {
        return undoBlocks == null ? 0 : undoBlocks.length;
    }

    public int remaining() {
        return undoBlocks == null ? 0 : undoBlocks.length - undoIndex;
    }

    public int process(int maxBlocks) {
        int processedBlocks = 0;
        while (undoBlocks != null && undoIndex < undoBlocks.length && processedBlocks < maxBlocks) {
            BlockData blockData = undoBlocks[undoIndex];
            Block block = blockData.getBlock();
            if (!block.getChunk().isLoaded()) {
                block.getChunk().load();
                break;
            }
            Material material = block.getType();
            boolean isAttachable = attachables.contains(material) || attachablesWall.contains(material)
                    || attachablesDouble.contains(material) || delayed.contains(material);
            if ((isAttachable && !finishedAttachables) || (!isAttachable && finishedAttachables)) {
                trackUndoBlocks.add(blockData);
                if (!undoList.undo(blockData, applyPhysics)) {
                    break;
                }
            }
            undoIndex++;
            processedBlocks++;
        }
        if (undoBlocks == null || (undoIndex >= undoBlocks.length && finishedAttachables)) {
            finish();
        } else if (undoIndex >= undoBlocks.length) {
            finishedAttachables = true;
            undoIndex = 0;
        }

        return processedBlocks;
    }

    public void finish() {
        if (!finished) {
            undoList.unregisterAttached();
            undoList.undoEntityEffects();
            finished = true;
            controller.update(trackUndoBlocks);
            CastContext context = undoList.getContext();
            if (context != null) {
                context.playEffects("undo");
            }
        }
    }

    @Override
    public boolean isFinished() {
        return finished;
    }

    @Override
    public String getName() {<commit_msg>Track undo blocks with a BlockList, not an UndoList<commit_after>package com.elmakers.mine.bukkit.batch;

import java.util.Arrays;
import java.util.Comparator;
import java.util.Set;

import com.elmakers.mine.bukkit.api.action.CastContext;
import com.elmakers.mine.bukkit.block.BlockList;
import org.apache.commons.lang.ArrayUtils;
import org.bukkit.Material;
import org.bukkit.block.Block;

import com.elmakers.mine.bukkit.api.block.BlockData;
import com.elmakers.mine.bukkit.api.magic.Mage;
import com.elmakers.mine.bukkit.api.magic.MageController;
import com.elmakers.mine.bukkit.block.UndoList;

public class UndoBatch implements com.elmakers.mine.bukkit.api.batch.UndoBatch {
    protected final MageController controller;
    private BlockList trackUndoBlocks;
    private static final BlockData[] template = new BlockData[0];
    private final BlockData[] undoBlocks;
    private int undoIndex = 0;
    private boolean finishedAttachables = false;
    protected boolean finished = false;
    protected boolean applyPhysics = false;
    protected UndoList undoList;

    private final Set<Material> attachables;
    private final Set<Material> attachablesWall;
    private final Set<Material> attachablesDouble;
    private final Set<Material> delayed;

    public UndoBatch(UndoList blockList) {
        Mage mage = blockList.getOwner();
        controller = mage.getController();

        // We're going to track the blocks we undo
        // But this doesn't get put back in the undo queue, or
        // it will just flip-flop forever between these two actions.
        // Maybe eventually we'll have a "redo" queue.
        trackUndoBlocks = new BlockList();

        undoList = blockList;
        this.applyPhysics = blockList.getApplyPhysics();
        this.attachables = controller.getMaterialSet("attachable");
        this.attachablesWall = controller.getMaterialSet("attachable_wall");
        this.attachablesDouble = controller.getMaterialSet("attachable_double");
        this.delayed = controller.getMaterialSet("delayed");

        // Sort so attachable items don't break
        this.undoBlocks = blockList.toArray(template);
        ArrayUtils.reverse(this.undoBlocks);
        Arrays.sort(undoBlocks, new Comparator<BlockData>() {
            @Override
            public int compare(BlockData block1, BlockData block2) {
                Material material1 = block1.getMaterial();
                Material material2 = block2.getMaterial();
                boolean attachable1 = attachablesWall.contains(material1) || attachables.contains(material1) || attachablesDouble.contains(material1) || delayed.contains(material1);
                boolean attachable2 = attachablesWall.contains(material2) || attachables.contains(material2) || attachablesDouble.contains(material2) || delayed.contains(material2);
                if (attachable1 && !attachable2) {
                    return 1;
                }
                if (attachable2 && !attachable1) {
                    return -1;
                }
                return block1.getLocation().getBlockY() - block2.getLocation().getBlockY();
            }
        });
    }

    public int size() {
        return undoBlocks == null ? 0 : undoBlocks.length;
    }

    public int remaining() {
        return undoBlocks == null ? 0 : undoBlocks.length - undoIndex;
    }

    public int process(int maxBlocks) {
        int processedBlocks = 0;
        while (undoBlocks != null && undoIndex < undoBlocks.length && processedBlocks < maxBlocks) {
            BlockData blockData = undoBlocks[undoIndex];
            Block block = blockData.getBlock();
            if (!block.getChunk().isLoaded()) {
                block.getChunk().load();
                break;
            }
            Material material = block.getType();
            boolean isAttachable = attachables.contains(material) || attachablesWall.contains(material)
                    || attachablesDouble.contains(material) || delayed.contains(material);
            if ((isAttachable && !finishedAttachables) || (!isAttachable && finishedAttachables)) {
                trackUndoBlocks.add(blockData);
                if (!undoList.undo(blockData, applyPhysics)) {
                    break;
                }
            }
            undoIndex++;
            processedBlocks++;
        }
        if (undoBlocks == null || (undoIndex >= undoBlocks.length && finishedAttachables)) {
            finish();
        } else if (undoIndex >= undoBlocks.length) {
            finishedAttachables = true;
            undoIndex = 0;
        }

        return processedBlocks;
    }

    public void finish() {
        if (!finished) {
            undoList.unregisterAttached();
            undoList.undoEntityEffects();
            finished = true;
            controller.update(trackUndoBlocks);
            trackUndoBlocks = null;
            CastContext context = undoList.getContext();
            if (context != null) {
                context.playEffects("undo");
            }
        }
    }

    @Override
    public boolean isFinished() {
        return finished;
    }

    @Override
    public String getName() {
{'fraction_non_alphanumeric': 0.09910516693928606, 'fraction_numerical': 0.00577311652073511, 'mean_word_length': 2.4157081827144267, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1562199', 'n_tokens_mistral': 2809, 'n_tokens_neox': 2669, 'n_words': 610}