追加案:状態変数マクロの追加

Issue #120 resolved
req created an issue

私は以前 C#.NET で書かれた CWI のソースから、パーティメーカーや世に知られていない小物ツールを作っていたのですが、その際 CWSL という、クラシックシナリオのスクリプトもどきを作ったことがあります。その試みは自分のスクリプト仕様追求の甘さから、メッセージ・セリフの本文をちょこっといじる程度に終わりました。

さてそれからCWXスクリプトに出会って、私の悲願の1つは9割方達成されているのですが、そこで思うことがあります。以前自分が CWSL をやろうとしたときは、シナリオ(cwxeditor で言えば シナリオXML)と1対1関係のスクリプトを作ろうとしたのです。

今考えれば、今のCWXスクリプトが正しいと思います。ですが、ここで思うことは、

CWXスクリプトがイベントコンテント(コンテントツリー)を記述して、ステップ名、フラグ名を変更できるのに、肝心の ステップ・フラグ の定義をCWXスクリプトで書けないじゃないかということです。

そこで現在の案は、ステップ・フラグの 状態変数マクロ を定義し、状態変数の操作も一括で行ってしまおうというものです。

Comments (35)

  1. k4nagatsuki repo owner

    CWの状態変数は、イベントから独立しています。CWXスクリプトはイベントを記述するものですから、CWの状態変数を記述する事はできない事になります。それをするには、前提として、

    • イベント付属の状態変数という要素を作る
    • CWXスクリプトで状態変数を含むシナリオ全体を表現できるようにする

    これらのいずれかが実現される状況が必要になってくると思います。

    スクリプトで全データを表現したいという野心は、CWXスクリプトの設計当初からあります。しかし、実装の手間が恐るべきものである事と、どのような文法が適切かが分からないという事で、実現へ向けては一歩も進んでいない状況です。


    なお、状態変数の名前や値を変数にして取り回したいという程度の話であれば、今でもCWXスクリプトの変数を使って行う事ができます。

    $response = "返事"
    $yes = true
    $no = false
    
    msg M, @C
    よろしいかね?」
    @
    if "はい"
        setflag $response, $yes
    elif "いいえ"
        setflag $response, $no
    fi
    
  2. req reporter

    この前の自分が、間違った内容の pull request していた、Index加算を思い浮かべてください。

    あの時、フラグ a を false にしておいて、とおっしゃいました。 ということは、現状CWXスクリプトがイベントを記述するものであるとするならば、

    名称はどうするかはともかく、CWXスクリプト・状態変数版(CWXスクリプト2でも状態変数スクリプトでも何でもいい) は 別に欲しい のです。

    step "ステップ名のDataからの相対パス", 段階数(省略時10), 初期値インデックス(省略時0), [ ステップインデックス,"ステップ値"] ・・・ (ステップ値 = ”Step - ステップインデックス” の場合は省略)

    flag "フラグ名のDataからの相対パス" , 初期値フラグ(省略時 true ) , "true 時のフラグ値"(省略時:”TRUE”), "false 時のフラグ値"(省略時:”FALSE”)

    適当に書きましたが、こんな感じに状態変数テーブルで右クリックしてメニューを選んだら、全ステップ・フラグの値を書き出して、

    編集して戻したら、全ステップ・フラグの値をリセットするような仕組みを作れないのかなというのが簡単ですが自分のアイディアです。(下で修正しました。)

    CWXスクリプトを全書き出ししておいて、ステップ名(AAA¥BBB)を一括置換(→ CCC¥DDD)した場合に、こちらもステップ名を変えておいて、両方とも戻せばいいと思っています。

  3. req reporter

    CWの状態変数は、イベントから独立しています。CWXスクリプトはイベントを記述するものですから、CWの状態変数を記述する事はできない事になります。

    そうだと思います。ですがスクリプトで書けると魅力的だと思います。

    もし 1テキストで記述したいということであれば、処理は複雑になる恐れはありますが、

    • 全てをスクリプトに変換してコピー の下に、状態変数スクリプトを含めて全て変換してコピー か何かの文言の メニューアイテム を追加し、それが押されたら、/* 状態変数スクリプト */ 状態変数スクリプト ・・・ /* CWXスクリプト */ CWXスクリプト ・・・ のようにコメント区切りと、状態変数スクリプトを前に追加したものを、クリップボードに書き出します。

    • イベントツリーに貼り付けるときに、step か flag があったら、同時並行で、全ステップ・フラグリセットを行い、状態変数を設定しなおします。

    ということをしてあげたらどうでしょうか?

  4. req reporter

    更なる改良案としては、

    /* 変数名 */
    $STEP_1 = "ステップ名1"
    $FLAG_1 = "フラグ名1"
    $FLAG_2 = "フラグ名2"
    /* 状態変数スクリプト */
    step $STEP_1
    flag $FLAG_1
    flag $FLAG_2, false
    /* CWXスクリプト */
    setstep $STEP_1, 3
    setflag $FLAG_1, false
    setflag $FLAG_2, true
    

    とステップ名、フラグ名が、CWXスクリプトの変数を使って、外にくくりだされていると、 一括置換する必要もなくなると思ったのですが、どうでしょうか?

  5. req reporter

    CWXスクリプトも、同じステップ名、同じフラグ名は自動的に前に、CWXスクリプトの変数を使って外にくくりだされているモードも作れるといいと思います。

  6. req reporter
    • marked as major
    • edited description

    やっぱり実現できるならさせたいものであるので、major に変更。 問題点がありそうなので、長月さんのご意見を聞きたいところ。

  7. req reporter

    ですので現状を整理すると、

    • 状態変数スクリプトを追加して、このコメントのように実装する案 (このスクリプトの書式例は このコメント )

    • 設定でチェックか何かが入っていたらでもいいのですが、/* ステップ名 *//* フラグ名 */をCWXスクリプトの変数を使って前にくくりだされるモードを搭載する案

    の2案です。

  8. req reporter

    スクリプトで全データを表現したいという野心は、CWXスクリプトの設計当初からあります。

    野心あると思います。ですが自分のCWXスクリプトで90%以上満たされた満足を100%にするためにも、ステップとフラグのための状態変数スクリプトの実現を目指してみませんか?

    エディタは長月さんが1人で作ってこられたものなので、ソース上変更・追加に無理が無く、ユーザーにステップとフラグのスクリプトを提供できると長月さんがGOサインを出されたら、自分は他の開発や調査、バグ探しを差し置いて、必ず!これからやります。必ずです。

  9. k4nagatsuki repo owner

    すみません、どうもやりたい事がよく分かりません。

    CWXスクリプトの使い方は、イベントを書いてイベントビューに貼り付けるというものです。仰っている内容は、貼り付けたタイミングで状態変数の定義を書き換えるというように見えるのですが、そういう事で合っているでしょうか。

    イベントを編集するつもりで貼り付けを行ったら、知らないうちに他のデータが書き換わっていた、という事にならないでしょうか。私は勘で関数呼び出しを書いて名前が正しいかはコンパイルで確かめる、というような事をよくやるのですが、貼り付けで編集している対象以外のものが変わってしまうと、いつの間にかデータを失ってしまい、しかもそれに気づかないおそれがあります。

  10. Iraka.T

    状態変数の定義、値の内容修正に関して、テキストでまとめて行いたいということなら、XMLを編集するといいと思います。

    クラシックシナリオはXMLではありませんが、編集(E)メニューの中にコピーしたデータをXMLに変換という機能があります。また、クリップボードの内容がWsnに則したXMLである場合には、編集中のシナリオがクラシック形式でもペースト可能であるようです。

  11. req reporter

    貼り付けたタイミングで状態変数の定義を書き換えるというように見える

    その通りです。フラグ a を false にしておいて の場合、

    /* 状態変数スクリプト */
    flag ”a”,false
    /* CWXスクリプト */
    

    の3行がCWXスクリプトの前に3行に追加された形の、拡大スクリプトになります。

    イベントを編集するつもりで貼り付けを行ったら、知らないうちに他のデータが書き換わっていた、という事にならないでしょうか。

    スクリプト言語ですから、CWXスクリプトも、テキストの編集ミスでコンパイルエラーなどということを起こしたりしているというのを twitterで見ましたが、CWXスクリプトの亜流として、CWXスクリプトでもキーワードというか命令語として step と flag を予約済みにしておいて、使えなくしておけばいいと思います。

    貼り付けで編集している対象以外のものが変わってしまうと、いつの間にかデータを失ってしまい、しかもそれに気づかないおそれがあります。

    CWXスクリプトで貼り付けたときに対象以外のものに変わってしまう例といえば、スタートコンテントの名前が重複していて()付きに置き換わるぐらいのものだと思うのですが、CWXスクリプトもスクリプトですから、貼り付けたときに存在しないパラメータとか、逆にパラメータをなくすとか、パラメータの型が違うとかあったらコンパイルエラー起こすのと同じようなものだと思います。 テキスト上でCWXスクリプトと分けるので、ミスは起こりにくいと思います。

    気づかないおそれがあります。

    状態変数スクリプトもCWXスクリプトと同様コンパイルチェックを入れて、基本それを信頼してもらえばいいと思います。

    XMLを編集するといいと思います。

    仰りたいことは分かるのですが違うのです。ここだけは譲れないのです。確かにXMLを編集すればステップ・フラグを編集できます。しかし、そのためには、1:先にCWXスクリプトで、ステップ名・フラグ名を一括置換しておく(それもステップ名とフラグ名で同じものが無いか、ステップ名・フラグ名と同じ文字列が無いか気を付ける。)、2:必要ならば、シナリオWSNをZIP解凍しXMLを取り出すなり、TempやRoamingフォルダなどに開かれているXMLを見つけてくる。3:変更した ステップ名・フラグ名 を一括で置き換える(それもステップ名とフラグ名で同じものが無いか、ステップ名・フラグ名と同じ文字列が無いか気を付ける)。4:必要ならば、XMLをZIP圧縮し、シナリオWSNに戻す。という作業をしなければなりません。そんな手間をシナリオ作者に強いることになります。

    あと今、バグ見つけました。

    twitter で背景変更でCWXスクリプトに書き出して戻したらコンパイルエラー起こったと言っていたのはこれかもしれません。

            rplback "tyrano_bg", ["MapOfWirth.png", "", 0, 0, 632, 420, false, "tyrano_bg", default], 5, DEFAULT, false, false
            chback ["Black.png", "", 0, 0, 632, 420, false, "tyrano_bg", default], 5, DEFAULT
            chback ["Black.png", "", 0, 0, 632, 420, false, "tyrano_bg", default], 5, DEFAULT
            chback ["Black.png", "", 0, 0, 632, 420, false, "tyrano_bg", default], 5, DEFAULT
            chback ["MapOfWirth.png", "", -200, -200, 632, 420, false, default], 5, DEFAULT
    

    これが、スクリプトに変換してコピーで出力されたものですが、貼り付けで戻すと ここに数値が必要です のコンパイルエラーを起こします。

  12. k4nagatsuki repo owner

    すみません、仰られている内容で具体的に何をしたいのかがいまだによく分かりません。CWXスクリプトで状態変数の名前やパスを書き換えたいという事のように聞こえますが、それにはほとんどメリットがありません。

    cwxeditorはリソースの参照を記憶しており、リソースのパスなどが変更された時には自動的に参照を書き換えるようになっているので、仰られているような状態変数の修正は、次の手順で安全に行えます。

    1. 状態変数ビューを開く
    2. 状態変数の名前を変える(または移動する)

    特定の1つのイベントを編集した時に状態変数の定義が変わるというのは、他の全てのイベントで参照が切れてしまう事を意味します。なぜなら参照の書き換えには「変更前」と「変更後」の情報が必要ですが、スクリプトには「変更後」の情報しか無いからです。

    複雑なシナリオでそういう事をすると、シナリオ全体に渡ってデータの参照構造が破壊されてしまいます。それに気づかず保存してしまうと、修復は容易なことではなくなります。


    CWの状態変数は単一のイベントに付属しているのではなく、シナリオ全体で共用されています。ですから、状態変数を書き換える時は、それを参照している全てのイベントを書き換える必要があります。それをせずに状態変数を変えるとシナリオのあちこちで参照が破壊されます。

    私はコンパイルが失敗した時の事を問題にしているのではなく、成功した時の事を問題にしています。コンパイルが通って状態変数が変更されると上のような問題が起きるからです。しかも、人間はスクリプトを一発で完璧に書けるような存在ではないので、意図しない結果をもたらすコードでもたまたま通ってしまう場合があります。


    本質的な問題は、CWにおいては状態変数と各イベントはまったく異なる次元の存在であり、状態変数名(またはパス)という弱い参照で繋がっているに過ぎないという事です。

    イベントごとに個別の変数を持っているのであれば話は別ですが、CWのイベントはそういう構造ではありません。

  13. k4nagatsuki repo owner

    背景セルのバグは修正しました。レイヤとやセル名を追加した時に余計な事をした(それらがデフォルトならスクリプト変換時に値を生成しないようにした)せいで、間違ったスクリプトが生成されるようになっていました。ありがとうございます。

  14. req reporter

    バグが直って何よりです!!変更案は今整理しているところなのでしばらくお待ちください。

  15. req reporter

    整理してみました。

    CWの状態変数は単一のイベントに付属しているのではなく、シナリオ全体で共用されています。

    すみません、別エリアやバトルなどでも使用されているという、単純なことを失念しておりました。ご指摘ありがとうございます!

    リソースのパスなどが変更された時には自動的に参照を書き換えるようになっている

    状態変数を書き換える時は、それを参照している全てのイベントを書き換える必要があります。

    参照の書き換えには「変更前」と「変更後」の情報が必要ですが、スクリプトには「変更後」の情報しか無い

    これを考慮に入れる必要があります。

    そこで状態変数スクリプトの案を、

    CWXスクリプトとは完全に独立して、

    step "変更前のステップ名のDataからの相対パス", "変更後のステップ名のDataからの相対パス(省略時"")", 段階数(省略時10), 初期値インデックス(省略時0), [ ステップインデックス,"ステップ値"] ・・・ (ステップ値 = ”Step - ステップインデックス” の場合は省略)
    flag "変更前のフラグ名のDataからの相対パス","変更後のフラグ名のDataからの相対パス(省略時"")"  ,  初期値フラグ(省略時 true ) , "true 時のフラグ値"(省略時:”TRUE”), "false 時のフラグ値"(省略時:”FALSE”)
    
    • 状態変数ビューの右クリックに、メニューアイテム:状態変数スクリプトに変換してコピー を追加し、それが押されたとき、ステップ・フラグの状態変数スクリプトをクリップボードにコピー

    • 状態変数ビューで貼り付けられたときに、状態変数スクリプトで記述した全てのステップ・フラグをチェックしそれがない場合、ステップ・フラグの削除と参照している全てのイベントの参照を参照無しに書き換え

    • 状態変数ビューで貼り付けられたときに、該当する"変更前のステップ名"のステップ・"変更前のフラグ名"がフラグがある場合で、"変更後のステップ名・フラグ名"が "" でない場合、ステップ・フラグの更新と参照している全てのイベントの参照を変更後に書き換え

    • 状態変数ビューで貼り付けられたときに、該当する"変更前のステップ名"のステップ・"変更前のフラグ名"がフラグがある場合で、"変更後のステップ名・フラグ名"が "" の場合、ステップ・フラグの追加

    という案に変更します。

    自分はあの時、長月さんに、状態変数ビューに

    /* 状態変数スクリプト */
    flag "a", , false
    

    を貼り付けといてと言ってほしかったのです。

    あと、CWXスクリプトの変数を使って前にくくりだされるモードを搭載する案は、

    設定にチェックボックスを一つ追加し、ステップ名・フラグ名・セル名称(対象は他にもあるかも) をCWXスクリプトの変数を使って前にくくりだされるモードを搭載する案に変更します。状態変数スクリプトが実装となった場合はこれも対象にします。

  16. req reporter

    よく考えると、これなら状態変数ビューにメニュー追加・貼り付けでなく、イベントツリーでメニュー追加・貼り付けして、1テキストにも出来るのでは?

    ただ気になる点は、既存のステップ・フラグの変更・削除・追加を行ったとき、1ステップ・フラグに対して元に戻すが発生していたのに対し、これはまとめて行われるので、その辺りがどうなのかということがあります。

  17. k4nagatsuki repo owner

    分かりかけてきたような気がするのですが、これは状態変数の作成のような操作をスクリプトで行いたいという事でしょうか。

    だとすると、それはマクロのような仕組の役割だと思います。

    CWXスクリプトはイベントのデータ・プロセスの表現形式の1つであって、それによってエディタに何か仕事をさせるという性質のものではありません。

    cwxeditorにはマクロ機能はありませんが、CWの外へ目を向ければマクロを持つツールは色々とあります。大雑把にいって、マクロとは人間の操作を自動的に行えるように操作の内容を書いておくようなものであって、同じような「スクリプト」という呼び名こそあれ、単なる記法であるCWXスクリプトとは異なるものです。

    テキストエディタでいうと、CWXスクリプトはテキスト本体で、マクロは「この行を削除してカーソルを下へ動かし、このような内容の行を追加し……」というような操作を記録しておいて任意のタイミングで実行させる事ができるものです。

    スクリプトを書く事で状態変数を操作して内容を変更する、という操作を実行させたいのであれば、それはマクロに他なりません。有用な機能ですが、CWXスクリプトとはほとんど関係ありません。


    あと、CWXスクリプトの変数を使って前にくくりだされるモード

    何をしたいのかについての私の理解が怪しいのですが、もし内容の決まっていない変数をCWXスクリプト内に書いて、コンパイルする時に始めて変数の内容を決めるような事をしたいのであれば、それはすでに可能です。

    次のように冒頭に中身のない変数を置いてみてください。

    $name
    $value
    
    setstep $name, $value
    
  18. req reporter

    これは状態変数の作成のような操作をスクリプトで行いたいという事でしょうか。

    その通りです。それ以外の何物でもありません。

    スクリプトを書く事で状態変数を操作して内容を変更する、という操作を実行させたいのであれば、それはマクロに他なりません。

    長月さんがマクロだとおっしゃるなら、自分は状態変数マクロとでも呼称して全然構いません。スクリプトを書く事で状態変数を操作して内容を変更して、CWXスクリプトと合わせて、悲願の1つの10割達成したいだけなのですから。

    CWXスクリプトとはほとんど関係ありません。

    機能的に独立しているので CWXスクリプトとはほとんど関係がないというのも当然だと思います。ですが、やってみたいのです。

    CWXスクリプトの変数を使って前にくくりだされるモードについて

    start "到着"
        setstep "AAA\PP$PP", 0
        brstepm "AAA\PP$PP"
        sif 0
        stepdown "AAA\PP$PP"
        cpstep random, "AAA\PP$PP"
        cmpstep "AAA\PP$PP", "ZZZ"
        sif ">"
        chkstep "", "=", 0
    

    例えばステップに関して、こんなのがあったとします。このモードにチェックが入っていたら、スクリプトを上からなめて、発見したステップ名(空文字除く)の順番に$STEP_1、$STEP_2と変数名を付けて、

    /*変数名 */
    $STEP_1 = "AAA\PP$PP"
    $STEP_2 = "ZZZ"
    /* CWXスクリプト */
    start "到着"
        setstep $STEP_1, 0
        brstepm $STEP_1
        sif 0
        stepdown $STEP_1
        cpstep random, $STEP_1
        cmpstep $STEP_1, $STEP_2
        sif ">"
        chkstep "", "=", 0
    

    にスクリプトが置き換わるだけの機能というイメージだと思ってください。置き換わるだけなので、まだ今一つコード上でどこに入れていいかは悩んでいますが、CWXスクリプトが綺麗に整形されて生成されて、クリップボード出力する前までの間にでも置き換えを挿入できるのではないかと思っています。

  19. req reporter

    CWXスクリプトが生成されて、クリップボード出力する前までの間にでも置き換えを挿入 が出来るのなら、状態変数マクロも、このコメント の状態変数ビューをイベントビューに置き換えて、CWXスクリプトを生成した後に追加したり、貼り付けのCWXスクリプト解析の前に状態変数マクロの解析とマクロ処理をやって状態変数マクロを削除してCWXスクリプトに渡せないかなという気もします。そうすれば1テキストで書けるかなとも思います。

  20. k4nagatsuki repo owner

    用語についてですが、少し正確にいうと、やりたい事としてはマクロで、それを実現する方法としてスクリプト言語を設計するという事になるかと思います。実際のところ、他の機能と混同されないように注意さえすれば、別にどう呼んでもいいと思います。

    cwxeditorにマクロがつくとしたら、それは嬉しい事です。ほしいと思っても手を付けられない機能の1つがマクロでした。設計するのも面倒で、実装の手間もとてつもなく大きくなる事が明白だったからです。

    状態変数の編集だけができる所からスタートするのはよい考えかもしれません。


    しかし、マクロをCWXスクリプトと併用できるようにしたとして(例えば「このイベントツリーを挿入する」というようなマクロを書くには、マクロでCWXスクリプトを扱えるようにするのが一番よいでしょう)、状態変数を操作するマクロをCWXスクリプトと同じファイルに書けるかというと、これはCWシナリオの構造上無理があると思います。状態変数とイベントツリーはまったく異なる場所・異なるレベルにあります。

    例えば数百個のイベントが含まれるシナリオで、状態変数ビューでCWXスクリプト(すなわちイベントツリー)を貼り付けようとしても、それがどのイベントを相手にしているかは分かりません。

    逆にある特定のイベントに対してCWXスクリプトを貼り付けた時に状態変数が変更されるとなると、私が今まで書いてきたような厄介な問題が発生します。

    これらの無理は、本来別個のものを一緒に扱おうとする所から発生しています。その別個ぶりは、シナリオの最上位のレベルまで辿らないと繋がらないほどなので、イベントツリーと状態変数を1つのテキストで表すという事は、1つのシナリオ全体を1つのテキストで 表すというに等しいです。


    このモードにチェックが入っていたら、スクリプトを上からなめて、発見したステップ名(空文字除く)の順番に$STEP_1、$STEP_2と変数名を付けて、

    それは現状でエリアIDなどに対して実行されているものですね。

    IDは数値で、スクリプトの内容を見てもどのエリアを指しているか分かりづらかったのでそういう風にしました。ただの数値ではテキストエディタでの置換も難しいです。

    状態変数もそういう風にしても別に構わないと思いますが、メリットがあるかは疑問です。$STEP_1などのようにすると、実際に使用している箇所で状態変数名の情報が失われます。状態変数名は「それはなんのフラグ/ステップか」という唯一の情報なので、それが無くなると、なんだか分からない状態変数を操作するイベントのスクリプトが生成されてしまう事になります。

    その上、状態変数名の置換は、ほとんどすべてのテキストエディタにある置換機能で行う事ができます。

  21. req reporter

    これからは大事だと思っているので慎重に考えていきたいと思います。

    cwxeditorにマクロがつくとしたら、それは嬉しい事です。ほしいと思っても手を付けられない機能の1つがマクロでした。設計するのも面倒で、実装の手間もとてつもなく大きくなる事が明白だったからです。状態変数の編集だけができる所からスタートするのはよい考えかもしれません。

    ありがとうございます。

    状態変数とイベントツリーはまったく異なる場所・異なるレベルにあります。

    全く同意見です。

    私が今まで書いてきたような厄介な問題が発生します。これらの無理は、本来別個のものを一緒に扱おうとする所から発生しています。イベントツリーと状態変数を1つのテキストで表すという事は、1つのシナリオ全体を1つのテキストで 表すというに等しいです。

    確かに無理な面もありますが、自分が考えていることは少し違います。ここで自分が問題だと思っていることは、1つのテキストで書いたとき、状態変数のマクロのパラメータは保持しておいて、先にCWXスクリプトが実行されて確定していること(1操作)、その後、状態変数が編集されること(複数操作) という順番が決まっていないことに問題があると思います。

    このようにすると決めてしまえば、マクロとして記述する場合は自分はセンスないので何ですが、

    step "a","b"
    area 7,"これが最後だ!エリア",・・・
    script "到着"
    CWXスクリプト・・・
    script end
    area end
    battle 2 ,"通常戦闘",・・・
    script "[キーコード]"
    CWXスクリプト・・・
    script end
    battle end
    package 3 ,"資金操作パッケージ"
    script
    CWXスクリプト・・・
    script end
    package end
    

    状態変数名は「それはなんのフラグ/ステップか」という唯一の情報なので、それが無くなると、なんだか分からない状態変数を操作するイベントのスクリプトが生成されてしまう事になります。

    本当は$STEP_ステップ名 と付けたかったのですが、¥マークや$などが使えないので出来ませんでした。CWXスクリプトの変数を使って前にくくりだされるモード は、ほおっておいていいかなと思いました。

  22. k4nagatsuki repo owner

    すいません、今でもこの提案で何がしたいのかがよく分かりません。

    状態変数とイベントツリーを一括で操作できる事でどのような手間を削減できるのでしょう?

    そもそもですが、

    CWXスクリプトがイベントコンテント(コンテントツリー)を記述して、ステップ名、フラグ名を変更できる

    CWのイベントではこういう事はできません。どうも考え方の前提が食い違っているような気がします。イベントを書く事で状態変数に何をしたいのでしょう?

    例えばCWXスクリプトを書いている最中に状態変数名を変えたくなった場合に……と解釈すると、それは状態変数ビューを開いて変数名を変更するだけなので、即座に終了する作業です。内容に対して解決できる問題が小さすぎるので、この解釈は違う気がします。しかし、頭をひねっても他の解釈が出てきません。

  23. req reporter

    CWXスクリプトがイベントコンテント(コンテントツリー)を記述して、ステップ名、フラグ名を変更できる については、すみません。自分整理付いていませんでした。取り消します。

    どうせやるならですが、マクロと全CWXスクリプト出力 か何かのメニューアイテムを押したら、マクロとCWXスクリプトでずらーっと出力されて、外部に持ち出し、スマホのテキストエディタとかでいつでも編集し、家に帰ってきたら反映できるのが理想です。

  24. k4nagatsuki repo owner

    XMLは記法が大仰で人間が書くには向いていないので、もっと簡単なテキスト記法でシナリオを表現できたらいいなぁとは私も思いますね。

    それを作ると、必然的に新しいシナリオ形式が増える事になってしまいますが。

  25. req reporter

    理想は理想として持っといて、第1弾としてはやはり、状態変数ビューでのマクロ出力と貼り付けですかね?

  26. k4nagatsuki repo owner

    マクロを設計して実行できるようにすればいいかと思います。まずは状態変数ビューだけを操作できるものでも構わないでしょう。

    マクロに対応する機能が増えていき、イベントビューまで操作できるようになれば、必然的に、1つのマクロによって状態変数の名前の変更とCWXスクリプトの貼り付けなども行えるようになるはずです。

    マクロには、既存のプログラミング言語を拡張して実現するものと、独自のスクリプト言語を開発して実現するものとがあります。前者の例としてはサクラエディタ、後者の例としてはTeraTermなどがあります。

  27. req reporter

    マクロ仕様案を書いてみました。ご覧になって、ダメ出しなり、ゴーサインなり、改善点とか、案とか出していただけると幸いです。いろんな人にご指摘受けたいところです。

  28. k4nagatsuki repo owner

    ようやくですが、ざっと目を通してみました。問題がありそうなところだけ書きます。

    カンマ(,)、中括弧({,})、セミコロン(;)などの記号を読み飛ばす

    デメリットの項にも書かれているので気づかれている事と思いますが、これをしてしまうと、データ構造をうまく記述できないケースが多々出てきます。構文解析の手間が激増しますので、あまりおすすめできません。

    これはよくある設計ミスらしく、例えばTeraTermのマクロは引数を空白で区切る形にしたせいで、i -1などと書いた時に「i-1なのか、i-1なのか?」という区別がつけられず、i 0-1のように書かないとエラーになってしまう、という事になってしまっています。

    マクロの書き出しについて。例えばテキストエディタやExcelなどでは、マクロの開始を記録するように指示を出して、いくつか操作を行い、記録終了を指示すると、一連の操作のマクロが出来上がる、というような形でマクロを作成する事ができます。後々あらゆる操作に対応する事を考えると、メニューから作るよりは、それに倣った方がよいと思います(その分大変ですが)。

    allキーワードについて。forのような繰り返し構文を用意した方がいいです。実際には全てではなく条件を満たした一部を配列にまとめて一連の処理を実行させたい、というような事が多いはずです。

    イベントツリーについて。すでにCWXスクリプトがありますので、それをデータとして取り回せるようにすればよいです。それ以外のデータの記法ですが、CWXスクリプトの複合パラメータを流用する事はお勧めしません。数十もあるキャストカードのパラメータをキーワードも無しで全部横並びで書く事を考えてみてください。別の記法を採用するべきです。

    memoryについて。これは変数とはどう違うのでしょう? 例えばクリップボードを操作するには、普通の変数を使って次のようにすればよいと思うのですが……。

    $data = "CardWirth"
    clipboard set $data
    

    変数なら複数の値を取り回す事も簡単です。


    全体的に見て、どういう思想でどういう文法なのかがちょっとピンときていません。

    このようなマクロ言語の設計は、実際に使ってみないとよく分からないところがあるので、試験的な実装を行いつつ同時に設計を行うしかないのかもしれません。

  29. req reporter

    構文解析の手間が激増しますので、あまりおすすめできません。

    構文解析の手間が激増とまではいかないと思っています。コマンドラインなども言ってみれば空白区切りです。それが処理できているのです。出来るはずです。CWXスクリプトのようにコンパイルチェックを吐くこともありませんし、読み飛ばしが効いて、少し柔軟に書けるほうがいいと考えます。

    これはよくある設計ミスらしく、例えばTeraTermのマクロは引数を空白で区切る形にしたせいで、i -1などと書いた時に「iと-1なのか、i-1なのか?」という区別がつけられず、i 0-1のように書かないとエラーになってしまう

    例えば・・・、に対して返答して、また、じゃあこういう場合もあるよと帰ってきそうな気がしますが、いろいろ長月さんには教えてもらいたいので書きます。

    マクロは操作を記述する言語だと長月さんは言いました。ということは、変数 i  なんて出てきません。あったらそれはキーワードとして判断され、キーワードにも i は定義してないので、当然スキップされますのでこういうことは起こりません。計算しないので、0-1 はまず0が数字として判断されます。じゃあ -1 や - 1 はどうする?となりますが、+- の記号が出た後は、必ず数字である必要があり、それと合わせてプラスマイナスの数字として解析されることにします。 +- の記号だけあって次が数字でない場合、+0、-0 つまり 0 と判断されることにしちゃいましょうか。本来はそんな書き方するなと言いたいですが、未定義はまずいということなので書きました。

    メニューから作るよりは、それに倣った方がよいと思います(その分大変ですが)。

    対象を右クリックしてメニューでその対象のマクロ書き出しとやったほうが直観的でいいと私は考えましたが・・・そういうものなのですかね?

    allキーワードについて。forのような繰り返し構文を用意した方がいいです。実際には全てではなく条件を満たした一部を配列にまとめて一連の処理を実行させたい、というような事が多いはずです。

    マクロは操作を記述する言語ですと長月さんは言いました。ということは、エディタでは対象を選択して値を変更し・・・とか、このボタンを押しとか、言ってしまえば 基本的に動作は1対象というか1操作ずつです。それに対して、あり得ないのですが、全部に対して反復実行したい。というのを all キーワードで書けるという利点があります。じゃあ2対象は?となりますが、それは2回書けという話です。

    forのような繰り返し構文を用意することも考えましたが、そうなると、繰り返し範囲指定の記号を用意したり、その間のマクロをストックしておいて反復実行ということになりますが、他のマクロの部分とごっちゃになって分かりにくくなると思っていますが、良い書き方あればすぐ採用します。

    CWXスクリプトの複合パラメータを流用する事はお勧めしません。数十もあるキャストカードのパラメータをキーワードも無しで全部横並びで書く事を考えてみてください。別の記法を採用するべきです。

    これに関しては悩んでいます。状態変数の範囲では問題ないのですが、全記述を目指すとなるときついところです。何かいいアイディアはございますか?

    対象キーワードを clipboard、操作キーワードを set として

    clipboard set "/* シナリオ: */"
    

    このように書けるとします。しかしこれでは、文字列連結を考慮に入れていません。後ろにマクロ記述例書きましたが、ああいう文字列連結がいくつもある場合はどうしたらいいの?ということになります。ですので、自分は対象に memory を含めておいて、最後に clip (分かりづらければ clipboard ) を付けることを推しますが、もっといいアイディアあれば言ってください。


    このようなマクロ言語の設計は、実際に使ってみないとよく分からないところがあるので、試験的な実装を行いつつ同時に設計を行うしかないのかもしれません。

    暇が出来たら、この場合の構文解析例を、d言語で・・・怪しいですが書いてご提示したいと思います。

  30. k4nagatsuki repo owner

    構文解析の手間が激増とまではいかないと思っています。コマンドラインなども言ってみれば空白区切りです。それが処理できているのです。出来るはずです。CWXスクリプトのようにコンパイルチェックを吐くこともありませんし、読み飛ばしが効いて、少し柔軟に書けるほうがいいと考えます。

    これは実際にやってみてください。案外上手く行くかもしれませんし、壁に突き当たったら考え直せばいいだけです。

    マクロは操作を記述する言語ですと長月さんは言いました。ということは、エディタでは対象を選択して値を変更し・・・とか、このボタンを押しとか、言ってしまえば 基本的に動作は1対象というか1操作ずつです。それに対して、あり得ないのですが、全部に対して反復実行したい。というのを all キーワードで書けるという利点があります。じゃあ2対象は?となりますが、それは2回書けという話です。

    マクロが充分に高機能であれば、「状態変数の中で名前に『ゴブリン』を含むものを見つけ出して初期値をTRUEに変更せよ」というような操作を記述する事ができます。これができるとできないとでは使い勝手が圧倒的に違うので、そうした需要は必ず出てくると思います。今のうちに制御構文を考えておいた方がいいです。

    マクロは操作を記述するものですが、どのようなデータに対して、どのようなデータを設定するか、という事をやるので、必然的にデータも記述する事になります。

    データを書くにも、制御構文を書くにも、変数が必要になってきます。

    操作と操作に必要なデータを記述するものであるマクロは、本質的にプログラミング言語です。よほど用途を制限するのでない限り、プログラミング言語の基本的な要素は全て備えておく必要があります。

    対象を右クリックしてメニューでその対象のマクロ書き出しとやったほうが直観的でいいと私は考えましたが・・・そういうものなのですかね?

    例えばフラグに対する操作を列挙すると:

    • 作る
    • 消す
    • 名前を変える
    • ディレクトリ間を移動する
    • TRUEの値を変更する
    • FALSEの値を変更する
    • 初期値を変更する

    といった操作があり、しかも多くの場面で複数の操作を連続で実行する必要がありますが、これを右クリックメニューの中に詰め込んで、1つ1つの操作をクリップボードに書き出して、最終的にステップやディレクトリの操作なんかも入れて30個の操作を連ねたマクロを作る事を想像してみてください。多分途中でやってらねぇやとなると思います。

    アンドゥのように、マクロを記述する時点では操作対象の実体が存在しない操作もあります。

    これに関しては悩んでいます。状態変数の範囲では問題ないのですが、全記述を目指すとなるときついところです。何かいいアイディアはございますか?

    XMLやJSONはじめ、色々なデータ記述言語があります。各種プログラミング言語も、クラスや構造体としてデータ構造を記述できます。それらの構文を見れば答えが出てくると思います。

    大抵は、データ名とそれに当てはめる値という形になっているはずです(複合パラメータは値だけで、データ名の概念が無い)。

    文字列連結などに関してですが、これは演算が書けるようになっていれば解決します。連結演算子を定義すればいいだけです。

  31. k4nagatsuki repo owner

    マクロがプログラミング言語の要素を備える必要があるというのは、面倒な事ばかりでなく、色々な言語の考え方を流用・応用できるという事でもあります。

    各種の軽量プログラミング言語について調べてみると色々参考になると思います。

  32. req reporter

    マクロが充分に高機能であれば、「状態変数の中で名前に『ゴブリン』を含むものを見つけ出して初期値をTRUEに変更せよ」というような操作を記述する事ができます。例えばフラグに対する操作を列挙

    まだ定義していませんが、自分が想定していることを書きます。状態変数の中で名前検索 (step search name とか?)というのが操作キーワードまでで指定しなければいけない内容です。いざとなったら操作キーワードが3個以上になってでもやります。その後、基本パラメータで『ゴブリン』とTRUEを渡します。すると1マクロで書けます。・・・と思っていたのですが・・・、すべて選択できますね。分かりました。for キーワードと { } を用意します。{ } は複数パラメータ、複数マクロを入れるために使うことにします。for キーワードを明示的に書けますが、その後には必ず { がないといけないことにします。

    自分の想定していたマクロ書き出しというのは対象を右クリックしたら、対象の状態を変更しやすいように、状態変数ならば状態変数1つ1つの状態を edit 操作キーワードで、現在の状態を基本パラメータに反映する。edit マクロの 基本パラメータ を 変えて、貼り付ければ 値の編集、edit キーワードの書き方を真似て、create や delete も出来るというものです。エリアでマクロ書き出しをすると、そのエリアのマクロ、それに属するメニューとイベントのマクロが edit キーワード でエリア全体の状態がマクロ書き出しされます。

    edit で、名前を変える、TRUEの値を変更する、TRUEの値を変更する、FALSEの値を変更する、(Dataフォルダもマクロ書き出しすれば、ディレクトリの名前を変える、ディレクトリ間を移動する)は出来ます。

    ですが、その他、コピー・複製・絞込検索・参照検索など cwxeditor はシャレにならない高機能なことが出来ます。それらの為にも、マクロの開始を記録するように指示を出して、いくつか操作を行い、記録終了を指示すると、一連の操作のマクロが出来上がるにしたほうがいいかもしれません。ツール(T)にメニューを持って、マクロ書き出しダイアログを出して、書き出すに一本化したほうが良さそうですね。

    XMLやJSONはじめ、色々なデータ記述言語があります。各種プログラミング言語も、クラスや構造体としてデータ構造を記述できます。それらの構文を見れば答えが出てくると思います。 大抵は、データ名とそれに当てはめる値という形になっているはずです(複合パラメータは値だけで、データ名の概念が無い)。

    データ名は何とか付けたかったところですが、では、キャストのパラメータすべてにデータ名を付けるのかとなると悩ましいところです。と思っていましたが、やはりつけないといけませんね。そこでこうします。一つの値は、["データ名",<値>] と複合パラメータで書くことにします。フラグのような false が一つしかないものなどは、["初期値",false] と同様と考えます。データ名が重複する場合は、何らか前に文字を付け、1つにデータ名を絞ります。

    アンドゥのように、マクロを記述する時点では操作対象の実体が存在しない操作もあります。

    undo・redo に対しては操作キーワードを用意しています。どういうことになるかというと、ダイアログ・ビューはシナリオ・エリア・状態変数・パッケージなどにそれぞれ属すると考えます。状態変数マクロ書き出し(editマクロ書き出し)と全CWXスクリプト出力をしたかったので、まだ書いていませんが、これによりそれぞれの場所でのUNDO・REDOを記述します。

    連結演算子を定義すればいいだけです。

    この連結演算子の使い勝手がどうなのかな?と思っています。例えば、$ストック変数 ~= area.id とか書いたとします。これでは本質的にCWXスクリプトから離れすぎてユーザー使う気無くすんじゃないか、更に使い勝手を追求し、$文字列 ~= "A" ~ "B" ~ "C" などとやりだした日には構造解析をもうどうしていいのやら分かりません。(よく考えると memory append と同じとも言えますが、~ の後ろに = があるかないかで処理を分岐させねばならず複雑になるのではないかと思っていますが、こっちの方が分かりやすいか?好みといえば ~ よりも + ですけど。)(基本開発者用に近いのでそれでもいいんですけど)

    マクロがプログラミング言語の要素を備える必要があるというのは、面倒な事ばかりでなく、色々な言語の考え方を流用・応用できるという事でもあります。 各種の軽量プログラミング言語について調べてみると色々参考になると思います。

    了解しました。


    基本、守屋さんから見にくいとのご指摘だったので、アイディアが変わるたび「修正」しているので、フロートしたとき・見たときより変わっていることもあるかもしれませんが、その点はご容赦ください。

  33. Log in to comment