Commit ebb92d95976777fa36d5803791ca634c38519256

Authored by Mumfrey
1 parent af5a7f6a

Add DebugMessage capability

src/client/java/com/mumfrey/liteloader/client/mixin/MixinGuiOverlayDebug.java 0 → 100644
  1 +/*
  2 + * This file is part of LiteLoader.
  3 + * Copyright (C) 2012-16 Adam Mummery-Smith
  4 + * All Rights Reserved.
  5 + */
  6 +package com.mumfrey.liteloader.client.mixin;
  7 +
  8 +import java.util.List;
  9 +
  10 +import org.spongepowered.asm.mixin.Mixin;
  11 +import org.spongepowered.asm.mixin.Shadow;
  12 +import org.spongepowered.asm.mixin.injection.At;
  13 +import org.spongepowered.asm.mixin.injection.Inject;
  14 +import org.spongepowered.asm.mixin.injection.Redirect;
  15 +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
  16 +
  17 +import com.mumfrey.liteloader.util.debug.DebugMessage;
  18 +import com.mumfrey.liteloader.util.debug.DebugMessage.Position;
  19 +
  20 +import net.minecraft.client.gui.Gui;
  21 +import net.minecraft.client.gui.GuiOverlayDebug;
  22 +
  23 +@Mixin(GuiOverlayDebug.class)
  24 +public abstract class MixinGuiOverlayDebug extends Gui
  25 +{
  26 + @Shadow protected abstract List<String> call();
  27 +
  28 + @Shadow protected abstract <T extends Comparable<T>> List<String> getDebugInfoRight();
  29 +
  30 + private boolean captureNextCall = false;
  31 +
  32 + @Inject(method = "renderDebugInfoLeft()V", at = @At(value = "HEAD"))
  33 + private void onRenderDebugInfoLeft(CallbackInfo ci)
  34 + {
  35 + this.captureNextCall = true;
  36 + }
  37 +
  38 + @Redirect(method = "renderDebugInfoLeft()V", at = @At(value = "INVOKE", target = "Ljava/util/List;size()I"))
  39 + private int getSize(List<String> list)
  40 + {
  41 + if (this.captureNextCall)
  42 + {
  43 + this.captureNextCall = false;
  44 + List<String> messages = DebugMessage.getMessages(Position.LEFT_BOTTOM);
  45 + if (messages != null)
  46 + {
  47 + list.addAll(messages);
  48 + }
  49 + }
  50 +
  51 + return list.size();
  52 + }
  53 +
  54 + @Redirect(method = "renderDebugInfoLeft()V", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/GuiOverlayDebug;call()Ljava/util/List;"))
  55 + private List<String> onCall(GuiOverlayDebug self)
  56 + {
  57 + List<String> list = this.call();
  58 +
  59 + List<String> topMessages = DebugMessage.getMessages(Position.LEFT_TOP);
  60 + if (topMessages != null)
  61 + {
  62 + list.addAll(1, topMessages);
  63 + }
  64 +
  65 + List<String> midMessages = DebugMessage.getMessages(Position.LEFT_AFTER_INFO);
  66 + if (midMessages != null)
  67 + {
  68 + list.addAll(midMessages);
  69 + }
  70 +
  71 + return list;
  72 + }
  73 +
  74 + @Redirect(method = "renderDebugInfoRight(Lnet/minecraft/client/gui/ScaledResolution;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/GuiOverlayDebug;getDebugInfoRight()Ljava/util/List;"))
  75 + private <T extends Comparable<T>> List<String> onGetDebugInfoRight(GuiOverlayDebug self)
  76 + {
  77 + List<String> list = this.getDebugInfoRight();
  78 +
  79 + List<String> topMessages = DebugMessage.getMessages(Position.RIGHT_TOP);
  80 + if (topMessages != null)
  81 + {
  82 + list.addAll(0, topMessages);
  83 + list.add(null);
  84 + }
  85 +
  86 + List<String> bottomMessages = DebugMessage.getMessages(Position.RIGHT_BOTTOM);
  87 + if (bottomMessages != null)
  88 + {
  89 + list.add(null);
  90 + list.addAll(bottomMessages);
  91 + }
  92 +
  93 + return list;
  94 + }
  95 +}
src/client/resources/mixins.liteloader.client.json
@@ -21,7 +21,8 @@ @@ -21,7 +21,8 @@
21 "MixinSimpleReloadableResourceManager", 21 "MixinSimpleReloadableResourceManager",
22 "MixinSoundHandler", 22 "MixinSoundHandler",
23 "MixinGuiTextField", 23 "MixinGuiTextField",
24 - "MixinIntIdentityHashBiMap" 24 + "MixinIntIdentityHashBiMap",
  25 + "MixinGuiOverlayDebug"
25 ], 26 ],
26 "injectors": { 27 "injectors": {
27 "defaultRequire": 1 28 "defaultRequire": 1
src/main/java/com/mumfrey/liteloader/util/debug/DebugMessage.java 0 → 100644
  1 +/*
  2 + * This file is part of LiteLoader.
  3 + * Copyright (C) 2012-16 Adam Mummery-Smith
  4 + * All Rights Reserved.
  5 + */
  6 +package com.mumfrey.liteloader.util.debug;
  7 +
  8 +import java.util.ArrayList;
  9 +import java.util.EnumMap;
  10 +import java.util.List;
  11 +import java.util.Map;
  12 +
  13 +import com.google.common.collect.ImmutableList;
  14 +import com.google.common.collect.ImmutableList.Builder;
  15 +
  16 +/**
  17 + * A debug screen message, only displayed on clients. Consumers can create
  18 + * debug messages and then change them using the returned handle.
  19 + */
  20 +public final class DebugMessage
  21 +{
  22 + /**
  23 + * Position to display the debug message, relative to other debug info
  24 + */
  25 + public enum Position
  26 + {
  27 + /**
  28 + * At the top of the left column, immediately below the version string
  29 + */
  30 + LEFT_TOP,
  31 +
  32 + /**
  33 + * At the bottom of the left column, after the debug info and before
  34 + * the help text
  35 + */
  36 + LEFT_AFTER_INFO,
  37 +
  38 + /**
  39 + * At the bottom of the left column, below the help text and prompt
  40 + */
  41 + LEFT_BOTTOM,
  42 +
  43 + /**
  44 + * At the top of the right column, above the JVM details
  45 + */
  46 + RIGHT_TOP,
  47 +
  48 + /**
  49 + * At the bottom of the right column
  50 + */
  51 + RIGHT_BOTTOM;
  52 + }
  53 +
  54 + /**
  55 + * Map of positions to lists of messages
  56 + */
  57 + private static final Map<Position, List<DebugMessage>> messages = new EnumMap<DebugMessage.Position, List<DebugMessage>>(Position.class);
  58 +
  59 + /**
  60 + * Position for this message
  61 + */
  62 + private final Position position;
  63 +
  64 + /**
  65 + * Message text, can be null though it is recommended to set the message to
  66 + * invisible to hide it. Null messages leave a blank line.
  67 + */
  68 + private String message;
  69 +
  70 + /**
  71 + * Current visible state
  72 + */
  73 + private boolean visible = true;
  74 +
  75 + private DebugMessage(Position position, String message)
  76 + {
  77 + this.position = position;
  78 + this.message = message;
  79 + }
  80 +
  81 + /**
  82 + * Update the message text. Null messages can be used to leave blank lines
  83 + *
  84 + * @param message the new message text
  85 + * @return fluent interface
  86 + */
  87 + public DebugMessage setMessage(String message)
  88 + {
  89 + this.message = message;
  90 + return this;
  91 + }
  92 +
  93 + /**
  94 + * Set the message visibility.
  95 + *
  96 + * @param visible visibility state
  97 + * @return fluent interface
  98 + */
  99 + public DebugMessage setVisible(boolean visible)
  100 + {
  101 + this.visible = visible;
  102 + return this;
  103 + }
  104 +
  105 + public boolean isVisible()
  106 + {
  107 + return this.visible;
  108 + }
  109 +
  110 + @Override
  111 + public String toString()
  112 + {
  113 + return this.message != null ? this.message : "";
  114 + }
  115 +
  116 + /**
  117 + * Remove the message permanently, to re-add the message you must create a
  118 + * new one. After calling this method, the {@link #setMessage} and
  119 + * {@link #setVisible} methods have no effect.
  120 + */
  121 + public void remove()
  122 + {
  123 + List<DebugMessage> messages = DebugMessage.messages.get(this.position);
  124 + if (messages != null)
  125 + {
  126 + messages.remove(this);
  127 + if (messages.size() == 0)
  128 + {
  129 + DebugMessage.messages.put(this.position, null);
  130 + }
  131 + }
  132 + }
  133 +
  134 + /**
  135 + * Create a new debug message with the specified initital values
  136 + *
  137 + * @param position Position to display the message
  138 + * @param message Initial message (can be changed with {@link #setMessage}
  139 + * @return new message handle
  140 + */
  141 + public static DebugMessage create(Position position, String message)
  142 + {
  143 + if (position == null)
  144 + {
  145 + throw new NullPointerException("Null position specified");
  146 + }
  147 +
  148 + DebugMessage debugMessage = new DebugMessage(position, message);
  149 + if (DebugMessage.messages.get(position) == null)
  150 + {
  151 + DebugMessage.messages.put(position, new ArrayList<DebugMessage>());
  152 + }
  153 +
  154 + DebugMessage.messages.get(position).add(debugMessage);
  155 + return debugMessage;
  156 + }
  157 +
  158 + public static List<String> getMessages(Position position)
  159 + {
  160 + List<DebugMessage> debugMessages = DebugMessage.messages.get(position);
  161 + if (debugMessages == null)
  162 + {
  163 + return null;
  164 + }
  165 +
  166 + Builder<String> messages = ImmutableList.<String>builder();
  167 + for (DebugMessage debugMessage : debugMessages)
  168 + {
  169 + if (debugMessage.isVisible())
  170 + {
  171 + messages.add(debugMessage.toString());
  172 + }
  173 + }
  174 + return messages.build();
  175 + }
  176 +}