提供: Minecraft Modding Wiki
2017年5月11日 (木) 23:32時点におけるNMS (トーク | 投稿記録)による版 (ILuaObjectについての解説を修正)
(差分) ← 古い版 | 最新版 (差分) | 新しい版 → (差分)
移動先: 案内検索

ComputerCraft API >

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

ILuaObjectの利用

ILuaObjectを利用してJava側のオブジェクトをLua側から扱えるようにする方法について解説します。

  • ILuaObjectの実装
  • Lua側での利用

ILuaObjectの実装

ILuaObjectとは、通常Luaでは扱えない独自のオブジェクトをLua側からでも間接的に扱えるようにするためのインターフェイスです。 ILuaObjectの実装クラスのインスタンスをLua側へ渡すことで、Lua側からは実装したメソッドを通してJava側のオブジェクトを操作することができます。

次の例では、MyObjectというJava側で作成したオブジェクトをILuaObjectを用いてLua側で扱えるようにしています。

実装例(IPeripheral.callMethod()の戻り値でLua側へ渡す場合):

public class SamplePeripheral implements IPeripheral {

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

	@Override
	public String[] getMethodNames() {
		return new String[] { "createMyObject" }
	}

	@Override
	public Object[] callMethod(IComputerAccess computer, ILuaContext context, int method, Object[] arguments) throws LuaException, InterruptedException {
		switch (method) {
		case 0:  // createMyObject
			MyObject myObject = new MyObject();  // ILuaObjectで扱うJava側のオブジェクトの例
			return new Object[] { wrapMyObject(myObject) };  // myObjectをILuaObjectでラップしてLua側へ渡す
		}

		return null;
	}

	private ILuaObject wrapMyObject(final MyObject myObject) {  // 匿名クラス内で利用するためにfinalにする
		return new ILuaObject() {

			@Override
			public String[] getMethodNames() {
				return new String[] { /* TODO: myObjectを扱うためのメソッド名の配列 */ };
			}

			@Override
			public Object[] callMethod(ILuaContext context, int method, Object[] arguments) throws LuaException, InterruptedException {
				// TODO: myObjectを扱うための各メソッドの処理を実装
				return null;
			}

		};
	}

	/* 略 */

}

この例ではILuaObjectを匿名クラス(無名クラス)で実装しましたが、もちろん通常のクラスで実装しても構いません。

Java側のオブジェクトをLua側から扱うためのメソッドを ILuaObject.getMethodNames() 及び ILuaObject.callMethod() で実装します。
実装方法については IPeripheral.getMethodNames() 及び IPeripheral.callMethod() と同じなので、「周辺機器メソッドの追加」を参考にしてください。

ILuaObjectの引き渡し

ILuaObjectの実装クラスのインスタンスは、以下のようなメソッドでLua側へ渡すことができます。

  • IPeripheral.callMethod()の戻り値のObject[]の要素
  • IComputerAccess.queueEvent()の引数のObject[]の要素
  • TurtleCommandResult.success()の引数のObject[]の要素

Lua側での利用

ILuaObjectの実装クラスのインスタンスはテーブルに変換されてLua側へ渡されます。テーブルの要素はキーがメソッド名の文字列、値がそのメソッドを呼ぶための関数です。

ここでは、上の例で実装した周辺機器を元に、ILuaObjectの実装部分に手を加えて解説します。

例えばJava側で以下のようにILuaObjectを実装した場合、

// Java:
// ILuaObject.getMethodNames()
@Override
public String[] getMethodNames() {
	return new String[] { "getType", "getPos", "getName", "kill" };
}

Lua側では以下のようにメソッドを呼び出すことができます。

-- Lua:
-- 周辺機器からILuaObjectを取得
local tSample = peripheral.find("sample")
local tMyObject = tSample.createMyObject()
-- 取得したILuaObjectのメソッド呼び出し
tMyObject.getType()
tMyObject.getPos()
tMyObject.getName()
tMyObject.kill()

Lua側でメソッドを呼び出した場合、Java側では実装したcallMethod()が呼び出されます。

// Java:
// ILuaObject.callMethod()
@Override
public Object[] callMethod(ILuaContext context, int method, Object[] arguments) throws LuaException, InterruptedException {
	switch(method) {
	case 0:
		// getType の処理
	case 1:
		// getPos の処理
	case 2:
		// getName の処理
	case 3:
		// kill の処理
	}

	return null;
}

以上の仕組みにより、Lua側から呼び出されたメソッドによって、Java側のオブジェクトを操作したり、値を返したりすることができます。