最新版 |
編集中の文章 |
1行目: |
1行目: |
| ==はじめに== | | ==はじめに== |
− | Minecraft Forge Universalから新しいEventシステムが組み込まれた。ある処理にこちらの用意した処理を割り込ませる機能であり、介入しづらい処理にも介入できるようになりました。<br> | + | Minecraft Forge Universalから新しいEventシステムが組み込まれた。ある処理にこちらの用意した処理を割り込ませる機能であり、介入しづらいバニラの処理にも介入できるようになる。<br> |
− | BukkitPluginのEventシステムと考え方は同じです。<br>
| + | BukkitPluginのEventシステムやFMLの@ModなどもこのEventシステムと同じ概念である。<br> |
− | 詳しく知りたい場合は、DI(依存性の注入)やAOP(アスペクト指向)などの概念、Struts2, SpringFrameworkなどの有名なフレームワークがキーワードとなるかもしれません。 | + | 詳しく知りたい場合は、DI(依存性の注入)やAOP(アスペクト指向)などの概念、Struts2, SpringFrameworkなどの有名なフレームワークがキーワードとなるだろう。 |
| | | |
− | == 基礎 ==
| |
− | 説明を抽象化するため、SampleEventという架空のイベントを仮定して説明します。<br>
| |
| | | |
− | メソッドにアノテーションと引数を指定すると、引数に指定したイベントの発火に合わせて呼び出されるようになります。<br>
| + | ==基本== |
− | 引数でイベントを指定するため、メソッド名は自由に設定できます。
| + | メソッドにアノテーションと引数を指定すると、イベント発火に合わせて呼び出されるようになる。 |
| <source lang = "java"> | | <source lang = "java"> |
| @SubscribeEvent | | @SubscribeEvent |
− | public void onSampleEvent(SampleEvent event) { | + | public void onSampleEvent(SampleEvent event) |
| + | { |
| } | | } |
| </source> | | </source> |
− | このメソッドの場合はSampleEventがEventBusを介してpostされる箇所で呼び出されます。メソッドを持つクラスまたはそのインスタンスは適切な箇所でEventBusに登録する必要があります。
| + | このメソッドはSampleEventクラスがpostされる箇所で呼び出される。メソッドを持つクラスは適切な箇所でMinecraftForgeのAPIを使って登録する必要がある。 |
− | | |
− | Minecraft Forgeの扱えるEventは[[Minecraft Forge API#イベント]]を参照すること。
| |
− | | |
− | == 解説 ==
| |
− | | |
− | === イベントハンドラ ===
| |
− | 処理を挟み込むには、イベントを待ち受けるメソッド(Event Handlerと呼ばれます)を作成します:
| |
− | <source lang="java">
| |
− | public void onSampleEvent(SampleEvent event) {
| |
− | // ここに処理を書きます...
| |
− | }
| |
− | </source>
| |
− | このままではただのメソッドなので、SubscribeEventアノテーションをつけてイベントハンドラであることを明示しなければなりません。
| |
− | | |
− | === SubscribeEventアノテーション ===
| |
− | SubscribeEventアノテーションをメソッドにつけることでメソッドがハンドラであることを明示し、引数に取ったイベントを購読できるようになります。
| |
− | | |
− | SubscribeEventアノテーションはメソッドを対象に取るアノテーションです。最も簡潔な記述は以下のとおりです:
| |
− | <source lang="java">@SubscribeEvent</source>
| |
− | この場合は、メソッドは優先度NORMALのイベントハンドラであるという指定になります。
| |
− | | |
− | 以上をまとめると、次のようになります:
| |
− | <source lang="java">@SubscribeEvent
| |
− | public void onSampleEvent(SampleEvent event) {
| |
− | // ここに処理を書きます...
| |
− | }</source>
| |
− | | |
− | ==== イベントハンドラの設定 ====
| |
− | SubscribeEventアノテーションでは、ハンドラについて設定できます。<br />
| |
− | 現時点では次のような指定が行えます:
| |
− | {| class="wikitable"
| |
− | |型
| |
− | |項目名
| |
− | |デフォルト値
| |
− | |概要
| |
− | |指定できる値
| |
− | |-
| |
− | |EventPriority
| |
− | |priority
| |
− | |EventPriority.NORMAL
| |
− | |ハンドラの優先度。
| |
− | |
| |
− | * EventPriority.HIGHEST
| |
− | * EventPriority.HIGH
| |
− | * EventPriority.NORMAL
| |
− | * EventPriority.LOW
| |
− | * EventPriority.LOWEST
| |
− | |-
| |
− | |boolean
| |
− | |receiveCanceled
| |
− | |false
| |
− | |この値にtrueを指定した場合は、イベントがキャンセルされた際にイベントを購読しない。
| |
− | |
| |
− | * true
| |
− | * false
| |
− | |}
| |
− | | |
− | ===== イベントの優先度 =====
| |
− | | |
− | 上記の表にあるように、イベントの優先度は5種類ありますが、イベントが呼び出される順序は下記のようになっています。
| |
− | | |
− | # EventPriority.HIGHEST
| |
− | # EventPriority.HIGH
| |
− | # EventPriority.NORMAL
| |
− | # EventPriority.LOW
| |
− | # EventPriority.LOWEST
| |
− | | |
− | 優先度が高いものから順繰りに実行されていきます。<br>
| |
− | HIGHESTなど高い優先度のハンドラでイベントがキャンセルされると、それ以下の優先度かつreceiveCanceledがtrueの場合ハンドラの処理がスキップされるということです。
| |
− | | |
− | === イベントハンドラの登録 ===
| |
− | 以上のようにメソッドを記述した上で、EventBusにそのメソッドを記述したクラスやそのインスタンスを登録しなければなりません。<br>
| |
− | | |
− | 記述しているメソッドが購読するイベントに応じて、登録するEventBusは変わります。<br>
| |
− | | |
− | 例えば、ForgeEventHookというクラスにMinecraftForge.EVENT_BUSで発火されるイベントのハンドラを記述した場合は
| |
| <source lang = "java"> | | <source lang = "java"> |
| MinecraftForge.EVENT_BUS.register(new ForgeEventHook()) | | MinecraftForge.EVENT_BUS.register(new ForgeEventHook()) |
| </source> | | </source> |
− | または
| + | MinecraftForge.EVENT_BUSに限っては、@EventBusSubscriberでクラスを注釈すれば自動的に登録され、静的メソッドであれば対応したタイミングに呼び出されるようになる。 |
− | <source lang = "java">
| |
− | MinecraftForge.EVENT_BUS.register(ForgeEventHook.class) | |
− | </source>
| |
− | というように登録します。
| |
| | | |
− | インスタンスで登録した場合は、インスタンスメソッドでハンドラを記述します。<br>
| + | ここでは具体的なサンプルは扱わず、SampleEventというEventも存在しないが、Forgeのイベントの使い方の流れは大体このようであると認識して良い。 |
− | クラスで登録した場合は、クラスメソッドでハンドラを記述します。<br>
| |
− | MinecraftForge.EVENT_BUSに限っては、@EventBusSubscriberでクラスを注釈すれば自動的に登録されます。<br>
| |
− | この場合は、クラスメソッドでハンドラを記述します。
| |
| | | |
− | MinecraftForgeが提供するEventBusには三種類あります。
| + | Minecraft Forgeの扱えるEventは[[Minecraft Forge API#イベント]]を参照すること。 |
− | ; MinecraftForge.EVENT_BUS
| |
− | : 基本的なイベント群はここから発火される。以下のBusで発火されないイベントはここと覚えれば良い。
| |
− | ; MinecraftForge.TERRAIN_GEN_BUS
| |
− | : 地形生成に関するイベントはここから発火される。
| |
− | ; MinecraftForge.ORE_GEN_BUS
| |
− | : 鉱石生成に関するイベントはここから発火される。
| |
− | | |
− | 以前はFMLCommonHandler.instance().bus()という物もありましたが、MinecraftForge.EVENT_BUSに統合されました。
| |
− | | |
− | === 利用可能なメソッド解説 ===
| |
− | イベントによって様々あるが、ここではベースクラス[[Event]]について解説する。
| |
− | | |
− | ==== イベントのキャンセル ====
| |
− | イベントがCancelableな場合は、イベントをキャンセルできます。<br>
| |
− | 具体的にはsetCanceledでtrueを渡すとキャンセルすることになります。<br>
| |
− | イベントがCancelableかどうかは、そのイベントにCancelableアノテーションがついているかによって判断できます。<br>
| |
− | スキップできる処理はイベントによって異なりますが、バニラの処理と後述するreceiveCanceledがtrueのハンドラの処理が対象になります。<br>
| |
− | 詳しくはそれぞれのEventのドキュメントを参照しています。
| |
− | | |
− | ==== イベントの結果 ====
| |
− | イベントがHasResultな場合は、イベントに結果を持たせられます。<br>
| |
− | 具体的にはsetResultを呼び出すことで結果を決定できます。<br>
| |
− | イベントがHasResultかどうかは、そのイベントにHasResultアノテーションがついているかによって判断できます。<br>
| |
− | ResultはDENY,DEFAULT,ALLOWの三値をとります。<br>
| |
− | 各イベントで若干意味は異なりますが、基本的には
| |
− | それぞれ、
| |
− | ; DENY
| |
− | : 強制不成功。イベントをキャンセルするのによく似る。
| |
− | ; DEFAULT
| |
− | : 判定をバニラと同様にする。結果への不介入。処理は挟むが、その後の処理については別に干渉したくない場合に用いる。
| |
− | ; ALLOW
| |
− | : 強制成功。DENYの全く逆。
| |
− | | |
− | == イベントの自作 ==
| |
− | Minecraft Forgeの利用しているイベントの仕組みと全く同一の仕組みを利用して、イベントを自作できます。<br>
| |
− | 自作と言っても、Eventクラスを継承していればイベントとして機能しますので、好きに設計することができます。<br>
| |
− | クラスを作成すれば、あとは任意のタイミングで任意のEventBusからpostを呼び出せば発火できます。
| |
− | | |
− | CancelableやHasResultの指定も同様に行えますが、その場合スキップ判定等は自分で行わなければならないことに注意してください。
| |