我做了一些关于此问题的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类")。
另一方面,是否可以调用" functionONE"从类KEY_TWO或EVENT_ONE ??
很抱歉打扰但是我没有发现错误。
谢谢和问候。塞尔吉奥
答案 0 :(得分: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的想法是将所有代码封装在对象中。
最后,还可以选择在main方法中分配所有对象,并将它们作为参数传递给其他对象。这允许f.e.让多个其他对象访问相同的对象。但是有一个警告:小心对象不要相互抓住"彼此"或者他们不能从记忆中释放出来。 (这可以通过使用ObjectID和命令GetScriptObjectFromID
来避免。有关详细信息,请参阅 scripting-> Objects 一章中关于弱引用的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()
答案 1 :(得分:0)
执行的DM脚本文件中的类定义仅在执行该脚本期间有效。当用户为您的侦听器输入击键时,您的主要功能已完全执行,因此EVENT_ONE的类定义不再有效。如果将EVENT_ONE和KEY_TWO类的实现拆分为单独的文件,然后将该文件安装为脚本库,则代码将起作用。这样,类定义在DM会话的整个生命周期内都保持有效。