Add asynchronous event API from issue #200
This commit is contained in:
parent
1edd27963f
commit
692610cd7e
72
api/src/main/java/net/md_5/bungee/api/event/AsyncEvent.java
Normal file
72
api/src/main/java/net/md_5/bungee/api/event/AsyncEvent.java
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
package net.md_5.bungee.api.event;
|
||||||
|
|
||||||
|
import com.google.common.base.Preconditions;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.ToString;
|
||||||
|
import net.md_5.bungee.api.Callback;
|
||||||
|
import net.md_5.bungee.api.plugin.Event;
|
||||||
|
import net.md_5.bungee.api.plugin.Plugin;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents an event which depends on the result of asynchronous operations.
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@ToString(callSuper = true)
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
public class AsyncEvent extends Event
|
||||||
|
{
|
||||||
|
|
||||||
|
private final Callback done;
|
||||||
|
private final Set<Plugin> intents = Collections.newSetFromMap( new ConcurrentHashMap<Plugin, Boolean>() );
|
||||||
|
private final AtomicBoolean fired = new AtomicBoolean();
|
||||||
|
private final AtomicInteger latch = new AtomicInteger();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public void postCall()
|
||||||
|
{
|
||||||
|
fired.set( true );
|
||||||
|
if ( latch.get() == 0 )
|
||||||
|
{
|
||||||
|
done.done( this, null );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register an intent that this plugin will continue to perform work on a
|
||||||
|
* background task, and wishes to let the event proceed once the registered
|
||||||
|
* background task has completed.
|
||||||
|
*
|
||||||
|
* @param plugin the plugin registering this intent
|
||||||
|
*/
|
||||||
|
public void registerIntent(Plugin plugin)
|
||||||
|
{
|
||||||
|
Preconditions.checkState( !fired.get(), "Event %s has already been fired", this );
|
||||||
|
Preconditions.checkState( !intents.contains( plugin ), "Plugin %s already registered intent for event %s", plugin, this );
|
||||||
|
|
||||||
|
intents.add( plugin );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notifies this event that this plugin has done all its required processing
|
||||||
|
* and wishes to let the event proceed.
|
||||||
|
*
|
||||||
|
* @param plugin a plugin which has an intent registered for this evemt
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public void completeIntent(Plugin plugin)
|
||||||
|
{
|
||||||
|
Preconditions.checkState( intents.contains( plugin ), "Plugin %s has not registered intent for event %s", plugin, this );
|
||||||
|
intents.remove( plugin );
|
||||||
|
if ( latch.decrementAndGet() == 0 )
|
||||||
|
{
|
||||||
|
done.done( this, null );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -5,4 +5,11 @@ package net.md_5.bungee.api.plugin;
|
|||||||
*/
|
*/
|
||||||
public abstract class Event
|
public abstract class Event
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method called after this event has been dispatched to all handlers.
|
||||||
|
*/
|
||||||
|
public void postCall()
|
||||||
|
{
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -227,8 +227,11 @@ public class PluginManager
|
|||||||
*/
|
*/
|
||||||
public <T extends Event> T callEvent(T event)
|
public <T extends Event> T callEvent(T event)
|
||||||
{
|
{
|
||||||
|
Preconditions.checkNotNull( event, "event" );
|
||||||
|
|
||||||
long start = System.nanoTime();
|
long start = System.nanoTime();
|
||||||
eventBus.post( event );
|
eventBus.post( event );
|
||||||
|
event.postCall();
|
||||||
// TODO: No exceptions!
|
// TODO: No exceptions!
|
||||||
if ( !( event instanceof LoginEvent ) )
|
if ( !( event instanceof LoginEvent ) )
|
||||||
{
|
{
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package net.md_5.bungee.tablist;
|
package net.md_5.bungee.tablist;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Collections;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import net.md_5.bungee.BungeeCord;
|
import net.md_5.bungee.BungeeCord;
|
||||||
import net.md_5.bungee.UserConnection;
|
import net.md_5.bungee.UserConnection;
|
||||||
@ -12,9 +13,7 @@ import net.md_5.bungee.packet.PacketC9PlayerListItem;
|
|||||||
public class GlobalTabList implements TabListHandler
|
public class GlobalTabList implements TabListHandler
|
||||||
{
|
{
|
||||||
|
|
||||||
// Sweet trick to avoid locking, basically reimplement HashSet based on a ConcurrentHashMap
|
private final Set<ProxiedPlayer> sentPings = Collections.newSetFromMap( new ConcurrentHashMap<ProxiedPlayer, Boolean>() );
|
||||||
private static final Object PRESENT = new Object();
|
|
||||||
private final Map<ProxiedPlayer, Object> sentPings = new ConcurrentHashMap<>();
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onConnect(ProxiedPlayer player)
|
public void onConnect(ProxiedPlayer player)
|
||||||
@ -22,7 +21,7 @@ public class GlobalTabList implements TabListHandler
|
|||||||
UserConnection con = (UserConnection) player;
|
UserConnection con = (UserConnection) player;
|
||||||
for ( ProxiedPlayer p : ProxyServer.getInstance().getPlayers() )
|
for ( ProxiedPlayer p : ProxyServer.getInstance().getPlayers() )
|
||||||
{
|
{
|
||||||
con.sendPacket(new PacketC9PlayerListItem( p.getDisplayName(), true, p.getPing() ) );
|
con.sendPacket( new PacketC9PlayerListItem( p.getDisplayName(), true, p.getPing() ) );
|
||||||
}
|
}
|
||||||
BungeeCord.getInstance().broadcast( new PacketC9PlayerListItem( player.getDisplayName(), true, player.getPing() ) );
|
BungeeCord.getInstance().broadcast( new PacketC9PlayerListItem( player.getDisplayName(), true, player.getPing() ) );
|
||||||
}
|
}
|
||||||
@ -30,10 +29,10 @@ public class GlobalTabList implements TabListHandler
|
|||||||
@Override
|
@Override
|
||||||
public void onPingChange(ProxiedPlayer player, int ping)
|
public void onPingChange(ProxiedPlayer player, int ping)
|
||||||
{
|
{
|
||||||
if ( !sentPings.containsKey( player ) )
|
if ( !sentPings.contains( player ) )
|
||||||
{
|
{
|
||||||
BungeeCord.getInstance().broadcast( new PacketC9PlayerListItem( player.getDisplayName(), true, player.getPing() ) );
|
BungeeCord.getInstance().broadcast( new PacketC9PlayerListItem( player.getDisplayName(), true, player.getPing() ) );
|
||||||
sentPings.put( player, PRESENT );
|
sentPings.add( player );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user