Package org.mctourney.autoreferee.util.worldsearch

Source Code of org.mctourney.autoreferee.util.worldsearch.WorkerAsyncSearchSnapshots

package org.mctourney.autoreferee.util.worldsearch;

import java.util.Set;

import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.Validate;
import org.bukkit.ChunkSnapshot;
import org.bukkit.Material;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.util.Vector;
import org.mctourney.autoreferee.util.BlockData;

import com.google.common.collect.Sets;

/**
* Consumes: ObjectiveExhaustionMasterTask.snapshots<br>
* Output: ObjectiveExhaustionMasterTask.found<br>
* Output: ObjectiveExhaustionMasterTask.foundContainers<br>
* Cancellation: Self-cancels upon master.all_snapshots_added and queue empty
*
* Searches the ChunkSnapshots for the goal blocks.
*
* @author kane
*
*/
public class WorkerAsyncSearchSnapshots extends BukkitRunnable
{
  public volatile boolean finished = false;
  private ObjectiveExhaustionMasterTask master;

  public WorkerAsyncSearchSnapshots(ObjectiveExhaustionMasterTask task)
  {
    master = task;
  }

  @Override
  public void run()
  {
    // pre-clear, pass it on later
    boolean wasInterrupted = Thread.interrupted();

    try
    {
      // Blocking run until everything's available
      while (!master.all_snapshots_added)
      {
        consume(master.snapshots.take());
      }

      // Finish off by listening to special value
      ChunkSnapshot snap;
      while ((snap = master.snapshots.poll()) != null)
      {
        consume(snap);
      }
    }
    catch (IllegalArgumentException poisonSignal)
    {
      // thrown if null is recieved, which means we're done
    }
    catch (InterruptedException e)
    {
      e.printStackTrace();
      wasInterrupted = true;
    }
    // Re-add null to the list, for the other workers to take
    master.snapshots.offer(null);

    finished = true;

    if (wasInterrupted) // pass it on
      Thread.currentThread().interrupt();
  }

  private void consume(ChunkSnapshot snap)
  {
    Validate.notNull(snap); // send stop signal if poison-value

    Set<BlockData> goals = master.searching; // safe due to COW
    int[] interesting = buildInteresting(goals);

    int baseX = snap.getX() << 4;
    int baseZ = snap.getZ() << 4;

    for (int sy = 0; sy < 16; sy++)
    {
      if (snap.isSectionEmpty(sy))
        continue;
      for (int py = sy << 4; py < (sy << 4) + 16; py++)
        for (int iz = 0; iz < 16; iz++)
          for (int ix = 0; ix < 16; ix++)
          {
            int block = snap.getBlockTypeId(ix, py, iz);
            if (ArrayUtils.contains(interesting, block))
            {
              Vector pos = new Vector(baseX + ix, py, baseZ + iz);
              BlockData bd = new BlockData(Material.getMaterial(block), (byte) snap.getBlockData(ix, py, iz));
              for (BlockData data : goals)
                if (data.equals(bd))
                  master.found.add(new _Entry<BlockData, Vector>(data, pos));
            }
          }
    }
  }

  // Often this will just return the equivalent of new int[] { 35 } but whatever.
  private static int[] buildInteresting(Set<BlockData> goals)
  {
    Set<Integer> filterGoals = Sets.newHashSet();
    for (BlockData data : goals)
    {
      filterGoals.add(data.getMaterial().getId());
    }
    return ArrayUtils.toPrimitive(filterGoals.toArray(new Integer[filterGoals.size()]));
  }
}
TOP

Related Classes of org.mctourney.autoreferee.util.worldsearch.WorkerAsyncSearchSnapshots

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.