V9.35β8No.11688
秀丸担当 さん 24/06/06 14:48
 
V9.35β8を公開しました。

以下のページの「先行開発バージョンはこちら」からダウンロードできます。
https://hide.maruo.co.jp/software/hidemaru.html

32bit版:
https://hide.maruo.co.jp/software/bin3/hm935b8_signed.exe

64bit版:
https://hide.maruo.co.jp/software/bin3/hm935b8_x64_signed.exe

[ ]
RE:11688 hidemaru.setTimeout 時系列が担No.11690
こみやんま さん 24/06/07 09:26
 
jsmode "WebView2";
js {
debuginfo(2)
    hidemaru.setTimeout(()=>{console.log("★");},0);
    hidemaru.setTimeout(()=>{console.log("■");},2);

}


■が先に出力されてしまっています。

私のローカルのマシン(Ryzen 7700X)では、1つめが0ミリ秒、2つ目が16ミリ秒 くら
いまでの指定だと
順番が逆転してしまいます。

「本来は仮に両方0」「あるいは両方同じ値」だった場合でも「先に受け付けた方」
が先に実行されるのが正しいといえる挙動です。

そこの(=タイムが等しい時の順序の)実装が難しかったとしても、
後に受け付けたあげくに、引数のタイム指定が大きい方が、先に実行する、
という挙動はコントロール困難な挙動だと言えます。

hidemaru.*** ではなく、window.*** ならば、
// ---------------------------------------------
jsmode "WebView2";
js {
debuginfo(2)
    window.setTimeout(()=>{console.log("★");},0);
    window.setTimeout(()=>{console.log("■");},2);

}
// ---------------------------------------------
どころか、
// ---------------------------------------------
jsmode "WebView2";
js {
debuginfo(2)
    window.setTimeout(()=>{console.log("★");},0);
    window.setTimeout(()=>{console.log("■");},0);

}
// ---------------------------------------------
すらも原則順番が逆転することはありません。



// ---------------------------------------------
上の延長の話ですが、下も妙な順番になります。

jsmode "WebView2";
js {
debuginfo(2)
    hidemaru.setTimeout(()=>{console.log("1");},100)
    hidemaru.setTimeout(()=>{console.log("2");},100);

    hidemaru.setTimeout(()=>{console.log("3");},200);
    let a = hidemaru.setInterval(()=>{console.log("4");hidemaru.clearInterva
l(a)},200);
}


// ---------------------------------------------
// delayタイムが同じなら受け付けた順番通りになるべき
jsmode "WebView2";
js {
debuginfo(2)
    window.setTimeout(()=>{console.log("1");},100)
    window.setTimeout(()=>{console.log("2");},100);

    window.setTimeout(()=>{console.log("3");},200);
    let a = window.setInterval(()=>{console.log("4");window.clearInterval
(a)},200);
}



[ ]
RE:11690 hidemaru.setTimeout 時系列が担No.11691
秀丸担当 さん 24/06/07 17:54
 
確かにそうなることが確認できました。
hidemaru.setTimeoutはWin32APIのSetTimerに由来していて、だいたいそれと同じだ
と思います。
精度や順序も同じっぽいようでした。
そういう精度があるということもヘルプに書いておこうと思います。

WebView2やchromeのwindows.setTimeoutは一応動作する場合の分解能は高いようです
が、それ以外の制約があってまともに使えないので、それよりかはマシということで…
全く同じ時間の場合の順序はそこまで保証するものでもない気がします。

精度については、PerformaceCounter系のものを駆使してSetTimer互換のもを頑張っ
て作ればできるのだと思いますが、それはそれで不安定になってしまいそうです。
何にも考えずに分解能だけ上がるSetTimer2みたいのをOS側で用意してくれたらいい
のにと思います。

[ ]
RE:11688 V9.35β8No.11693
こみやんま さん 24/06/07 22:38
 
https://www.maruo.co.jp/turukame/3/x11675_.html#11675

こちらの、「hidemaru.setTimeoutが近いと、実行そのものがロストすることがある」
という問題と、

hidemaru.postExec*** 系は1つだけスタックする、という問題から
考えると、
(すでにpostExecがスケジュール済みだと、次のpostExecはスケジュールに失敗)

旧版・新版ともに、ある程度拾いながら、複数になっても対応しやすいのは


// ------------------- しばらくは想定される形 -------------------

jsmode "WebView2\\namespace1";
js {
    debuginfo(2);

    let peRetry1 = hidemaru.setInterval(()=>{

        // 新版ではv9.35では実行登録の失敗時に0が失敗時は返ってくるようにな
ったので、
        // それ以前のバージョンのnullとの違いを「明確に」醸し出すため「厳密
等価(===)」で。
        // if (!success) などと書かないこと。旧版だとnullしか返さないので永
久にループになってしまう。

        if (hidemaru.isScheduled()) return;
        let success = hidemaru.postExecMacroMemory("js {console.log('OK1');}");
        if (success === 0) return; // 再挑戦
        hidemaru.clearInterval(peRetry1);
        console.log("tick1");
    }, 100);

}

// 実際には「他のマクロがsetIntervalやpostExec」やってることが想定される
jsmode "WebView2\\namespace2";
js {

    let peRetry2 = hidemaru.setInterval(()=>{
        console.log("OK2");
        if (hidemaru.isScheduled()) return;
        let success = hidemaru.postExecMacroMemory("js {console.log('OK2');}");
        if (success === 0) return; // 再挑戦
        hidemaru.clearInterval(peRetry2);
        console.log("tick2");
    }, 100);

}

// 実際にはまた「さらに別のマクロ」がmessageなりinputなり出してることが想定
される
jsmode "WebView2\\namespace3";
js {
    message("OK");
}

// 以上のパターンがpostExecが累積するのに一番想定されやすい形。
// 今はまだJSの割合が少ないから全く露見していないだけで、将来増えてくるほど
この衝突が想定される
// --------------------------------------

みたいな記述ですかね?

個人利用ならば、最新版の秀丸限定なら

    let peRetry1 = hidemaru.setInterval(()=>{

        if (hidemaru.isScheduled()) return;  // ★この行を足すことでわずかに
速くなる?(うーん、どの道 最新版だと postExecMacroMemoryのネイティブ先頭で同
じ判定して返してるんだろうから効果全くないかもw)
        let success = hidemaru.postExecMacroMemory("js {console.log('OK');}");
        if (success === 0) return; // 再挑戦
        hidemaru.clearInterval(peRetry1);
        console.log("tick1");
    }, 100);

ぐらいの感じですかね?

postExec単体の性能としては、「スケジュールが衝突」した時は、「スケジュール済
み」のものが採用される形で、
「新しく来た方」は無視されるんですよね?

(スケジュールだけしてまだ実行開始していないのに、
 新しいpostExecが来たからといって上書きしたりはないという理解で正しいですか?)

[ ]
RE:11693 V9.35β8No.11694
こみやんま さん 24/06/07 22:44
 
if (hidemaru.isScheduled()) return;



if (hidemaru.isScheduled?.()) return;

です。

[ ]
RE:11694 V9.35β8No.11695
こみやんま さん 24/06/10 11:13
 
この hidemaru.isScheduled() ってこれ名称があまり適切ではないのでは...

何がスケジュールされているのか目的格相当がないので、

hidemaru.isPostExecScheduled とかの方がよくないですか?

そうすれば将来別のものがスケジュールされるような仕組みが出来たとしても

hidemaru.is(**名詞**)Scheduled

みたいに出来て統一感も維持できますし。


[ ]
RE:11695 V9.35β8No.11696
秀丸担当 さん 24/06/10 12:38
 
>postExec単体の性能としては、「スケジュールが衝突」した時は、「スケジュール
>済み」のものが採用される形で、
>「新しく来た方」は無視されるんですよね?

V9.35β8においては、そのようにしています。
それより前のバージョンではそうではなかったのですが、もともとおかしいので以前
の仕様も何もないです。

あとpostExecMacroMemoryは唯一1つの実行枠ですが、非同期関数はマクロ実行中の
可能性もありました。
hidemaru.isMacroExecutingをループして待機することは意味ないけど、hidemaru.is
MacroExecutingで実行すべきかの判断はあったらいいです。

postExecMacroMemoryの返り値などバージョンの違いは、古いバージョン対応を考え
るとややこしいので、hidemaruversionを最初に宣言しておくほうが得策かもしれま
せん。

isScheduled()の名前は確かに具体的なほうがよかったかもです。
それかisScheduled("xxx");みたいにパラメータがあることを前提として、パラメー
タなしの既定がpostExecMacro**とか。
..netのように長く具体的に書くのもいいですが、簡便なのもいいかなと。

ちなみにProcessInfoのonClose(xx)とかも、ヘルプにはそう書いてますが、onClose
= xx;のほうが適切だったかもと思いつつ(実はできますが)、例えばnode.jsはon
(...)とだけあって、そっちのほうがいいかなと思ったりもしました。
何がonなのという感じですが、意味よりも記述の簡便さもあったらいいかなと思いま
す。

[ ]
RE:11696 V9.35β8No.11697
こみやんま さん 24/06/10 14:07
 
うーん、コメントでも読まない限りは、

hidemaru.isScheduled が hidemaru.postExecMacroMemory

の事前判定だと結びつきにくいかと思います。

理由は簡単で、
互いに事実上「グローバル関数」なのに、「互いに互いの『関数名が全くかすってい
ない』」ためです。
たとえば、「schedulePostExecMacroMemoryと「isScheduled」だったら、scheduleの
部分で掠ってるので気づくんですが...

// 非同期か何かの中
() => {
   if (hidemaru.isMacroExecuting()) { return; }
   if (hidemaru.isScheduled()) { return; } // これがpostExecをはじいてると結
びつきにくい。上にisMacroExecuting で弾くのが併記されてると余計結びつきが希
薄に見える。
   hidemaru.postExecMacroFile(...);
}

() => {
    if (hidemaru.isMacroExecuting()) { return; }
    if (hidemaru.isScheduled("PostExec")) { return; } // 一応これは次の行と
結びついているとは気づくが、JavaScriptの定義ファイルありの開発環境だと「hide
maru.postExec」と入力した際に、hidemaru.isScheduled は候補にでないので、post
ExecMacroFile を呼び出す際に、isScheduledの存在に気づきにくい >> 頭に完全に
入っているか、ヘルプを上から下まで読むかしないと気付かない。
    hidemaru.postExecMacroFile(...);
}


() => {
    if (hidemaru.isMacroExecuting()) { return; }
    if (hidemaru.isPostExecScheduled()) { return; } // これは次の行と結びつ
いているとは気づく。コメントがなくても return と組み合わせてあるため、postEx
ecがすでにされてるから弾いてるんだろうとわかる。(次の行との関連がわかる)
    hidemaru.postExecMacroFile(...);
}


もうひとつが今まで作ってきているのといきなり法則が変化しています。

hidemaru.isMacroExecuting // マクロが実行中である
hidemaru.isProcessIdValid // プロセスが有効である
hidemaru.isScheduled      // スケジュールされている ← 何が???

// こういうことならわかりますが...
hidemaru.isExecuting("macro");
hidemaru.isValid("process");
hidemaru.isScheduled("postexec");
// まぁあまり推奨されません。こういうのはあまり良い関数ではないっていうか、
// 事前の記述の正当性のチェックが頼りない感じになるので。

nodeやjqeuryなどで on みたいな文化があるのは、on("***"  の部分などのイベント
の***部分をユーザーが作成・登録したりも出来るという文化があるからですかねぇ。

[ ]
RE:11697 V9.35β8No.11698
秀丸担当 さん 24/06/10 17:01
 
言われていることはわかっているのですが、あまりいいものが思いつかないというか
なんというか…
isPostExecScheduledだと、これからポストするのをスケジュールしているみたいな。
しいていうなら、isExecMacroScheduledでしょうか。
そもそもPostに対してScheduledは対ではないですし、今後もしかしたらキューにす
るかもとか。
簡便にしたいというのもあります。
いっそのことis("...")とか。
思いつかないのでisScheduledにしてみています。

hidemaru.runProcessなどもそうでしたが、runとかの案のものを残したまま、ヘルプ
に書いているのだけをrunProcessにしていたりするので、思いついたら別名を後から
変更でもいいかもしれないです。

一応既存の法則としては、hidemaruGlobal.は、既存のマクロ文/関数の名前をそのま
まで、hidemaru.は、DLLのエクスポート関数やウィンドウメッセージなどの名前をで
きるだけ引き継いでいるみたいな感じです。

[ ]
RE:11698 V9.35β8No.11699
こみやんま さん 24/06/10 17:26
 
>しいていうなら、isExecMacroScheduledでしょうか。
>そもそもPostに対してScheduledは対ではないですし、今後もしかしたらキューにす
>るかもとか。

■命名候補
「isExecMacroScheduled」はアリだと思います。

他だと、

isMacroExecuthing() に合わせて
「isMacroScheduled()」 とかにしておく。
(せめて「何の」スケジュールなのかくらいはわかるようにしておく)

isScheduled だけではもはや
・プロセスのスケジュールなの?
・別の秀丸が実行される予約なの?
(みたいに見えます。多分コメントがないままAIとかに聞いたら、そのような関数に
違いないと判断します)


■hidemaru.isScheduled()は公開しないのも手
あるいは、そもそも
「hidemaru.isSchedule() は公開しない」(必要になったら公開する)
というのも手かもしれません。


hidemaru.isSchedule みたいな関数が必要なのは、
「postExecスケジュール中に、別のpostExecが来ると、**前のもpostExecを上書きし
ちゃいます**」
という『上書きの仕様』になっている場合に必要となる関数ですし。

現状、仕様は上書きしないわけですし。

上書きにならないのであれば、hidemaru.postExec*** 自体の返り値が hidemaru.isS
chedule の返り値を
兼ねている(内包しているし、速度的にも別にほぼ変わらないハズ) なので、
当面要らないんじゃ? という話でもあります。


[ ]
RE:11699 V9.35β8No.11700
秀丸担当 さん 24/06/11 17:07
 
isExecMacroScheduledが一番しっくりきます。
そもそも必要ないのもそうだと思います。
そんな感じで考えようと思います。

[ ]