コンテキスト

保存スクリプトの実行ライフサイクル

Luaのスクリプトをプラグイン(拡張機能)として端末本体に保存することができます。

保存したスクリプトは以下のタイミングで読み込まれ実行が開始されます。

  • 起動時
  • SDKよりobniz.plugin.reloadLua()が実行された場合

例えば以下のプログラムを実行した場合、対象のobnizデバイスにLuaが既に入っていてもいなくてもクラウドに"Hello"を送信するプログラムで上書きされ、reloadLua()により読み込み直しが行われてデータを一度受け取ることになります。

どのようなLuaがもともと端末で実行していたとしてもそれは終了され、すべての変数や関数もクリアされた上で再度保存されているLuaが読み込み直しされます。

obniz.onconnect = async () => {
  obniz.plugin!.onreceive = (data: any, str: string | null) => {
    console.log("received", str);
  };

  obniz.storage.savePluginLua(`
cloud.pluginSend("Hello")
  `);
  obniz.plugin.reloadLua();
}

例えば、既に上記のプログラムでクラウドにデータを送るLuaが入っている場合、以下のようにobniz.plugin.reloadLua()を呼ぶだけで、Contextをクリアして再度実行させることが可能です。

obniz.onconnect = async () => {
  obniz.plugin!.onreceive = (data: any, str: string | null) => {
    console.log("received", str);
    // You will receive "Hello" when you already saved above Lua script.
  };

  obniz.plugin.reloadLua();
}

随時実行

内部に保存せずにLuaスクリプトを随時Javascript SDKより送信して実行する場合にもContextは共通かつ1つのみとなります。

例えば、本体にはLuaスクリプトがないとして、以下のプログラムを実行した場合にはaという変数は保持されるため、a=a+1が実行されるごとにaはインクリメントされます。

以下のプログラムではonreceiveでは2 3 4 を受け取ることになります。

obniz.onconnect = async () => {
  obniz.plugin!.onreceive = (data: any, str: string | null) => {
    console.log("received", str);
    // you will receive 2, 3, 4
  };

  obniz.plugin!.execLua("a=1");
  obniz.plugin!.execLua(`a=a+1;cloud.pluginSend(tostring(a))`);
  obniz.plugin!.execLua(`a=a+1;cloud.pluginSend(tostring(a))`);
  obniz.plugin!.execLua(`a=a+1;cloud.pluginSend(tostring(a))`);
}

変数だけでなく、関数も転送することができます。同じ名前の関数があれば上書きされることになります。

obniz.onconnect = async () => {
  obniz.plugin!.onreceive = (data: any, str: string | null) => {
    console.log("received", str);
    // you will receive 2, 3, 4
  };

  obniz.plugin!.execLua("a=1");
  obniz.plugin!.execLua(`
function add(value)
  return value + 1
end
a=add(a);
cloud.pluginSend(tostring(a))
  `);
}

execLua()はjavascriptでいうeval()関数と同じになります。

渡されるプログラムは内部に保存されるわけではなく、あくまでその場限りで実行されることになります。

しかしLua自体は継続的に本体内部で動作し、再起動するかreloadLua()が呼ばれるまではContextが一貫して保持されるので、変数や関数を書き換えた場合、その影響はずっと残ることになります。

保存しているLuaとexecLua()の共存

端末内部に保存され起動後から動作するLuaとexecLua()実行されるLuaも共通のContextです。

そのためもともと本体に書き込んでいたLuaスクリプトの変数や関数をexecLua()で変更することができます。

ただし、あくまで実行中に変更しているに過ぎません。再起動したりreloadLua()を呼んだ場合にはクリアされ、もともと本体に保存されていたLuaスクリプトが再度実行されます。

以下の例では本体にaという変数を0にして、increment()という1を加える関数を本体に保存しています。
これは一度だけ実行すれば良いのですが、以下の例では起動したら必ず再度書き込むようになっています。

その後にexecLua()で内部に保存されているincrement()関数を利用してaを増やしてクラウドに送信しています。

obniz.onconnect = async () => {
  obniz.plugin!.onreceive = (data: any, str: string | null) => {
    console.log("received", str);
  };

  obniz.storage.savePluginLua(`
local a=0
function increment()
  a=a+1
  return a
end
  `);
  obniz.plugin.reloadLua();

  obniz.plugin!.execLua(`
increment();
cloud.pluginSend(tostring(a))
  `);

}

contextは一貫していますので、2度実行しますと返ってくる値は増え続けることになります。

obniz.onconnect = async () => {
  obniz.plugin!.onreceive = (data: any, str: string | null) => {
    console.log("received", str);
  };

  obniz.storage.savePluginLua(`
local a=0
function increment()
  a=a+1
  return a
end
  `);
  obniz.plugin.reloadLua();

  // you will receive 1
  obniz.plugin!.execLua(`
increment();
cloud.pluginSend(tostring(a))
  `);

  // you will receive 2
  obniz.plugin!.execLua(`
increment();
cloud.pluginSend(tostring(a))
  `);

}