提供: Minecraft Modding Wiki
2012年6月16日 (土) 18:19時点におけるUdonya (トーク | 投稿記録)による版 (大きな記事なので外部化)
(差分) ← 古い版 | 最新版 (差分) | 新しい版 → (差分)
移動先: 案内検索

新しいEventSystemの使い方

Minecraft1.1向けのBukkit API以降、新しいイベントの仕組みが提供されています。
この新しい仕組みは、シンプルでかつ、汎用性・高速性・可読性等に優れています。

解説動画

当項目の、翻訳元記事で紹介されている動画を参照して下さい。
http://wiki.bukkit.org/Introduction_to_the_New_Event_System#Video_Tutorial

基礎

PlayerLoginEventについて説明します。
このイベントは最低限動作するための処理のみを記述するよう心がけ、
極力シンプルに保ちつつ編集していきましょう。

イベントリスナ

まず、イベントを待ち受ける処理(Event Listenerと呼ばれます)が必要です:

public void onPlayerLogin(PlayerLoginEvent event) {
    // Your code here...
}

次に、発生するイベント(Event Handlerと呼ばれます)が必要になります。

イベントハンドラ

イベントハンドラはイベントリスナに対する注釈であり、次のような書き方をします:

@EventHandler // EventPriority.NORMAL がデフォルト値

この記述は、メソッドがイベント優先度がNORMALのイベントハンドラである事を指定します。

イベントハンドラには優先度を指定でき、次のような書き方をします:

@EventHandler(priority = EventPriority.HIGHEST) // 高優先度のイベントとする
@EventHandler(priority = EventPriority.LOW) // 低優先度のイベントとする

以上をまとめると、次のようになります:

@EventHandler
public void onPlayerLogin(PlayerLoginEvent event) {
    // Your code here...
}

リスナの追加

"PlayerListener"として拡張する場合は、"Listener"インタフェースを実装する必要があります。
この時点では、次のような形のメソッドになりそうです:

public class myPlayerListener implements Listener {
    @EventHandler
    public void onPlayerLogin(PlayerLoginEvent event) {
        // Your code here...
    }
}

リスナ内部のメソッドは任意の名前を付けて呼び出する事が可能であり、
"onPlayerLogin()"のような、メソッドの名称が重要ではない事に言及しておきましょう。
「Bukkitは、どのEventを識別可能でどうやってListenするのか?」と不思議に思うかもしれませんが・・・
Bukkitは、あなたが指定したイベントからそれら(識別可能なEventと、そのListenの方法)を読み込みます。
上記の例で言えば、PlayerLoginEventから読み込みます。

Note: 特定のイベントまたはBukkitが登録しないイベントに関しては、手動で指定しなければなりません。(訳が不適切か)

イベントハンドラの設定

イベントハンドラには、様々な内容を指定可能です。
現時点では次のような指定が行えます:

項目名 デフォルト値 概要 指定できる値
EventPriority priority EventPriority.NORMAL リスナに指定する優先度。
  • EventPriority.MONITOR
  • EventPriority.HIGHEST
  • EventPriority.HIGH
  • EventPriority.NORMAL
  • EventPriority.LOW
  • EventPriority.LOWEST
boolean ignoreCancelled false この値にTrueを指定したメソッド場合は、イベントがキャンセルされた際にイベントを受け付けない。
  • true
  • false

イベントの登録

イベントを記述するクラスは、
Listenerインタフェースを実装(implements)し、かつイベントハンドラを含んでいなければなりません。

import org.bukkit.event.Listener;

public class LoginListener implements Listener {
}

イベントの登録処理は、PluginManagerインスタンスのregisterEventsメソッドとして、プラグインとリスナに記述します。

getServer().getPluginManager().registerEvents(Listener, Plugin);

リスナの例

このリスナは、2つのイベントハンドラを含んでいます。
1つは高優先度のもの、もうひとつは通常の優先度のものです。

import org.bukkit.event.Listener;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.player.PlayerLoginEvent;
 
public class LoginListener implements Listener {
    @EventHandler
    public void normalLogin(PlayerLoginEvent event) {
        // 何かの処理
    }
 
    @EventHandler(priority = EventPriority.HIGH)
    public void highLogin(PlayerLoginEvent event) {
        // 何かの処理
    }
}

プラグインへのイベントの登録

イベントの登録処理は、リスナとプラグインが必要です。
丁度よい事に、既にLoginListenerを作成していますので、これを利用してLoginPluginを作りましょう!

import org.bukkit.plugin.java.JavaPlugin;

public class LoginPlugin extends JavaPlugin {
    public void onEnable() {
        getServer().getPluginManager().registerEvents(new LoginListener(), this);
    }
}

プラグインへのイベントのリスナとしての登録

メインとなるクラスもイベントを持つ事ができます。
例:

import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.event.Listener;
import org.bukkit.event.EventHandler;
import org.bukkit.event.player.PlayerLoginEvent;
 
public class LoginPlugin extends JavaPlugin implements Listener {
    public void onEnable() {
        getServer().getPluginManager().registerEvents(this, this);
    }
 
    @EventHandler
    public void normalLogin(PlayerLoginEvent event) {
        // 何かの処理
    }
}

リスナへのイベントの登録

イベントの登録には複数の方法があります。リスナクラスでイベントを登録する例を記述します。

import org.bukkit.event.Listener;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.player.PlayerLoginEvent;
 
public class LoginListener implements Listener {
    public LoginListener(LoginPlugin plugin) {
        plugin.getServer().getPluginManager().registerEvents(this, plugin);
    }
 
    @EventHandler
    public void normalLogin(PlayerLoginEvent event) {
        // Some code here
    }
 
    @EventHandler(priority = EventPriority.HIGH)
    public void highLogin(PlayerLoginEvent event) {
        // Some code here
    }
}

LoginPluginは次のようになります:

import org.bukkit.plugin.java.JavaPlugin;
 
public class LoginPlugin extends JavaPlugin {
    public void onEnable() {
        new LoginListener(this);
    }
}

イベントの自作

Bukkit自体が利用しているイベント記述の仕組みと全く同一の仕組みを利用して、 イベントを自作する事ができます。 この方法は、従来のような、 自作イベントである事に起因する固有のチェックが不要な点、 Bukkitの処理方法をそのまま利用するためにパフォーマンスを犠牲にしないという点で、 従来のイベント自作の方法よりも優れています。

イベントを自作する際は、次の2点に留意して下さい。

  • Eventクラスを継承する必要がある
  • static(静的)なハンドラとして作成する必要がある

staticハンドラは、自作イベント中に次のように記述して下さい。

private static final HandlerList handlers = new HandlerList();
 
public HandlerList getHandlers() {
    return handlers;
}
 
public static HandlerList getHandlerList() {
    return handlers;
}

上記のコードを実際に自作のイベント処理の中に記述する事で、 処理は疎結合となり、実行速度が改善します。

自作イベントの例

import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
 
public class CustomEvent extends Event {
    private static final HandlerList handlers = new HandlerList();
    private String message;
 
    public CustomEvent(String example) {
        message = example;
    }
 
    public String getMessage() {
        return message;
    }
 
    public HandlerList getHandlers() {
        return handlers;
    }
 
    public static HandlerList getHandlerList() {
        return handlers;
    }
}

自作イベントの呼び出し

イベントの呼び出し方法は、従来の方法と同様です:

// イベントのインスタンス化
CustomEvent event = new CustomEvent("Sample Message");
// イベントの実行
Bukkit.getServer().getPluginManager().callEvent(event);
// イベントから得たメッセージの出力処理
Bukkit.getServer().broadcastMessage(event.getMessage());

自作イベントの待ち受け

イベントはどのようにListen(待受,受付などとも表記)すれば良いでしょう? 簡単です。通常のイベントと同様に待ち受けして下さい。

import org.bukkit.event.Listener;
import org.bukkit.event.EventHandler;
 
public class CustomListener implements Listener {
    @EventHandler
    public void normalLogin(CustomEvent event) {
        // 何かの処理
    }
}