use of org.spongepowered.api.event.CauseStackManager.StackFrame in project SpongeCommon by SpongePowered.
the class TrackingUtil method throwMultiEventsAndCreatePost.
public static ChangeBlockEvent.Post throwMultiEventsAndCreatePost(ImmutableList<Transaction<BlockSnapshot>>[] transactionArrays, List<ChangeBlockEvent> blockEvents, ChangeBlockEvent[] mainEvents) {
if (!blockEvents.isEmpty()) {
try (StackFrame frame = Sponge.getCauseStackManager().pushCauseFrame()) {
for (BlockChange blockChange : BlockChange.values()) {
final ChangeBlockEvent mainEvent = mainEvents[blockChange.ordinal()];
if (mainEvent != null) {
Sponge.getCauseStackManager().pushCause(mainEvent);
}
}
final ImmutableList<Transaction<BlockSnapshot>> transactions = transactionArrays[MULTI_CHANGE_INDEX];
final ChangeBlockEvent.Post post = SpongeEventFactory.createChangeBlockEventPost(Sponge.getCauseStackManager().getCurrentCause(), transactions);
SpongeImpl.postEvent(post);
return post;
}
}
return null;
}
use of org.spongepowered.api.event.CauseStackManager.StackFrame in project SpongeCommon by SpongePowered.
the class TrackingUtil method randomTickBlock.
public static void randomTickBlock(PhaseTracker phaseTracker, IMixinWorldServer mixinWorld, Block block, BlockPos pos, IBlockState state, Random random) {
final WorldServer minecraftWorld = mixinWorld.asMinecraftWorld();
try (@SuppressWarnings("unused") StackFrame frame = Sponge.getCauseStackManager().pushCauseFrame()) {
Sponge.getCauseStackManager().pushCause(minecraftWorld);
if (ShouldFire.TICK_BLOCK_EVENT) {
final BlockSnapshot currentTickBlock = mixinWorld.createSpongeBlockSnapshot(state, state, pos, BlockChangeFlags.NONE);
final TickBlockEvent event = SpongeEventFactory.createTickBlockEventRandom(Sponge.getCauseStackManager().getCurrentCause(), currentTickBlock);
SpongeImpl.postEvent(event);
if (event.isCancelled()) {
return;
}
}
final LocatableBlock locatable = LocatableBlock.builder().location(new Location<>(mixinWorld.asSpongeWorld(), pos.getX(), pos.getY(), pos.getZ())).state((BlockState) state).build();
Sponge.getCauseStackManager().pushCause(locatable);
IPhaseState<BlockTickContext> phase = ((IMixinBlock) block).requiresBlockCapture() ? TickPhase.Tick.RANDOM_BLOCK : TickPhase.Tick.NO_CAPTURE_BLOCK;
final BlockTickContext phaseContext = phase.createPhaseContext().source(locatable);
checkAndAssignBlockTickConfig(block, minecraftWorld, phaseContext);
// We have to associate any notifiers in case of scheduled block updates from other sources
final PhaseData current = phaseTracker.getCurrentPhaseData();
final IPhaseState<?> currentState = current.state;
((IPhaseState) currentState).appendNotifierPreBlockTick(mixinWorld, pos, current.context, phaseContext);
// Now actually switch to the new phase
try (PhaseContext<?> context = phaseContext.buildAndSwitch()) {
block.randomTick(minecraftWorld, pos, state, random);
} catch (Exception | NoClassDefFoundError e) {
phaseTracker.printExceptionFromPhase(e, phaseContext);
}
}
}
use of org.spongepowered.api.event.CauseStackManager.StackFrame in project SpongeCommon by SpongePowered.
the class TrackingUtil method tickRidingEntity.
public static void tickRidingEntity(net.minecraft.entity.Entity entity) {
checkArgument(entity instanceof Entity, "Entity %s is not an instance of SpongeAPI's Entity!", entity);
checkNotNull(entity, "Cannot capture on a null ticking entity!");
final IMixinEntity mixinEntity = EntityUtil.toMixin(entity);
if (!mixinEntity.shouldTick()) {
return;
}
final Optional<User> notifierUser = mixinEntity.getNotifierUser();
final Optional<User> creatorUser = mixinEntity.getCreatorUser();
final EntityTickContext tickContext = TickPhase.Tick.ENTITY.createPhaseContext().source(entity).notifier(() -> notifierUser).owner(() -> creatorUser);
try (final StackFrame frame = Sponge.getCauseStackManager().pushCauseFrame();
final EntityTickContext context = tickContext.buildAndSwitch();
final Timing entityTiming = mixinEntity.getTimingsHandler().startTiming()) {
Sponge.getCauseStackManager().pushCause(entity);
notifierUser.ifPresent(notifier -> frame.addContext(EventContextKeys.NOTIFIER, notifier));
creatorUser.ifPresent(notifier -> frame.addContext(EventContextKeys.OWNER, notifier));
entity.updateRidden();
} catch (Exception | NoClassDefFoundError e) {
PhaseTracker.getInstance().printExceptionFromPhase(e, tickContext);
}
}
use of org.spongepowered.api.event.CauseStackManager.StackFrame in project SpongeCommon by SpongePowered.
the class TrackingUtil method tickTileEntity.
@SuppressWarnings({ "unused", "try" })
public static void tickTileEntity(IMixinWorldServer mixinWorldServer, ITickable tile) {
checkArgument(tile instanceof TileEntity, "ITickable %s is not a TileEntity!", tile);
checkNotNull(tile, "Cannot capture on a null ticking tile entity!");
final net.minecraft.tileentity.TileEntity tileEntity = (net.minecraft.tileentity.TileEntity) tile;
final IMixinTileEntity mixinTileEntity = (IMixinTileEntity) tile;
final BlockPos pos = tileEntity.getPos();
final IMixinChunk chunk = ((IMixinTileEntity) tile).getActiveChunk();
if (!mixinTileEntity.shouldTick()) {
return;
}
final TileEntityTickContext context = TickPhase.Tick.TILE_ENTITY.createPhaseContext().source(tile);
try (final StackFrame frame = Sponge.getCauseStackManager().pushCauseFrame();
final PhaseContext<?> phaseContext = context) {
Sponge.getCauseStackManager().pushCause(tile);
// Add notifier and owner so we don't have to perform lookups during the phases and other processing
chunk.getBlockNotifier(pos).ifPresent(notifier -> {
Sponge.getCauseStackManager().addContext(EventContextKeys.NOTIFIER, notifier);
phaseContext.notifier(notifier);
});
User blockOwner = mixinTileEntity.getSpongeOwner();
if (!mixinTileEntity.hasSetOwner()) {
blockOwner = chunk.getBlockOwner(pos).orElse(null);
mixinTileEntity.setSpongeOwner(blockOwner);
}
if (blockOwner != null) {
Sponge.getCauseStackManager().addContext(EventContextKeys.OWNER, blockOwner);
phaseContext.owner(blockOwner);
}
phaseContext.owner = blockOwner;
// Add the block snapshot of the tile entity for caches to avoid creating multiple snapshots during processing
// This is a lazy evaluating snapshot to avoid the overhead of snapshot creation
// Finally, switch the context now that we have the owner and notifier
phaseContext.buildAndSwitch();
try (Timing timing = mixinTileEntity.getTimingsHandler().startTiming()) {
tile.update();
}
} catch (Exception e) {
PhaseTracker.getInstance().printExceptionFromPhase(e, context);
}
}
use of org.spongepowered.api.event.CauseStackManager.StackFrame in project SpongeCommon by SpongePowered.
the class TrackingUtil method tickEntity.
public static void tickEntity(net.minecraft.entity.Entity entityIn) {
checkArgument(entityIn instanceof Entity, "Entity %s is not an instance of SpongeAPI's Entity!", entityIn);
checkNotNull(entityIn, "Cannot capture on a null ticking entity!");
final IMixinEntity mixinEntity = EntityUtil.toMixin(entityIn);
if (!mixinEntity.shouldTick()) {
return;
}
final EntityTickContext tickContext = TickPhase.Tick.ENTITY.createPhaseContext().source(entityIn);
try (final StackFrame frame = Sponge.getCauseStackManager().pushCauseFrame();
final EntityTickContext context = tickContext;
final Timing entityTiming = mixinEntity.getTimingsHandler().startTiming()) {
mixinEntity.getNotifierUser().ifPresent(notifier -> {
frame.addContext(EventContextKeys.NOTIFIER, notifier);
context.notifier(notifier);
});
mixinEntity.getCreatorUser().ifPresent(owner -> {
if (mixinEntity instanceof EntityFallingBlock) {
frame.pushCause(owner);
}
frame.addContext(EventContextKeys.OWNER, owner);
context.owner(owner);
});
context.buildAndSwitch();
entityIn.onUpdate();
} catch (Exception | NoClassDefFoundError e) {
PhaseTracker.getInstance().printExceptionFromPhase(e, tickContext);
}
}
Aggregations