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

そう言えば SHIORI/2.0 にしたのに内容について触れてなかった(^^;) 期待した人ごめん。居ないから良いだろ、ともいえますが。まぁ。ね。

さてパーサーを書かねばならんので敬遠していた事は言いましたが、実装においてはもうパーサーなんて書きませんでしたよ。きょうび 800MHz でも 6000円を切ってんですから少しぐらいの負荷は赦して貰おうってコトで、AnsiSameText() をビシバシ呼んじゃってます。


function request( H:HGLOBAL; var Len:LongInt ): HGLOBAL; cdecl;
var
    I   : Integer;
    Cnt : Integer;
    Rslt: String;
    function  CmpCmnd( Code:String ):Boolean; begin Result := AnsiSameText( RequestHeader[0], Code ) end;
begin
    Rslt := '';

    RequestHeader.Text := HandleToStr( H, Len  );
    Cnt := RequestHeader.Count;
    for I:=0 to Cnt-1 do RequestHeader[I] := StringReplace( RequestHeader[I], ': ', '=', [] );
    GlobalFree( H );

    {$IFDEF VER140}
        {$IF Defined(DBG_RequestAll)}
            AddDebugLog( 'SHIORI - Request() - ', RequestHeader[0], True );
        {$IFEND}
    {$ENDIF}
    
    if      CmpCmnd( 'GET Word SHIORI/2.0'    ) then  Rslt := GetWord(      RequestHeader )
    else if CmpCmnd( 'GET Sentence SHIORI/2.0') then  Rslt := GetSentence(  RequestHeader )
    else if CmpCmnd( 'GET Sentence SHIORI/2.2') then  Rslt := OnEvent(      RequestHeader )
    else if CmpCmnd( 'GET Sentence SHIORI/2.3') then  Rslt := GetSentence2( RequestHeader )
    else if CmpCmnd( 'GET String SHIORI/2.5'  ) then  Rslt := GetString(    RequestHeader )
    else if CmpCmnd( 'GET Status SHIORI/2.0'  ) then  Rslt := GetStatus(    RequestHeader )
    else if CmpCmnd( 'GET Version SHIORI/2.0' ) then  Rslt := 'SHIORI/2.5 200 OK'
    else if CmpCmnd( 'NOTIFY SHIORI/2.0'      ) then  Rslt := 'SHIORI/2.0 200 OK'
    else if CmpCmnd( 'NOTIFY OwnerGhostName SHIORI/2.3' ) then  Rslt := SetOwnerGhostName( RequestHeader )
    else if CmpCmnd( 'NOTIFY OtherGhostName SHIORI/2.3' ) then  Rslt := SetOtherGhostName( RequestHeader )
    {$IFDEF VER140}
        {$IF Defined(DBG_Request)}
            else AddDebugLog( 'SHIORI - Request() - ', RequestHeader[0], True )
        {$IFEND}
    {$ENDIF};
    
    
    if (Rslt = '') then 
        Rslt := ExtractVersion(RequestHeader[0]) + ' 204 No Content'
    else
        Rslt := BuildScript( Rslt );

    Result := GetGlobalMemory( Rslt+TERMINAL, Len );
end;


イベントを処理する OnEvent() もほぼ同じようなもの……。イベント用スクリプト自体は、 OnMouseMove=\0なぞるな!\e  的なテキストを書いて、リクエストヘッダのイベント識別子をそのまま使って TStringList.Values[] で取り出したりなんかして。

なので実質的には俺は何も掻いてないに等しい(笑)

まぁそれだと流石にアレだってんで、イベントにバリエーションが必要なら例えば  OnMouseClick.Sub=\1なんか用かいな?\e  とかやるように簡易のインタプリタを実装。


とはいえこれも手抜きしていて、リクエストヘッダの各行最初の ':' を '=' に置換して TStringList で読ませているので楽チン楽チン。こんなに楽だと解ってたらば、あたら SHIORI/1.0 なんかでやる必要なかったよな〜。



ついでに書いてしまいますが、マルチプルエントリが使えないので、ランダムな文字列を何度も使うために変数を使えるようにしたと言いました。しかし何を勘違いしたか、格納されるのが %ms とかなら、実際には %ms そのものを展開してしまって同じ文字列を使おうとはしませんΣ( ̄□ ̄; なんてこったあ

仕方がないので名詞系のタグはスクリプト構築中にインタプリタ自身が文字列を取り出すようにしました。むろん Get Word リクエストとか自分に送る必要はなくただリクエストされた時と同じ実装部を呼び出しています。

副作用としては、%ms の置換なんかを本体に任せるとリクエストが二回も発生して、名詞のストックが無駄に浪費されてしまうバグを回避し無駄なく利用できるようになっちゃいました。
しかし……そもそも何だよ、この挙動は(^^;)

%selfname なんかの固定された文字列を返すタグは何もしないで本体に任せます。



あとまぁPCの起動時間と自分の常駐時間を混同している本体に抗って、自前で常駐時間を管理してたりとか。くだらんけど。



そろそろパイロット版ぐらいアップロードしたいんですが〜。う゛〜。絵が……。

シェルを自前で用意できる人向けに、手動インストール限定でアップする事なら出来るんですが。
当初の予定と違って DLL 自体は汎用ゴーストっぽい……デバッグの都合を考えると、そうなった。AI を実装し始めるとそうはいかんのだけれども。

まぁともかく話の種にアップせぇと思う人はリクエストだしてください。エンドユーザに誤解は与えたくないのでこのままだと当面アップできなさげですΣ( ̄□ ̄; まだかよ

つづく。


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