Package nallar.tickthreading.minecraft.commands

Source Code of nallar.tickthreading.minecraft.commands.ProfileCommand

package nallar.tickthreading.minecraft.commands;

import nallar.tickthreading.Log;
import nallar.tickthreading.minecraft.TickManager;
import nallar.tickthreading.minecraft.TickThreading;
import nallar.tickthreading.minecraft.profiling.ContentionProfiler;
import nallar.tickthreading.minecraft.profiling.EntityTickProfiler;
import nallar.tickthreading.minecraft.profiling.PacketProfiler;
import nallar.tickthreading.minecraft.profiling.Timings;
import nallar.tickthreading.minecraft.profiling.UtilisationProfiler;
import nallar.tickthreading.minecraft.tickregion.TickRegion;
import nallar.tickthreading.util.TableFormatter;
import net.minecraft.command.ICommandSender;
import net.minecraft.entity.Entity;
import net.minecraft.world.World;
import net.minecraftforge.common.DimensionManager;

import java.util.*;

public class ProfileCommand extends Command {
  public static String name = "profile";

  @Override
  public String getCommandName() {
    return name;
  }

  @Override
  public boolean requireOp() {
    return TickThreading.instance.requireOpForProfileCommand;
  }

  @Override
  public String getCommandUsage(ICommandSender commandSender) {
    return "Usage: /profile [type=a/e/l/p/u/(c [chunk x] [chunk z])] [time=7] [dimensionid=current dimension]";
  }

  @Override
  public void processCommand(final ICommandSender commandSender, List<String> arguments) {
    World world = null;
    int time_ = 7;
    boolean entity_;
    boolean location_ = false;
    Integer x = null;
    Integer z = null;
    try {
      if (arguments.isEmpty()) {
        throw new Exception();
      }
      String type = arguments.get(0).toLowerCase();
      if ("p".equals(type)) {
        PacketProfiler.startProfiling(commandSender, 10);
        return;
      }
      if ("l".equals(type)) {
        sendChat(commandSender, "Performing lock contention profiling for 4 minutes.");
        ContentionProfiler.profile(commandSender, 240, 11);
        return;
      }
      if ("u".equals(type)) {
        sendChat(commandSender, "Performing CPU utilisation profiling for 1 minute.");
        UtilisationProfiler.profile(commandSender, 60);
        return;
      }
      entity_ = "e".equals(type);
      if ("c".equals(type)) {
        entity_ = true;
        location_ = true;
        if (arguments.size() > 2) {
          x = Integer.valueOf(arguments.remove(1));
          z = Integer.valueOf(arguments.remove(1));
        }
      }
      if (arguments.size() > 1) {
        time_ = Integer.valueOf(arguments.get(1));
      }
      if (arguments.size() > 2) {
        world = DimensionManager.getWorld(Integer.valueOf(arguments.get(2)));
        if (world == null) {
          throw new NullPointerException();
        }
      }
    } catch (Exception e) {
      sendChat(commandSender, usage());
      return;
    }
    final int time = time_;
    final boolean entity = entity_;
    final boolean location = location_;
    if (location) {
      if (commandSender instanceof Entity) {
        Entity e = (Entity) commandSender;
        x = e.chunkCoordX;
        z = e.chunkCoordZ;
        world = e.worldObj;
      } else {
        world = DimensionManager.getWorld(0);
      }
    }
    final TickManager manager = TickThreading.instance.getManager(world == null ? DimensionManager.getWorld(0) : world);
    final List<World> worlds = new ArrayList<World>();
    if (world == null) {
      Collections.addAll(worlds, DimensionManager.getWorlds());
    } else {
      worlds.add(world);
    }
    final int hashCode = x != null ? TickManager.getHashCode(x * 16, z * 16) : 0;
    if (entity) {
      final EntityTickProfiler entityTickProfiler = EntityTickProfiler.ENTITY_TICK_PROFILER;
      if (location) {
        if (!world.getChunkProvider().chunkExists(x, z)) {
          sendChat(commandSender, "The chunk coords " + x + ',' + z + " are not loaded, can not profile.");
          return;
        }
      }
      if (!entityTickProfiler.startProfiling(new Runnable() {
        @Override
        public void run() {
          if (location) {
            TickRegion tickRegion = manager.getEntityRegion(hashCode);
            if (tickRegion != null) {
              tickRegion.profilingEnabled = false;
            }
            tickRegion = manager.getTileEntityRegion(hashCode);
            if (tickRegion != null) {
              tickRegion.profilingEnabled = false;
            }
          }
          sendChat(commandSender, entityTickProfiler.writeStringData(new TableFormatter(commandSender)).toString());
        }
      }, location ? ProfilingState.CHUNK : ProfilingState.GLOBAL, time, worlds)) {
        sendChat(commandSender, "Someone else is currently profiling.");
      }
      if (location) {
        manager.profilingEnabled = false;
        TickRegion tickRegion = manager.getEntityRegion(hashCode);
        if (tickRegion != null) {
          tickRegion.profilingEnabled = true;
        }
        tickRegion = manager.getTileEntityRegion(hashCode);
        if (tickRegion != null) {
          tickRegion.profilingEnabled = true;
        }
      }
      sendChat(commandSender, "Profiling for " + time + " seconds in " + (world == null ? "all worlds " : Log.name(world)) + (location ? " at chunk coords " + x + ',' + z : ""));
      return;
    }
    if (Timings.enabled) {
      sendChat(commandSender, "Someone else is currently profiling, please wait and try again.");
      return;
    }
    Timings.enabled = true;
    Runnable profilingRunnable = new Runnable() {
      @Override
      public void run() {
        try {
          Thread.sleep(1000 * time);
        } catch (InterruptedException ignored) {
        }
        Timings.enabled = false;
        try {
          Thread.sleep(100 * time);
        } catch (InterruptedException ignored) {
        }
        sendChat(commandSender, String.valueOf(Timings.writeData(new TableFormatter(commandSender))));
        Timings.clear();
      }
    };
    Thread profilingThread = new Thread(profilingRunnable);
    profilingThread.setName("TT Profiler");
    sendChat(commandSender, "Profiling for " + time + " seconds");
    profilingThread.start();
  }

  public static enum ProfilingState {
    NONE,
    GLOBAL,
    CHUNK
  }
}
TOP

Related Classes of nallar.tickthreading.minecraft.commands.ProfileCommand

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.