Skip to content

Commit

Permalink
!feat: Add CompositeEvent
Browse files Browse the repository at this point in the history
This also breaks InteractBlockEvent.Secondary and SpawnEntityEvent.Pre
  • Loading branch information
gabizou committed Apr 21, 2024
1 parent cb4ee93 commit ab94acf
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 34 deletions.
51 changes: 51 additions & 0 deletions src/main/java/org/spongepowered/api/event/CompositeEvent.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package org.spongepowered.api.event;

import org.spongepowered.api.util.annotation.eventgen.NoFactoryMethod;

import java.util.List;
import java.util.function.Consumer;

/**
* A {@link CompositeEvent} is an {@link Event} that contains multiple
* side effectual {@link Event Events}, which may have their own side effects
* and may be {@link Cancellable}. In some cases, the interactions of this event
* may be cancellable as a whole, but are not guaranteed to revert all side
* effects on the {@link org.spongepowered.api.Game}. The {@link #children()} of
* this event are ordered in a "best-effort" basis, and may not be guaranteed
* to be in any particular order.
* <p>Using {@link #setCancelled(boolean)} will perform a best effort cancellation
* on each of the children events.
*/
@NoFactoryMethod
public interface CompositeEvent<E extends Event> extends Event, Cancellable {

E baseEvent();

List<Event> children();

default <E extends Event> List<? extends E> event(Class<E> type) {
return this.children().stream()
.filter(type::isInstance)
.map(type::cast)
.toList();
}

default <E extends Event> void applyTo(Class<E> type, Consumer<? super E> consumer) {
this.children().stream()
.filter(type::isInstance)
.map(type::cast)
.forEach(consumer);
}

/**
* {@inheritDoc}
*
* Cancels this event and all related events captured {@link #children()}.
* Selectively, if individual events are wished to be cancelled,
* the individual events should be cancelled instead.
*
* @param cancel The new cancelled state
*/
@Override
void setCancelled(boolean cancel);
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,18 @@
import org.spongepowered.api.block.BlockTypes;
import org.spongepowered.api.entity.living.player.Player;
import org.spongepowered.api.event.Cancellable;
import org.spongepowered.api.event.CompositeEvent;
import org.spongepowered.api.event.action.InteractEvent;
import org.spongepowered.api.event.entity.SpawnEntityEvent;
import org.spongepowered.api.event.item.inventory.ChangeInventoryEvent;
import org.spongepowered.api.item.inventory.ItemStack;
import org.spongepowered.api.util.Direction;
import org.spongepowered.api.util.Tristate;
import org.spongepowered.api.world.server.ServerLocation;
import org.spongepowered.math.vector.Vector3d;

import java.util.Optional;

/**
* Base event for all interactions involving a {@link BlockSnapshot} at a
* {@link ServerLocation}.
Expand Down Expand Up @@ -101,7 +106,7 @@ interface Finish extends Primary, Cancellable {
*
* <p>This is usually right-click.</p>
*/
interface Secondary extends InteractBlockEvent, Cancellable {
interface Secondary extends InteractBlockEvent {

Tristate originalUseItemResult();

Expand Down Expand Up @@ -143,43 +148,47 @@ interface Secondary extends InteractBlockEvent, Cancellable {
*/
Tristate useBlockResult();

/**
* Sets whether the {@link Player#itemInHand} should be used.
*
* <ul>
* <li>FALSE: The {@link ItemStack} will never be used.</li>
* <li>UNDEFINED: The {@link ItemStack} will be used if the block fails.
* </li>
* <li>TRUE: The {@link ItemStack} will always be used.</li>
* </ul>
*
* <p>Note: These results may differ depending on implementation.</p>
*
* @param result Whether the {@link Player#itemInHand} should be used
*/
void setUseItemResult(Tristate result);

/**
* Sets whether the interacted {@link BlockSnapshot} should be used.
*
* <ul>
* <li>FALSE: {@link BlockSnapshot} will never be used.</li>
* <li>UNDEFINED: {@link BlockSnapshot} will be used as normal.</li>
* <li>TRUE: {@link BlockSnapshot} will always be used.</li>
* </ul>
*
* <p>Note: These results may differ depending on implementation.</p>
*
* @param result Whether the interacted {@link BlockSnapshot} should be
* used
*/
void setUseBlockResult(Tristate result);

/**
* Gets the point of interaction where the interaction occurred as a {@link Vector3d}.
*
* @return The interaction point
*/
Vector3d interactionPoint();

interface Pre extends Secondary, Cancellable {

/**
* Sets whether the {@link Player#itemInHand} should be used.
*
* <ul>
* <li>FALSE: The {@link ItemStack} will never be used.</li>
* <li>UNDEFINED: The {@link ItemStack} will be used if the block fails.
* </li>
* <li>TRUE: The {@link ItemStack} will always be used.</li>
* </ul>
*
* <p>Note: These results may differ depending on implementation.</p>
*
* @param result Whether the {@link Player#itemInHand} should be used
*/
void setUseItemResult(Tristate result);

/**
* Sets whether the interacted {@link BlockSnapshot} should be used.
*
* <ul>
* <li>FALSE: {@link BlockSnapshot} will never be used.</li>
* <li>UNDEFINED: {@link BlockSnapshot} will be used as normal.</li>
* <li>TRUE: {@link BlockSnapshot} will always be used.</li>
* </ul>
*
* <p>Note: These results may differ depending on implementation.</p>
*
* @param result Whether the interacted {@link BlockSnapshot} should be
* used
*/
void setUseBlockResult(Tristate result);
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

import org.spongepowered.api.entity.Entity;
import org.spongepowered.api.event.Cause;
import org.spongepowered.api.event.impl.entity.AbstractAffectEntityEvent;
import org.spongepowered.api.event.impl.entity.AbstractSpawnEntityEvent;
import org.spongepowered.api.util.annotation.eventgen.GenerateFactoryMethod;
import org.spongepowered.api.util.annotation.eventgen.ImplementedBy;
Expand All @@ -51,7 +52,8 @@ public interface SpawnEntityEvent extends AffectEntityEvent {
* will result in no awareness to the client that the entity was being
* spawned and later cancelled.
*/
interface Pre extends SpawnEntityEvent {}
@ImplementedBy(value = AbstractAffectEntityEvent.class, priority = 2)
interface Pre extends AffectEntityEvent {}

interface Custom extends SpawnEntityEvent {}
}

0 comments on commit ab94acf

Please sign in to comment.