(ひとまずLua側での利用まで) |
(ILuaObjectについての解説を修正) |
||
(同じ利用者による、間の1版が非表示) | |||
7行目: | 7行目: | ||
*ILuaObjectの実装 | *ILuaObjectの実装 | ||
*Lua側での利用 | *Lua側での利用 | ||
− | |||
=== ILuaObjectの実装 === | === ILuaObjectの実装 === | ||
ILuaObjectとは、通常Luaでは扱えない独自のオブジェクトをLua側からでも間接的に扱えるようにするためのインターフェイスです。 | ILuaObjectとは、通常Luaでは扱えない独自のオブジェクトをLua側からでも間接的に扱えるようにするためのインターフェイスです。 | ||
+ | ILuaObjectの実装クラスのインスタンスをLua側へ渡すことで、Lua側からは実装したメソッドを通してJava側のオブジェクトを操作することができます。 | ||
+ | |||
+ | 次の例では、MyObjectというJava側で作成したオブジェクトをILuaObjectを用いてLua側で扱えるようにしています。 | ||
実装例(IPeripheral.callMethod()の戻り値でLua側へ渡す場合): | 実装例(IPeripheral.callMethod()の戻り値でLua側へ渡す場合): | ||
<source lang = "java"> | <source lang = "java"> | ||
− | public class | + | public class SamplePeripheral implements IPeripheral { |
+ | |||
+ | @Override | ||
+ | public String getType() { | ||
+ | return "sample"; | ||
+ | } | ||
− | + | @Override | |
+ | public String[] getMethodNames() { | ||
+ | return new String[] { "createMyObject" } | ||
+ | } | ||
@Override | @Override | ||
public Object[] callMethod(IComputerAccess computer, ILuaContext context, int method, Object[] arguments) throws LuaException, InterruptedException { | public Object[] callMethod(IComputerAccess computer, ILuaContext context, int method, Object[] arguments) throws LuaException, InterruptedException { | ||
− | / | + | switch (method) { |
− | + | case 0: // createMyObject | |
− | MyObject myObject = new MyObject(); // | + | MyObject myObject = new MyObject(); // ILuaObjectで扱うJava側のオブジェクトの例 |
− | return new Object[] { wrapMyObject(myObject) }; | + | return new Object[] { wrapMyObject(myObject) }; // myObjectをILuaObjectでラップしてLua側へ渡す |
+ | } | ||
− | + | return null; | |
} | } | ||
− | private ILuaObject wrapMyObject(final MyObject myObject) { | + | private ILuaObject wrapMyObject(final MyObject myObject) { // 匿名クラス内で利用するためにfinalにする |
return new ILuaObject() { | return new ILuaObject() { | ||
@Override | @Override | ||
public String[] getMethodNames() { | public String[] getMethodNames() { | ||
− | return new String[] { /* | + | return new String[] { /* TODO: myObjectを扱うためのメソッド名の配列 */ }; |
} | } | ||
@Override | @Override | ||
public Object[] callMethod(ILuaContext context, int method, Object[] arguments) throws LuaException, InterruptedException { | public Object[] callMethod(ILuaContext context, int method, Object[] arguments) throws LuaException, InterruptedException { | ||
− | // TODO: | + | // TODO: myObjectを扱うための各メソッドの処理を実装 |
return null; | return null; | ||
} | } | ||
44行目: | 55行目: | ||
}; | }; | ||
} | } | ||
+ | |||
+ | /* 略 */ | ||
} | } | ||
54行目: | 67行目: | ||
=== ILuaObjectの引き渡し === | === ILuaObjectの引き渡し === | ||
− | + | ILuaObjectの実装クラスのインスタンスは、以下のようなメソッドでLua側へ渡すことができます。 | |
*'''IPeripheral.callMethod()'''の戻り値のObject[]の要素 | *'''IPeripheral.callMethod()'''の戻り値のObject[]の要素 | ||
*'''IComputerAccess.queueEvent()'''の引数のObject[]の要素 | *'''IComputerAccess.queueEvent()'''の引数のObject[]の要素 | ||
61行目: | 74行目: | ||
=== Lua側での利用 === | === Lua側での利用 === | ||
− | + | ILuaObjectの実装クラスのインスタンスはテーブルに変換されてLua側へ渡されます。テーブルの要素はキーがメソッド名の文字列、値がそのメソッドを呼ぶための関数です。 | |
+ | |||
+ | ここでは、上の例で実装した周辺機器を元に、ILuaObjectの実装部分に手を加えて解説します。 | ||
例えばJava側で以下のようにILuaObjectを実装した場合、 | 例えばJava側で以下のようにILuaObjectを実装した場合、 | ||
75行目: | 90行目: | ||
<source lang = "lua"> | <source lang = "lua"> | ||
-- Lua: | -- Lua: | ||
− | -- | + | -- 周辺機器からILuaObjectを取得 |
− | + | local tSample = peripheral.find("sample") | |
− | + | local tMyObject = tSample.createMyObject() | |
− | + | -- 取得したILuaObjectのメソッド呼び出し | |
− | + | tMyObject.getType() | |
+ | tMyObject.getPos() | ||
+ | tMyObject.getName() | ||
+ | tMyObject.kill() | ||
</source> | </source> | ||
Lua側でメソッドを呼び出した場合、Java側では実装したcallMethod()が呼び出されます。 | Lua側でメソッドを呼び出した場合、Java側では実装したcallMethod()が呼び出されます。 | ||
101行目: | 119行目: | ||
} | } | ||
</source> | </source> | ||
+ | 以上の仕組みにより、Lua側から呼び出されたメソッドによって、Java側のオブジェクトを操作したり、値を返したりすることができます。 |
2017年5月11日 (木) 23:32時点における最新版
この記事は"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側のオブジェクトを操作したり、値を返したりすることができます。