Search in sources :

Example 1 with TransactionType

use of org.spongepowered.common.event.tracking.context.transaction.type.TransactionType in project SpongeCommon by SpongePowered.

the class TransactionalCaptureSupplier method generateEventForTransaction.

@SuppressWarnings("unchecked")
private static <E extends Event & Cancellable> void generateEventForTransaction(@NonNull final GameTransaction<E> pointer, @Nullable final GameTransaction<@NonNull ?> parent, final PhaseContext<@NonNull ?> context, final ImmutableList.Builder<EventByTransaction<@NonNull ?>> builder, final ImmutableList<GameTransaction<E>> transactions, final ImmutableMultimap.Builder<TransactionType, ? extends Event> transactionPostEventBuilder) {
    final Optional<BiConsumer<PhaseContext<@NonNull ?>, CauseStackManager.StackFrame>> frameMutator = pointer.getFrameMutator(parent);
    final PhaseTracker instance = PhaseTracker.getInstance();
    try (final CauseStackManager.StackFrame frame = frameMutator.map(mutator -> {
        final CauseStackManager.StackFrame transactionFrame = instance.pushCauseFrame();
        mutator.accept(context, transactionFrame);
        return transactionFrame;
    }).orElseGet(instance::pushCauseFrame)) {
        final Optional<E> generatedEvent = pointer.generateEvent(context, parent, transactions, instance.currentCause());
        generatedEvent.ifPresent(e -> {
            final EventByTransaction<E> element = new EventByTransaction<>(e, transactions, parent, pointer);
            builder.add(element);
            ((ImmutableMultimap.Builder) transactionPostEventBuilder).put(pointer.getTransactionType(), e);
        });
        for (final GameTransaction<E> transaction : transactions) {
            if (transaction.sideEffects == null || transaction.sideEffects.isEmpty()) {
                continue;
            }
            generatedEvent.ifPresent(frame::pushCause);
            for (final ResultingTransactionBySideEffect sideEffect : transaction.sideEffects) {
                if (sideEffect.head == null) {
                    continue;
                }
                builder.addAll(TransactionalCaptureSupplier.batchTransactions(sideEffect.head, pointer, context, transactionPostEventBuilder));
            }
        }
    }
}
Also used : NonNull(org.checkerframework.checker.nullness.qual.NonNull) Iterator(java.util.Iterator) Event(org.spongepowered.api.event.Event) Spliterators(java.util.Spliterators) Sponge(org.spongepowered.api.Sponge) SpongeCommon(org.spongepowered.common.SpongeCommon) PhaseTracker(org.spongepowered.common.event.tracking.PhaseTracker) MonotonicNonNull(org.checkerframework.checker.nullness.qual.MonotonicNonNull) PrepareBlockDrops(org.spongepowered.common.event.tracking.context.transaction.effect.PrepareBlockDrops) Objects(java.util.Objects) ImmutableList(com.google.common.collect.ImmutableList) Cancellable(org.spongepowered.api.event.Cancellable) ICaptureSupplier(org.spongepowered.common.event.tracking.context.ICaptureSupplier) PhaseContext(org.spongepowered.common.event.tracking.PhaseContext) StringJoiner(java.util.StringJoiner) BiConsumer(java.util.function.BiConsumer) Optional(java.util.Optional) TransactionType(org.spongepowered.common.event.tracking.context.transaction.type.TransactionType) ImmutableMultimap(com.google.common.collect.ImmutableMultimap) CauseStackManager(org.spongepowered.api.event.CauseStackManager) Collections(java.util.Collections) Spliterator(java.util.Spliterator) Nullable(org.checkerframework.checker.nullness.qual.Nullable) PhaseTracker(org.spongepowered.common.event.tracking.PhaseTracker) CauseStackManager(org.spongepowered.api.event.CauseStackManager) BiConsumer(java.util.function.BiConsumer)

Example 2 with TransactionType

use of org.spongepowered.common.event.tracking.context.transaction.type.TransactionType in project SpongeCommon by SpongePowered.

the class TransactionalCaptureSupplier method processTransactions.

@SuppressWarnings("unchecked")
public boolean processTransactions(final PhaseContext<@NonNull ?> context) {
    if (this.head == null) {
        return false;
    }
    final ImmutableMultimap.Builder<TransactionType, ? extends Event> builder = ImmutableMultimap.builder();
    final ImmutableList<EventByTransaction<@NonNull ?>> batched = TransactionalCaptureSupplier.batchTransactions(this.head, null, context, builder);
    boolean cancelledAny = false;
    for (final EventByTransaction<@NonNull ?> eventWithTransactions : batched) {
        final Event event = eventWithTransactions.event;
        if (eventWithTransactions.isParentOrDeciderCancelled()) {
            cancelledAny = true;
            eventWithTransactions.markCancelled();
            continue;
        }
        Sponge.eventManager().post(event);
        if (event instanceof Cancellable && ((Cancellable) event).isCancelled()) {
            eventWithTransactions.markCancelled();
            cancelledAny = true;
        }
        if (((GameTransaction) eventWithTransactions.decider).markCancelledTransactions(event, eventWithTransactions.transactions)) {
            cancelledAny = true;
        }
        for (final GameTransaction<@NonNull ?> transaction : eventWithTransactions.transactions) {
            if (transaction.cancelled) {
                ((GameTransaction) transaction).markEventAsCancelledIfNecessary(eventWithTransactions.event);
            }
            if (!transaction.cancelled) {
                ((GameTransaction) transaction).postProcessEvent(context, event);
            }
        }
    }
    if (cancelledAny) {
        for (final EventByTransaction<@NonNull ?> eventByTransaction : batched.reverse()) {
            if (eventByTransaction.decider.cancelled) {
                ((GameTransaction) eventByTransaction.decider).markEventAsCancelledIfNecessary(eventByTransaction.event);
            }
            for (final GameTransaction<@NonNull ?> gameTransaction : eventByTransaction.transactions.reverse()) {
                if (gameTransaction.cancelled) {
                    ((GameTransaction) gameTransaction).restore(context, eventByTransaction.event);
                }
            }
        }
    }
    builder.build().asMap().forEach((transactionType, events) -> transactionType.createAndProcessPostEvents(context, events));
    return !cancelledAny;
}
Also used : TransactionType(org.spongepowered.common.event.tracking.context.transaction.type.TransactionType) Cancellable(org.spongepowered.api.event.Cancellable) NonNull(org.checkerframework.checker.nullness.qual.NonNull) MonotonicNonNull(org.checkerframework.checker.nullness.qual.MonotonicNonNull) Event(org.spongepowered.api.event.Event) ImmutableMultimap(com.google.common.collect.ImmutableMultimap)

Aggregations

ImmutableMultimap (com.google.common.collect.ImmutableMultimap)2 MonotonicNonNull (org.checkerframework.checker.nullness.qual.MonotonicNonNull)2 NonNull (org.checkerframework.checker.nullness.qual.NonNull)2 Cancellable (org.spongepowered.api.event.Cancellable)2 Event (org.spongepowered.api.event.Event)2 TransactionType (org.spongepowered.common.event.tracking.context.transaction.type.TransactionType)2 ImmutableList (com.google.common.collect.ImmutableList)1 Collections (java.util.Collections)1 Iterator (java.util.Iterator)1 Objects (java.util.Objects)1 Optional (java.util.Optional)1 Spliterator (java.util.Spliterator)1 Spliterators (java.util.Spliterators)1 StringJoiner (java.util.StringJoiner)1 BiConsumer (java.util.function.BiConsumer)1 Nullable (org.checkerframework.checker.nullness.qual.Nullable)1 Sponge (org.spongepowered.api.Sponge)1 CauseStackManager (org.spongepowered.api.event.CauseStackManager)1 SpongeCommon (org.spongepowered.common.SpongeCommon)1 PhaseContext (org.spongepowered.common.event.tracking.PhaseContext)1