(Blockのソース、Tileの解説を修正) |
細 (ComputerCraft API/イベントを発生させる方法をComputerCraft API/イベントの発生へ移動: ページ名を簡単なものに変更) |
(相違点なし)
|
2014年11月13日 (木) 18:35時点における版
この記事は執筆中です。加筆してくださる人を募集しています。 |
この記事は"Minecraft Forge Universal 10.13.0.x~"及び"ComputerCraft 1.65~"を前提MODとしています。 |
目次
周辺機器からイベントを発生させる
右クリックされたとき、接続されたComputerやTurtleに対してイベントを発生させる周辺機器ブロックを追加する。
ソースコード
「周辺機器の追加」のソースコードを元にして、変更部分のみを解説する。
- BlockSamplePeripheral.java
package mods.sample.peripheral; import java.util.Random; import net.minecraft.block.BlockContainer; import net.minecraft.block.material.Material; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.tileentity.TileEntity; import net.minecraft.world.World; public class BlockSamplePeripheral extends BlockContainer { public BlockSamplePeripheral() { super(Material.ground); } @Override public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer entityPlayer, int side, float hitX, float hitY, float hitZ) { TileEntity tile = world.getTileEntity(x, y, z); if (!world.isRemote && tile != null && tile instanceof TileSamplePeripheral) { ((TileSamplePeripheral)tile).click(); } return true; } @Override public int quantityDropped(int meta, int fortune, Random random){ return quantityDroppedWithBonus(fortune, random); } @Override public int quantityDropped(Random random){ return 1; } @Override public TileEntity createNewTileEntity(World world, int a) { return new TileSamplePeripheral(); } }
- TileSamplePeripheral.java
package mods.sample.peripheral; import java.util.HashSet; import java.util.Set; import net.minecraft.tileentity.TileEntity; import dan200.computercraft.api.lua.ILuaContext; import dan200.computercraft.api.lua.LuaException; import dan200.computercraft.api.peripheral.IComputerAccess; import dan200.computercraft.api.peripheral.IPeripheral; public class TileSamplePeripheral extends TileEntity implements IPeripheral { private final Set<IComputerAccess> m_computers; public TileSamplePeripheral() { m_computers = new HashSet(); } @Override public String getType() { return "sample"; } @Override public String[] getMethodNames() { return new String[] {}; } @Override public Object[] callMethod(IComputerAccess computer, ILuaContext context, int method, Object[] arguments) throws LuaException, InterruptedException { return null; } @Override public void attach(IComputerAccess computer) { synchronized (this.m_computers) { this.m_computers.add(computer); } } @Override public void detach(IComputerAccess computer) { synchronized (this.m_computers) { this.m_computers.remove(computer); } } @Override public boolean equals(IPeripheral other) { if ((other != null) && (other instanceof TileSamplePeripheral)) { return other == this; } return false; } public void click() { synchronized (this.m_computers) { for (IComputerAccess computer : this.m_computers) { computer.queueEvent("sample_click", new Object[] {computer.getAttachmentName()} ); } } } }
解説
BlockSamplePeripheral.java
周辺機器ブロックが右クリックされた時の処理を追加する。
@Override public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer entityPlayer, int side, float hitX, float hitY, float hitZ) { TileEntity tile = world.getTileEntity(x, y, z); if (!world.isRemote && tile != null && tile instanceof TileSamplePeripheral) { ((TileSamplePeripheral)tile).click(); } return true; }
ブロックが右クリックされたらTileEntity(周辺機器)を取得してclick()を呼び出す。
TileSamplePeripheral.java
イベント発生の処理と、イベントを発生させるための接続されたComputerやTurtleのリストの管理を追加する。
private final Set<IComputerAccess> m_computers; public TileSamplePeripheral() { m_computers = new HashSet(); }
↑コンストラクタで接続されたComputerやTurtleへイベントを発生させるのに必要なIComputerAccessインスタンスのリストを初期化する。
@Override public void attach(IComputerAccess computer) { synchronized(this.m_computers) { this.m_computers.add(computer); } } @Override public void detach(IComputerAccess computer) { synchronized(this.m_computers) { this.m_computers.remove(computer); } }
↑attach()で接続されたComputerやTurtleのIComputerAccessインスタンスをリストへ追加、detach()で取り外されたComputerやTurtleのComputerAccessインスタンスをリストから削除。
attach()とdetach()はComputerCraftのLuaスレッドから呼び出されている。このリストはMinecraftスレッドから呼び出されるclick()からもアクセスされるのでsynchronizedで排他制御している。
public void click() { synchronized (this.m_computers) { for (IComputerAccess computer : this.m_computers) { computer.queueEvent("sample_click", new Object[] {computer.getAttachmentName()} ); } } }
↑周辺機器ブロックが右クリックされた時に、BlockSamplePeripheralから呼び出される。IComputerAccessインスタンスのリストにある全てのComputerやTurtleへIComputerAccess.queueEvent()で"sample_click"イベントを発生させる。前述の通り、リストへのアクセスは排他的に行っている。
- イベント
イベント名は、発生したイベントの内容が分かりやすいように"周辺機器の種類_イベントの内容"のような形にする事が推奨されている。(APIのjavadoc参照)
queueEvent()の引数はos.queueEvent関数と同様。ただし、イベントのパラメータはオブジェクト型配列として渡す。値の型はcallMethod()の戻り値と同様に適切なLuaの型へと変換される。イベントのパラメータの一番目には、ComputerやTurtleからどの周辺機器で発生したイベントなのかが分かるように、IComputerAccess.getAttachmentName()を渡すとよい。