提供: Minecraft Modding Wiki
2014年10月22日 (水) 21:08時点におけるNMS (トーク | 投稿記録)による版 (ページ作成)
(差分) ← 古い版 | 最新版 (差分) | 新しい版 → (差分)
移動先: 案内検索
この記事は執筆中です。加筆してくださる人を募集しています。

この記事は"Minecraft Forge Universal 10.13.0.x~"及び"ComputerCraft 1.65~"を前提MODとしています。

イベントの追加

ComputerやTurtleからperipheral.call関数でメソッドを呼び出せる周辺機器ブロックを追加する。

ソースコード

周辺機器の追加」のソースコードを元にして、変更部分のみを解説する。

  • TileSamplePeripheral.java
package mods.sample.peripheral;

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 {

	@Override
	public String getType() {
		return "sample";
	}

	@Override
	public String[] getMethodNames() {
		return new String[] {"fn1","fn2"};
	}

	@Override
	public Object[] callMethod(IComputerAccess computer, ILuaContext context,
			int method, Object[] arguments) throws LuaException,
			InterruptedException {
		switch(method) {

		case 0:  // fn1
			return new Object[] {"fn1 called!"};

		case 1:  // fn2
			if ( arguments.length < 1 ) {
				throw new LuaException("Expected argument");
			}
			if ( arguments[0] == null ) {
				throw new LuaException("Illegal argument");
			}
			return new Object[] {arguments[0], arguments[0].getClass().getName()};
		}

		return null;
	}

	@Override
	public void attach(IComputerAccess computer) {

	}

	@Override
	public void detach(IComputerAccess computer) {

	}

	@Override
	public boolean equals(IPeripheral other) {
		if ((other != null) && (other instanceof TileSamplePeripheral)) {
			return other == this;
		}
		return false;
	}

}

解説

TileSamplePeripheral.java

まず、接続されたComputerやTurtleへ呼出し可能なメソッドの名前を渡すためにIPeripheral.getMethodNames()を実装する。

@Override
public String[] getMethodNames() {
	return new String[] {"fn1","fn2"};
}

↑呼出し可能なメソッド名をString型配列として返す。この戻り値はゲーム中、常に同じ内容を返すようにする。

ComputerやTurtleがメソッドを呼び出した時の処理はIPeripheral.callMethod()で実装する。

@Override
public Object[] callMethod(IComputerAccess computer, ILuaContext context,
		int method, Object[] arguments) throws LuaException,
		InterruptedException {
	switch(method) {

	case 0:
		// fn1が呼び出された時の処理

	case 1:
		// fn2が呼び出された時の処理

	}
 
	return null;
}

↑ここではどのメソッドが呼び出されたのかを示すmothodの値がポイントで、これはgetMethodNames()の戻り値のString型配列のインデックスに対応している。この例では、"fn1"が呼び出された時にはmethod = 0、"fn2"が呼び出された時にはmethod = 1となる。methodの値をswitch文で分岐させれば簡潔に各メソッドの処理を書く事が出来る。

メソッドの戻り値はオブジェクト型の配列。返すべき値が無い時は空のオブジェクト型配列を返せばよい。

case 0:  // fn1
	return new Object[] {"fn1 called!"};

↑サンプルのfn1では、単純に"fn1 called!"という文字列を返している。

サンプルのfn2では引数の取得、例外のthrow、変数のreturnを行っている。

case 1:  // fn2
	if ( arguments.length < 1 ) {
		throw new LuaException("Expected argument");
	}
	if ( arguments[0] == null ) {
		throw new LuaException("Illegal argument");
	}
	return new Object[] {arguments[0], arguments[0].getClass().getName()};

↑引数なしでメソッドが呼び出されたなら例外LuaException("Expected argument")を発生、第一引数にJava側で受け取れない値が指定されていたら例外LuaException("Illegal argument")を発生させている。戻り値は指定した第一引数そのものと、そのJava側でのクラス名を返している。

  • 引数や戻り値の型

メソッド呼出し時の引数はオブジェクト型配列argumentsで渡される。引数や戻り値の型は自動的に変換される。
Lua→Java、Java→Luaでの型変換は以下の通り。

呼出し 戻り値
Lua Java Java Lua
boolean Boolean Boolean boolean
number Double Integer
Float
Double
number
string String String string
table HashMap HashMap table
その他 null その他 nil
  • 例外 LuaException

callMethod()の処理中で例外LuaExceptionをthrowすると、そこで処理を中止してComputerやTurtleの画面にエラーメッセージを表示する。ComputerCraftの周辺機器では主にメソッドの引数の不備を指摘する時に用いられているようだ。

throw new LuaException("Expected argument");

↑サンプルのfn2で、引数が何も指定されずに呼び出された時に発生させている例外。ComputerやTurtleの画面上には、
lua:1: Expected argument
のように表示される。lua:の後ろの数字はLuaスクリプトの行番号。

  • Minecraftとの競合

今回の例では問題ないが、callMethod()はComputerCraftのLuaスレッドから呼び出されているため、callMethod()からの一連の処理中において、Minecraftスレッドから変更され得るフィールドへのアクセスは競合が発生する可能性がある。従ってそのような処理では適宜synchronized等で排他制御する必要がある。