里々で華和梨をSAORIとして使用するTIPSです。Kawari as SAORI。
華和梨は配列変数の処理、里々で例えるなら「単語群に関する処理」に強いのが特徴です。
独自関数に相当するKIS(Kawari Inline Script)を利用して里々では難しい処理を行う事もできます。
ファイル編集はSAORI/YAYAほど高機能ではありませんが、テキストの編集くらいなら可能。
華和梨の基本的なシステムについては華和梨ユーザーズマニュアルを参照のこと。
里々でSAORIとして華和梨を使用する場合、通例通りsatori_conf.txtの@SAORI行以下に登録します。
華和梨本体はshiori.dllというファイル名なので、分かり難い・被りやすいと思ったらkawari.dllのように変えてしまいましょう。
shiori.dll | 華和梨本体。 |
kawarirc.kis | 華和梨の初期辞書。本体と同じフォルダに置くこと。 |
SAORIとして使う際も、華和梨の基本ルールであるこの2つのファイルが必須になります。
System.Callback.OnSaoriExecute | saoriとして呼び出された時に評価される。 |
System.Request.Argument0 | 引数が格納されている(末尾数値で1,2,3...と対応)。 |
System.Response.Result | 返したい結果及びスクリプトをセットするエントリ。 |
System.Response.Value0 | 追加情報をセットするエントリ(末尾数値で1,2,3...と対応)。 里々側は(S○)で受け取る。 |
System.Response | ステータスコードをセットするエントリ。 |
これらが華和梨をSAORIとして使う時のエントリ名になります。
つまり、呼び出された時には「System.Callback.OnSaoriExecute」エントリが参照され、ここに返したいスクリプト・処理を書いていき、戻り値として返す値は「System.Response.Result」エントリに設定します。
特に拘りがなければkawarirc.kisに記述します。
System.Callback.OnSaoriExecute : $( entry ${System.Request.Argument0}; setstr System.Response.Result ${返したい結果及びスクリプト}; setstr System.Response ${ステータスコード}; )
この例ではArgument0に指定したエントリ名を直接呼び出します。
ステータスコードは200(正常+戻り値あり)、204(正常+戻り値なし)、400(おかしい)から選びましょう。
=kis # 全エントリをクリア listtree @c .; set @a 0; loop $(size @c) $( clear $@c[${@a}]; inc @a; ); =end # システムコールバック System.Callback.OnSaoriExecute : $( entry kawari.${System.Request.Argument0}; ) # スクリプト例 kawari.元旦からの通算日 : $( setstr System.Response.Result $(date %J); setstr System.Response 200; )
@SAORI kawari,saori/shiori.dll
(kawari,元旦からの通算日)
この例ではKawari.(Argument0)から始まるエントリ呼び出しています。各自工夫して下さい。
dateは引数によって様々なフォーマットで日時情報を返します。
中でも %s フォーマットでは基準となる時間を得られるため、終了時にこの値を保存し、次の起動時に現在の値と減算することで「前回終了時から今回起動までの時間」の計測が容易にできます。
里々単体では起動・終了関連の「久しぶりに起動した時トーク内容を変える」項に同様の実現方法がありますが、あちらに比べ手軽かつ制限がない点で優れています。
kawari.通算時間 : $( # 1970/1/1 00:00:00(協定時)からの通算秒数を分(minute)に直して返す setstr System.Response.Result $[ $(date %s) / 60 ]; setstr System.Response 200; )
*OnSatoriUnload $終了時間【タブ】(kawari,通算時間) *OnBoot $前回から経過分【タブ】(calc,(kawari,通算時間)-(終了時間)) >一時間以内に起動した【タブ】(前回から経過分)<60 *一時間以内に起動した :(0)お帰りー。早かったじゃん? 忘れ物?
textloadは文字通りテキストファイルを読み込みます。
kawari.テキストファイル読込 : $( textload @t ${System.Request.Argument1}; setstr @s $( foreach @a @t $( escape ${@a}"\n"; ); ); if $(size @s) $( setstr System.Response.Result ${@s}; setstr System.Response 200; ) else $( setstr System.Response 400; ); )
*hoge.txtの内容を読み上げる (kawari,テキストファイル読込,hoge.txt) *hoge.txtの内容を改行しつつ読み上げる (replace,(kawari,テキストファイル読込,hoge.txt),\\n,\n)
読み込んだ内容は改行を\\n(エスケープされた状態)に置換してから返します。
あくまで例であり、このまま使用するとファイルにここで使っている区切り文字「,」が含まれていた場合replaceが引数指定ミスとして扱います。要注意。
華和梨では変数(=トーク、単語群)をエントリと呼び、これに関する処理で便利なものが揃っています。
里々の関数「単語の追加」で例えるならば、華和梨ではこの単語の追加を配列として処理し、単語群に単語を「先頭」「特定の位置」「最後尾」に加えたり、添え字で指定した単語を呼び出したり、呼び出された単語を同時に削除したり、単語(配列)数を数えたりといった事ができます。
単語群にある全ての単語を呼び出して一つ一つ処理に充てるコマンド、単語群の中のどの位置に特定の単語があるのかを調べるコマンドなど、普通に里々で処理しようと思った場合は相応の自作関数を組む必要があり、それらの手間を省けるのも強みです。
この場合、単語群の編集を華和梨に処理させ、そちらで別途作ったセーブデータまたはテキストデータで単語群を扱い、里々側に必要な単語群のデータを返すといった形が考えられます。
里々では変数が自動で保存され、これはゴーストのちょっとした挙動の運用に便利な反面、処理を書く際には不要となった変数の削除が必要になってきます。
華和梨にはエントリを跨いで使用できる通常の変数と一時変数があり、特に長い処理を組んだ場合の使い分けが便利になります。
saveは指定したエントリとその内容を華和梨形式辞書として保存するコマンドです。実体はテキストデータですが暗号化も可能です。
保存するエントリを引数に全て指定するため、手間を省くためxargsを使うのが一般的でしょう。
セーブ変数 : 車種 , エンジン , タイヤ セーブ実行 : $(xargs セーブ変数 save セーブデータ.txt) # 「セーブ実行」の呼び出しにより「車種」「エンジン」「タイヤ」エントリをセーブデータ.txtに保存
里々と違いセーブの実行タイミングは自動ではありません。
セーブが必要な場合は、ゴーストの終了宣言時に必ずセーブ実行用のエントリを呼び出して下さい。
loadは華和梨形式の辞書及びセーブデータを読み込むコマンドですが、これは既存のエントリの上書きではなく追加で読み込む形になります。
このため、不意に(例えば多重読込などで)同じ辞書のloadを重ねてしまうと、各エントリの配列数が倍増してしまいます。このまま気付かずにsaveしてしまうとセーブデータのサイズが単純に倍、倍、倍…と膨れ上がる可能性もあります。
セット例にて
=kis # 全エントリをクリア listtree @c .; set @a 0; loop $(size @c) $( clear $@c[${@a}]; inc @a; ); =end
といった処理を冒頭に置いて、主要なエントリを一度全て削除を行っているのはこれが理由になります。
セーブデータを一括管理ではなく任意のタイミングでロードさせたい場合、loadコマンドは自作関数化したものを使い、saveの項で説明した「セーブ変数」を流用する事で、予めロード予定の変数のみを削除してからロードするという方法も有効でしょう。
セーブ変数 : 車種 , エンジン , タイヤ セーブ実行 : $(xargs セーブ変数 save セーブデータ.txt) セーブ読込 : $(loadex セーブ変数 セーブデータ.txt) =kis function loadex $( if $[ $(size @arg) != 3 ] $(return "引数の数が正しくありません"); foreach @a $@arg[1] $( clear ${@a}; ); load $@arg[2]; return ""; ); =end
ここで使われているforeachコマンドはこれ一つで指定したエントリ(の中身のエントリ名)全てに同じ処理を実行させられる、非常に便利なコマンドです。