2015-08-15 65 views
2

我做了一些other question關於這一點,反應也不錯,但試圖與聽衆一個例子,我有一個錯誤:要在偵聽器的對象(的一些類)(第二部分)

是可能的,有人會測試這段代碼並解釋爲什麼它找不到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」,則銷燬鍵監聽器並發現錯誤(「未找到類EVENT_ONE」)。

另一方面,是否可以從類KEY_TWO或EVENT_ONE中調用「functionONE」?

對不起,但我沒有發現錯誤。

感謝和問候。 Sergio

+0

嗨塞爾吉奧,偉大的你已經找到你的方式在這裏StackOverflow DM腳本!在這個網站上,一般的政策是*不*在實際的問題/答案中寫入不必要的文本(如道歉,感謝等),而是寫入評論。問題/答案應只包含直接相關的信息。這有助於他人更容易和更快地查找/閱讀/理解事物。另外,如果您找到對您「正確」或「最有用」的答案,請點擊向上和向下箭頭下方的小勾號圖標「接受」答案。這給你和在現場寫出答案「聲譽」的人。 – BmyGuest

回答

0

執行的DM腳本文件中的類定義僅在該腳本執行期間有效。您的主函數在用戶輸入您的偵聽器的關鍵筆劃時完全執行完畢,因此EVENT_ONE的類定義不再有效。如果您將EVENT_ONE和KEY_TWO類的實現分離爲單獨的文件,然後將該文件作爲腳本庫進行安裝,那麼您的代碼就可以工作。這樣,類的定義在DM會話的整個生命週期中都保持有效。

+0

雖然正確,但需要以庫的形式安裝,因此很難開發代碼。我會建議反對這種做法。 – BmyGuest

1

Mike對腳本代碼只在腳本解析器保持「可用」的情況下才是正確的。但是,更好的解決方案是分配KEY_TWO類的構造函數中的第二個對象(或者在主腳本中調用的初始化方法中)。在此階段,代碼仍可用。所以你上面的腳本變爲:

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的想法是將所有代碼封裝在對象中。


最後,還可以選擇分配主方法中的所有對象,並將它們作爲參數傳遞給其他對象。這允許f.e.讓相同的對象被多個其他對象訪問。一個警告雖然:要小心,物體不相互握住「對方」,或他們不能從內存中釋放。 (這可以通過使用的ObjectID和命令GetScriptObjectFromID可以避免參見弱的一章中引用 F1幫助文檔scripting->進一步的信息對象。)

這種構建的一個實例:

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() 
+0

嗨!這正是我需要的。這兩種解決方案都很好。非常感謝!! – Sergio

+0

@BmyGuest建議的解決方案肯定會產生更獨立的解決方案。我同意這些是更清潔和更可維護的方法。 –

相關問題