2

これについて別の質問をしたところ、反応は良かったのですが、リスナーで例を試してみると、間違いがありました:

誰かがこのコードをテストして、EVENT_ONE クラスが見つからない理由を説明してくれる可能性はありますか?

void functionONE(){
    result("\n dentro de la FUNCION ONE")
}


class EVENT_ONE : object{

    void accionONE(object self){
        result("\n dentro de accionONE()")
    }

    EVENT_ONE(object self) result("\n EVENT_ONE creado")
    ~EVENT_ONE(object self) result("\n EVENT_ONE destruido")
}

class KEY_TWO : object{

    number evento
    object o

    void almacenaEventoTWO(object self, number pulsacion) evento = pulsacion

    number accionTWO(object self, ImageDisplay disp, object keydesc){
        number control=0

        Result("\n key:"+keydesc.GetKeyDescriptor())
        Result(" ("+keydesc.GetDescription()+")") 

        If ( keydesc.MatchesKeyDescriptor("esc")){
            result("\n has pulsado escape")
            control=1
            disp.ImageDisplayRemoveKeyHandler(evento)

            o = alloc(EVENT_ONE)
            //number idObjecto2 = disp.ImageDisplayAddEventListener( o,     "accionONE" )
            o.accionONE()

        }
        return control
    }

    KEY_TWO(object self) result("\n KEY_TWO creado")
    ~KEY_TWO(object self) result("\n KEY_TWO destruido")
}


void main(){
    image img = getFrontImage()
    showimage(img)
    imageDisplay imgDisp = img.imageGetImageDisplay(0)

    object controlFinal = Alloc(KEY_TWO)
    number idControlFinal = imgDisp.ImageDisplayAddKeyHandler( controlFinal,     "accionTWO" )
    controlFinal.almacenaEventoTWO(idControlFinal)
}
main()

キーリスナー (クラス KEY_TWO) が機能するためには、デスクトップに画像を配置する必要があります。このクラスでは、任意のキーを押すと出力し、「esc」を押すとキー リスナーを破棄して間違いを見つけます (「class EVENT_ONE not found」)。

一方、クラスKEY_TWOまたはEVENT_ONEから「functionONE」を呼び出すことは可能ですか??

お邪魔して申し訳ありませんが、間違いは見つかりません。

ありがとうございます。セルジオ

4

2 に答える 2

1

マイクは、スクリプト パーサーによって保持されている限り、スクリプト コードが "利用可能" であるという点で正しいです。ただし、問題に対するより良い解決策は、KEY_TWO クラスのコンストラクター(またはメイン スクリプトで呼び出される初期化メソッド) に 2 番目のオブジェクトを割り当てることです。この段階では、コードはまだ使用可能です。したがって、上記のスクリプトは次のようになります。

class EVENT_ONE : object{

    void accionONE(object self){
        result("\n dentro de accionONE()")
    }

    EVENT_ONE(object self) result("\n EVENT_ONE creado")
    ~EVENT_ONE(object self) result("\n EVENT_ONE destruido")
}

class KEY_TWO : object{

    number evento
    object o

    void almacenaEventoTWO(object self, number pulsacion){
        evento = pulsacion
    }

    number accionTWO(object self, ImageDisplay disp, object keydesc){
        number control=0

        Result("\n key:"+keydesc.GetKeyDescriptor())
        Result(" ("+keydesc.GetDescription()+")") 

        If ( keydesc.MatchesKeyDescriptor("esc")){
            result("\n has pulsado escape")
            control=1
            disp.ImageDisplayRemoveKeyHandler(evento)

            //o = alloc(EVENT_ONE)  // DO NOT ALLOCATE HERE - THE CODE IS NO LONGER AVAILABLE

            o.accionONE()
        }
        return control
    }

    KEY_TWO(object self) 
    {
        result("\n KEY_TWO creado")
        o = alloc(EVENT_ONE) // ALLOCATE HERE - THE CODE IS STILL AVAILABLE
    }
    ~KEY_TWO(object self) result("\n KEY_TWO destruido")

    // ALTERNATIVELY: Have a Init-method and alloacte here. This method is called (from the main script)
    // while all code is still available. Return the object self just to be able to "pipe-line" the Init call
    object Init(object self) {
        // o = alloc(EVENT_ONE) // ALTERNATIVE ALLOCATE HERE - THE CODE IS STILL AVAILABLE
        return self
    }
}


void main(){
    image img = getFrontImage()
    showimage(img)
    imageDisplay imgDisp = img.imageGetImageDisplay(0)

    object controlFinal = Alloc(KEY_TWO).Init() // Call INIT method
    number idControlFinal = imgDisp.ImageDisplayAddKeyHandler( controlFinal,     "accionTWO" )
    controlFinal.almacenaEventoTWO(idControlFinal)
}
main()

グローバル関数については、グローバル メソッドと変数を完全に避けることをお勧めします。OOC の考え方は、すべてのコードをオブジェクトにカプセル化することです。


最後に、すべてのオブジェクトをメイン メソッドに割り当て、それらをパラメーターとして他のオブジェクトに渡すオプションもあります。これにより、fe は同一のオブジェクトに他の複数のオブジェクトからアクセスできます。ただし、1 つの警告: オブジェクトが「互いに」保持されていないか、メモリから解放できないことに注意してください。(これは、ObjectIDs とコマンドを使用することで回避できます。詳細については、スクリプト -> オブジェクトの章の弱参照GetScriptObjectFromIDに関する F1 ヘルプ ドキュメントを参照してください。)

そのような構成の例:

class CCommon
{
    number v
    CCommon( object self ) { result("Created CCommon ID:"+self.ScriptObjectGetID()+"\n"); }
    ~CCommon( object self ) { result("Destructed CCommon ID:"+self.ScriptObjectGetID()+"\n"); }
    number GetV(object self ) { return v; }
    object SetV(object self, number val){ v=val; return self; }
}

class COne
{
    object co
    object init( object self, object common ) { co=common; return self; }
    object double( object self ) { co.SetV( co.GetV() * 2 ); return self; }
}

class CTwo
{
    object co
    object init( object self, object common ) { co=common; return self; }
    object AddOne( object self ) { co.SetV( co.GetV() + 1 ); return self; }
}

void main()
{
    object c = Alloc(CCommon).SetV(0)
    result("\n Initial:" + c.GetV() + "\n" )
    object o1 = Alloc(COne).Init(c)
    object o2 = Alloc(CTwo).Init(c)
    for (number i=0;i<10;i++)
    {
        o2.AddOne()
        result(" After +1: " + c.GetV() + "\n" )
        o1.Double()
        result(" After x2: " + c.GetV() + "\n" )
    }
}
main()
于 2015-08-17T19:10:06.687 に答える
0

実行された DM スクリプト ファイル内のクラス定義は、そのスクリプトの実行中にのみ有効です。メイン関数は、ユーザーがリスナーのキーストロークを入力するまでに実行を完全に終了しているため、EVENT_ONE のクラス定義は無効になっています。EVENT_ONE クラスと KEY_TWO クラスの実装を別のファイルに分割し、そのファイルをスクリプト ライブラリとしてインストールすると、コードが機能します。このようにして、クラス定義は DM セッションの存続期間中有効なままになります。

于 2015-08-16T17:37:51.520 に答える