Search in sources :

Example 1 with PrettyPrinter

use of org.lanternpowered.server.util.PrettyPrinter in project LanternServer by LanternPowered.

the class LanternCauseStack method popCauseFrame.

@Override
public void popCauseFrame(StackFrame oldFrame) {
    checkNotNull(oldFrame, "oldFrame");
    final CauseStackFrameImpl frame = this.frames.peek();
    if (frame != oldFrame) {
        if (frame.stack != this) {
            throw new IllegalStateException("Cause Stack Frame Corruption! Attempted to pop a frame from a different stack.");
        }
        // If the given frame is not the top frame then some form of
        // corruption of the stack has occurred and we do our best to correct
        // it.
        // If the target frame is still in the stack then we can pop frames
        // off the stack until we reach it, otherwise we have no choice but
        // to simply throw an error.
        int offset = -1;
        int i = 0;
        for (CauseStackFrameImpl f : this.frames) {
            if (f == oldFrame) {
                offset = i;
                break;
            }
            i++;
        }
        final String name = Thread.currentThread().getName();
        if (!DEBUG_CAUSE_FRAMES && offset == -1) {
            // that was erroneously popped.
            throw new IllegalStateException("Cause Stack Frame Corruption on the Thread \"" + name + "\"! Attempted to pop a frame that was not on the stack.");
        }
        final PrettyPrinter printer = new PrettyPrinter(100).add("Cause Stack Frame Corruption on the Thread \"%s\"!", name).centre().hr().add("Found %d frames left on the stack. Clearing them all.", new Object[] { offset + 1 });
        if (!DEBUG_CAUSE_FRAMES) {
            printer.add().add("Please add -Dsponge.debugcauseframes=true to your startup flags to enable further debugging output.");
            Lantern.getLogger().warn("  Add -Dsponge.debugcauseframes=true to your startup flags to enable further debugging output.");
        } else {
            printer.add();
            printer.add("> Attempting to pop frame:");
            printStack(printer, frame.debugStack);
            printer.add();
            printer.add("> Frames being popped are:");
            printStack(printer, ((CauseStackFrameImpl) oldFrame).debugStack);
        }
        while (offset >= 0) {
            CauseStackFrameImpl f = this.frames.peek();
            if (DEBUG_CAUSE_FRAMES && offset > 0) {
                printer.add();
                printer.add(String.format("> Stack frame in position %s:", offset));
                printStack(printer, f.debugStack);
            }
            popCauseFrame(f);
            offset--;
        }
        printer.trace(System.err);
        if (offset == -1) {
            // so we throw an exception.
            throw new IllegalStateException("Cause Stack Frame Corruption! Attempted to pop a frame that was not on the stack.");
        }
        return;
    }
    this.frames.pop();
    // Remove new values
    boolean ctxInvalid = false;
    if (frame.hasNew()) {
        frame.getNew().forEach(this.ctx::remove);
        ctxInvalid = true;
    }
    // Restore old values
    if (frame.hasStoredValues()) {
        for (Map.Entry<EventContextKey<?>, Object> e : frame.getStoredValues()) {
            this.ctx.put(e.getKey(), e.getValue());
        }
        ctxInvalid = true;
    }
    if (ctxInvalid) {
        this.cachedCtx = null;
    }
    // If there were any objects left on the stack then we pop them off
    while (this.cause.size() > this.minDepth) {
        this.cause.pop();
    }
    this.minDepth = frame.oldMinDepth;
}
Also used : PrettyPrinter(org.lanternpowered.server.util.PrettyPrinter) EventContextKey(org.spongepowered.api.event.cause.EventContextKey) HashMap(java.util.HashMap) Map(java.util.Map)

Aggregations

HashMap (java.util.HashMap)1 Map (java.util.Map)1 PrettyPrinter (org.lanternpowered.server.util.PrettyPrinter)1 EventContextKey (org.spongepowered.api.event.cause.EventContextKey)1