use of org.spongepowered.api.event.EventContextKey in project SpongeCommon by SpongePowered.
the class PhaseTracker method popCauseFrame.
@Override
public void popCauseFrame(final StackFrame oldFrame) {
checkNotNull(oldFrame, "oldFrame");
this.enforceMainThread();
@Nullable final SpongeCauseStackFrame frame = this.frames.peek();
if (frame != oldFrame) {
// 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 (final SpongeCauseStackFrame f : this.frames) {
if (f == oldFrame) {
offset = i;
break;
}
i++;
}
if (!PhaseTracker.DEBUG_CAUSE_FRAMES && offset == -1) {
// that was erroneously popped.
throw new IllegalStateException("Cause Stack Frame Corruption! Attempted to pop a frame that was not on the stack.");
}
final PrettyPrinter printer = new PrettyPrinter(100).add("Cause Stack Frame Corruption!").centre().hr().add("Found %d frames left on the stack. Clearing them all.", new Object[] { offset + 1 });
if (!PhaseTracker.DEBUG_CAUSE_FRAMES) {
printer.add().add("Please add -Dsponge.debugcauseframes=true to your startup flags to enable further debugging output.");
SpongeCommon.logger().warn(" Add -Dsponge.debugcauseframes to your startup flags to enable further debugging output.");
} else {
printer.add().add("Attempting to pop frame:").add(frame.stackDebug).add().add("Frames being popped are:").add(((SpongeCauseStackFrame) oldFrame).stackDebug);
}
while (offset >= 0) {
@Nullable final SpongeCauseStackFrame f = this.frames.peek();
if (PhaseTracker.DEBUG_CAUSE_FRAMES && offset > 0) {
printer.add(" Stack frame in position %d :", new Object[] { offset });
printer.add(f.stackDebug);
}
this.popCauseFrame(f);
offset--;
}
printer.trace(System.err, SpongeCommon.logger(), Level.ERROR);
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
for (final Map.Entry<EventContextKey<?>, Object> entry : frame.getOriginalContextDelta().entrySet()) {
this.cached_ctx = null;
if (entry.getValue() == null) {
// wasn't present before, remove
this.ctx.remove(entry.getKey());
} else {
// was there, replace
this.ctx.put(entry.getKey(), entry.getValue());
}
}
// If there were any objects left on the stack then we pop them off
while (this.cause.size() > this.min_depth) {
final int index = this.cause.size();
// there was a duplicate cause pushed prior to the frame being popped.
if (this.duplicateCauses.length > index) {
// At this point, we now need to "clean" the duplicate causes array of duplicates
// to avoid potentially pruning earlier frame's potentially duplicate causes.
// And of course, reset the number of duplicates in the entry.
this.duplicateCauses[index] = 0;
}
this.cause.pop();
// and clear the cached causes
this.cached_cause = null;
}
this.min_depth = frame.old_min_depth;
final int size = this.cause.size();
if (this.duplicateCauses.length > size) {
// Then set the last cause index to whatever the size of the entry was at the time.
this.duplicateCauses[size] = frame.lastCauseSize;
}
// finally, return the frame to the pool
if (this.framePool.size() < PhaseTracker.MAX_POOL_SIZE) {
// cache it, but also call clear so we remove references to
// other objects that may go out of scope
frame.clear();
this.framePool.push(frame);
}
}
use of org.spongepowered.api.event.EventContextKey in project SpongeCommon by SpongePowered.
the class ContextValueFilterSourceDelegate method insertCauseCall.
@Override
protected void insertCauseCall(final MethodVisitor mv, final ListenerClassVisitor.ListenerParameter param, final Type targetType) {
final Field targetField;
try {
targetField = EventContextKeys.class.getField(this.anno.value());
} catch (final NoSuchFieldException ex) {
throw new IllegalArgumentException(String.format("Field %s specified by GetValue annotation was not found in EventContextKeys", this.anno.value()));
}
if (!EventContextKey.class.isAssignableFrom(targetField.getType())) {
throw new IllegalArgumentException(String.format("Field %s.%s was not an EventContextKey", targetField.getName(), targetField.getType()));
}
// cause.context().get(EventContextKeys.<anno.value()>
mv.visitMethodInsn(INVOKEVIRTUAL, CauseFilterSourceDelegate.CAUSE.getInternalName(), "context", "()" + ContextValueFilterSourceDelegate.EVENT_CONTEXT.getDescriptor(), false);
mv.visitFieldInsn(GETSTATIC, ContextValueFilterSourceDelegate.EVENT_CONTEXT_KEYS.getInternalName(), this.anno.value(), ContextValueFilterSourceDelegate.EVENT_CONTEXT_KEY.getDescriptor());
mv.visitMethodInsn(INVOKEVIRTUAL, ContextValueFilterSourceDelegate.EVENT_CONTEXT.getInternalName(), "get", Type.getMethodDescriptor(ParameterFilterSourceDelegate.OPTIONAL, ContextValueFilterSourceDelegate.EVENT_CONTEXT_KEY), false);
}
Aggregations