「何か。」のゴースト製作記(8)(2001/11/24)
新着情報 トップメニュー ボードメニュー 掲示板 お手紙はここ!

いやはやいやはや。

なんだか突然に消える……とか起動できない……などと言うバグがあるのですが、原因が特定できなかったのでソースコードを破棄。ゼロから再出発してみました。
まぁどっかの段階でやらねばなーとか思ってたし。色々と再発見があるやら、元々気に入らんかったユニットの構成やらがちょっとマシになるやらで。

突然消える件に付いては、かなり改善が見られるものの無くなったわけではないのがショック。DLL 使ってるとは言え、勝手に死ねるようなコードがかけるケースには無視するとかして存続の方向でやってもらいたい気もしますが……
あと本体自体が落ちてるケースも少なくない……。ってこれウチだけかもしらん。



いくつかのイベントを無視すると不可視状態に移行するらしいことが判明。前バージョンで起動できない〜とか思ってたのはそう言う事でした。 OnBoot とか OnGhostChanged とかは慎重に応答しないと行けませんか(^^;) っていうかその程度の事はフレキシブルに動かさせろよ!とか思った(汗)
バグ自体はプログラム側ではなくイベントスクリプトの方の失敗だったりする……。これに懲りて、イベントスクリプトが定義されていない場合でも、より上位のスクリプトを呼び出すようにしてできうる限り応答しようとする仕様に変更。

DLL 自体にスクリプトを返す仕様を持たせることが良い事かどうかは解らないのでやってない……。204 No Content ってワケにゃイカンよな。

同じように OnSecondChange とかで 200 OK とかだけ返してみたら、リクエストヘッダ自体を毎秒繰り返して表示してくれるようになっちゃいました(汗) Sentence: を追加すると通常に戻る。

現在 OnSurfaceChange のスクリプトを定義してないんですが、消えるバグの追跡をすると最後に無視するリクエストがこれなのよね……。かといって全て OnSurfaceChange で落ちてるわけでもないし。なんでだ。



あとまぁ落ちる原因としては辞書からの行ランダム読み込みでミス。特に名詞辞書で。
名詞辞書は Windows の INI ファイルと同じ構造をしており、単語を引き出すと、次の時の候補から外れるように各セクション毎に並び替えを行って最後に置きなおします。この処理でに落ちる事がある。

TIniFile クラスでは並び替えを実装できないので(セクション読み込みはできるがセクション書き込みができない)、TStringList を継承した TDicStrings を定義。要求されたセクションをコピーして一行を選び、その行を最後に移動したりしたあと、元に書き戻す——と言うように処理してるんですが、書き戻しの際にインデックスが範囲を超えてるとかでエラーが出る。なんでだ。


begin
    Sct  := TDicStrings.Create;
    List := TDicStrings.Create;
    try
        for I:=0 to Max-1 do
            if (Self[I] <> '') then
                if (Self[I][1] = '[') then Sct.Append( Self[I] );

        if (SectName = '') then
            SectName := Sct.GetLineAtRandom
        else
            SectName := '['+SectName+']';

        Head := Sct.IndexOf( SectName );
        if (Head = -1) then
        begin
            Head := 0;
            Tail := Max-1;
        end else begin
            Head := Self.IndexOf( SectName )+1;
            if (Sct.IndexOf( SectName ) = Sct.Count-1) then
                Tail := Max-1
            else
                Tail := Self.IndexOf( Sct[ Sct.IndexOf( SectName )+1 ] )-1;
        end;

        List.FileType := ftLotate;
        for I:=Head to Tail do List.Append( Self[I] );
        Idx := List.IndexOfName( 'Remain' );
        if (Idx >= 0) then 
        begin
            List.Remain := StrToInt( List.Values['Remain'] );
            List.Delete( Idx );
        end;

        Result := List.GetLineAtRandom;

        try
            for I:=0 to List.Count-1 do Self[Head+I] := List[I]; // ここでエラーになってる
        except
            AddDebugLog( 'GetLineAtRandom('+SectName+')', Result+#13#10+IntToStr(List.Remain)+#13#10+List.Text );
        end;
        Self[Tail] := 'Remain='+IntToStr(List.Remain);

    finally
        Sct.Free;
        List.Free;
    end;
end;




落ちる個所が判明したことでマクロ処理の部分は元のをそのまま転用してしまったりなんかする手落ち。処理の簡略化の都合上、マクロのネストは内側から解決されていきます。これだと$.Select() によるブロック選択で、捨てられる部分のマクロも展開する事になり無駄。

$.Select をキャッチした時点でブロック指定かランダム選択かは明確である為、なんとかこれを「選択する部分だけ展開」するように持っていきたい……のですが、なんか共通化されたネストを見張る処理のせいでどうしても展開せざるを得ないのが……設計をミスったなぁ……

自前でプロック切り取りルーチンを書くしかないのか。トホホ〜。



配布ファイルの NAR 形式化に付いては、最初ただの ZIP という言葉に惑わされて、オンラインソフトで ZIP 書庫を作り *.NAR にリネームしたら読んでくれなかった(涙) どうも、通り一遍のヘッダしか扱えないらしい。よわ。

ルートに install.txt を含むフォルダを本体にドロップすると勝手に作ってくれます。しかし、これだと配布用書庫を作るのにバッチファイルでやれなくなっちゃったりしてね……。面倒くさい事に毎度手動でドロップせにゃならんのか〜。

コマンドラインからドロップさせる……と言うコンソールツールがあったよーに記憶してますが、探す手間がかかる。ヘッダのタイプとか特定できれば、圧縮時にヘッダを指定できるフリーのソフトはあるのでその方が楽かも知んない。本当に ZIP 形式ならばの話ですが。
それかコンソールで呼び出せる圧縮・解凍ツールぐらい添付したら良いのになぁ〜とかも思いますが。

けど、その前に UNZIP.DLL や UNLHA.DLL の読み出しをパージするメリットってあるんでしょうか。NAR 形式で無い → UNxxx.DLL で解凍、といったシークエンスで良いんじゃなかったのか……。これまたいずれは仕様変更で古いファイルが読めなくなっちゃうんだぜ。——あ、そか、だからスレイヤー≠ニ呼ぶのか。

もしかして、コマンドライン命令で圧縮ができる? 色々と引数はあるよーですが。



そう言えば *.nar を起動すると、本体が起動してる時はインストール作業に入るんですよね。でも本体が起動していないと本体が起動するだけ。これは弱すぎる仕様でしょう。

起動時に自分のミューテックスを見てるハズだから「ミューテックスがあれば既存の方にインストール作業を指示して自分は終了する else なければフラグを立てて後で自分が処理する」 とりあえず引数をキープしておいて、全てのスタートアップが終った適当なタイミングでインストール作業に入るのも良いだろうし。最初の OnSecondChange なんて好いと思いますけどねェ。切ってる人もいるにしても。

同一パスの多重起動はブロックしてるんですから、なにがしか監視している筈なんですが……。

もっと高度に OLE とか使ってんのかと思ってしまったよ履歴を読んだ時は(^^;) どうやってるんだろー(わくわく みたいな。少なくとも起動時に関連付けをして終了時に関連付けを破棄するとか何とか。



マクロスクリプトに付いては一考します。でもまぁ放置かな。さしあたっては、インターネットの自動徘徊型検索機能の実装を始めようと思うんですが……正規表現って何?(爆)

いやしかし非ビジュアルコンポーネントを使おうとすると、中々に問題が多いのですよ。主にサイズのね。



すでに正弓さんが描いてくれたシェルは公開されています。デフォルトのシェルにするには途中……と言うコトで…… 最新版 0.1.5.47 はこっちからダウンロードしてくらはい。


新着情報 トップメニュー ボードメニュー 掲示板 お手紙はここ!