提供: Minecraft Modding Wiki
移動先: 案内検索
(attach()/detach()での競合について追記)
(Blockのソース、Tileの解説を修正)
3行目: 3行目:
  
 
== 周辺機器からイベントを発生させる ==
 
== 周辺機器からイベントを発生させる ==
クリックされたとき、接続されたComputerやTurtleに対してイベントを発生させる周辺機器ブロックを追加する。
+
右クリックされたとき、接続されたComputerやTurtleに対してイベントを発生させる周辺機器ブロックを追加する。
  
 
=== ソースコード ===
 
=== ソースコード ===
11行目: 11行目:
 
<source lang = "java">
 
<source lang = "java">
 
package mods.sample.peripheral;
 
package mods.sample.peripheral;
 +
 +
import java.util.Random;
  
 
import net.minecraft.block.BlockContainer;
 
import net.minecraft.block.BlockContainer;
 
import net.minecraft.block.material.Material;
 
import net.minecraft.block.material.Material;
import net.minecraft.creativetab.CreativeTabs;
 
 
import net.minecraft.entity.player.EntityPlayer;
 
import net.minecraft.entity.player.EntityPlayer;
 
import net.minecraft.tileentity.TileEntity;
 
import net.minecraft.tileentity.TileEntity;
22行目: 23行目:
  
 
public BlockSamplePeripheral() {
 
public BlockSamplePeripheral() {
super(Material.rock);
+
super(Material.ground);
setBlockName("blockSamplePeripheral");
 
setCreativeTab(CreativeTabs.tabBlock);
 
 
}
 
}
  
 +
@Override
 
public boolean onBlockActivated(World world, int x, int y, int z,
 
public boolean onBlockActivated(World world, int x, int y, int z,
 
EntityPlayer entityPlayer, int side, float hitX, float hitY, float hitZ) {
 
EntityPlayer entityPlayer, int side, float hitX, float hitY, float hitZ) {
34行目: 34行目:
 
}
 
}
 
return true;
 
return true;
 +
}
 +
 +
@Override
 +
public int quantityDropped(int meta, int fortune, Random random){
 +
return quantityDroppedWithBonus(fortune, random);
 +
}
 +
 +
@Override
 +
public int quantityDropped(Random random){
 +
return 1;
 
}
 
}
  
117行目: 127行目:
 
=== 解説 ===
 
=== 解説 ===
 
==== BlockSamplePeripheral.java ====
 
==== BlockSamplePeripheral.java ====
周辺機器のブロックがクリックされた時の処理を追加する。
+
周辺機器ブロックが右クリックされた時の処理を追加する。
 
<source lang = "java">
 
<source lang = "java">
 +
@Override
 
public boolean onBlockActivated(World world, int x, int y, int z,
 
public boolean onBlockActivated(World world, int x, int y, int z,
 
EntityPlayer entityPlayer, int side, float hitX, float hitY, float hitZ) {
 
EntityPlayer entityPlayer, int side, float hitX, float hitY, float hitZ) {
128行目: 139行目:
 
}
 
}
 
</source>
 
</source>
ブロックがクリックされたらTileEntity(周辺機器)を取得してclick()を呼び出す。
+
ブロックが右クリックされたらTileEntity(周辺機器)を取得してclick()を呼び出す。
  
 
==== TileSamplePeripheral.java ====
 
==== TileSamplePeripheral.java ====
155行目: 166行目:
 
}
 
}
 
</source>
 
</source>
↑attach()で接続されたComputerやTurtleのIComputerAccessインスタンスをリストへ追加、detach()で取り外されたComputerやTurtleのComputerAccessインスタンスをリストから削除。attach()とdetach()はComputerCraftのLuaスレッドから呼び出されている。このリストはMinecraftスレッドから呼び出されるclick()からもアクセスされるのでsynchronizedで排他制御している。
+
↑attach()で接続されたComputerやTurtleのIComputerAccessインスタンスをリストへ追加、detach()で取り外されたComputerやTurtleのComputerAccessインスタンスをリストから削除。<br>
 +
attach()とdetach()はComputerCraftのLuaスレッドから呼び出されている。このリストはMinecraftスレッドから呼び出されるclick()からもアクセスされるのでsynchronizedで排他制御している。
 
<source lang = "java">
 
<source lang = "java">
 
public void click() {
 
public void click() {
165行目: 177行目:
 
}
 
}
 
</source>
 
</source>
↑周辺機器ブロックがクリックされた時に、ブロックのクラスから呼び出される。IComputerAccessインスタンスのリストにある全てのComputerやTurtleへIComputerAccess.queueEvent()で"sample_click"イベントを発生させる。前述の通り、リストへは排他制御でアクセスしている。
+
↑周辺機器ブロックが右クリックされた時に、BlockSamplePeripheralから呼び出される。IComputerAccessインスタンスのリストにある全てのComputerやTurtleへIComputerAccess.queueEvent()で"sample_click"イベントを発生させる。前述の通り、リストへのアクセスは排他的に行っている。
  
 
*イベント
 
*イベント
イベントの内容が分かりやすいように、イベント名は"[周辺機器の種類]_[イベントの内容]"の形にする事が推奨されている。<br>
+
イベント名は、発生したイベントの内容が分かりやすいように"'''周辺機器の種類_イベントの内容'''"のような形にする事が'''推奨'''されている。(APIのjavadoc参照)<br>
ComputerやTurtleがどの周辺機器から発生したイベントなのか分かるように、IComputerAccess.queueEvent()の第二引数のオブジェクト型配列argumentsの一番目にはIComputerAccess.getAttachmentName()を返すとよい。<br>
+
queueEvent()の引数はos.queueEvent関数と同様。ただし、イベントのパラメータはオブジェクト型配列として渡す。値の型はcallMethod()の戻り値と同様に適切なLuaの型へと変換される。イベントのパラメータの一番目には、ComputerやTurtleからどの周辺機器で発生したイベントなのかが分かるように、IComputerAccess.getAttachmentName()を渡すとよい。
os.pullEvent関数に対してargumentsは最大で5つの値を返すことができ、値の型はcallMethod()と同様に適切なLuaの型へと変換される。argumentsに空の配列を渡すとos.pullEvent関数はイベント名以外は何も返さない。
 

2014年10月23日 (木) 11:29時点における版

この記事は執筆中です。加筆してくださる人を募集しています。

この記事は"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()を渡すとよい。