在侦听器中创建一个对象(一些 class)(第二部分)
To create an object (of some class) in a listener (part II)
我对此做了一些,反响很好,但尝试用听众举例我有一个错误:
是否有人会测试此代码并解释为什么找不到 EVENT_ONE class?
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()
有必要将任何图像放在桌面上,以便按键侦听器 (class KEY_TWO) 工作。在这个class,当我按任意键时,打印它,如果你按"esc",销毁按键侦听器并找到错误("class EVENT_ONE not found")。
另一方面,是否可以从 class KEY_TWO 或 EVENT_ONE 调用 "functionONE"?
抱歉打扰了,我没发现错误。
感谢和问候。塞尔吉奥
Class 已执行 DM 脚本文件中的定义仅在该脚本执行期间有效。当用户为您的侦听器输入击键时,您的主要功能已完全执行完毕,因此 EVENT_ONE 的 class 定义不再有效。如果您将 EVENT_ONE 和 KEY_TWO class 的实现拆分到一个单独的文件中,然后将该文件安装为脚本库,您的代码将起作用。这样,class 定义在 DM 会话的整个生命周期内保持有效。
Mike 关于脚本代码保留 "available" 的说法是正确的,只要脚本解析器保留了这些代码。但是,更好的解决方案是在 constructor KEY_TWO class 中分配第二个对象(或在主脚本中调用的初始化方法中.) 在这个阶段,代码仍然可用。所以你上面的脚本变成了:
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。让多个其他对象访问相同的对象。不过有一个警告:注意对象不能保存 "each other" 否则它们不能从内存中释放。 (这可以通过使用 ObjectID 和命令 GetScriptObjectFromID
来避免。请参阅 scripting->Objects[=27 一章中关于 weak referencing 的 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()
我对此做了一些
是否有人会测试此代码并解释为什么找不到 EVENT_ONE class?
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()
有必要将任何图像放在桌面上,以便按键侦听器 (class KEY_TWO) 工作。在这个class,当我按任意键时,打印它,如果你按"esc",销毁按键侦听器并找到错误("class EVENT_ONE not found")。
另一方面,是否可以从 class KEY_TWO 或 EVENT_ONE 调用 "functionONE"?
抱歉打扰了,我没发现错误。
感谢和问候。塞尔吉奥
Class 已执行 DM 脚本文件中的定义仅在该脚本执行期间有效。当用户为您的侦听器输入击键时,您的主要功能已完全执行完毕,因此 EVENT_ONE 的 class 定义不再有效。如果您将 EVENT_ONE 和 KEY_TWO class 的实现拆分到一个单独的文件中,然后将该文件安装为脚本库,您的代码将起作用。这样,class 定义在 DM 会话的整个生命周期内保持有效。
Mike 关于脚本代码保留 "available" 的说法是正确的,只要脚本解析器保留了这些代码。但是,更好的解决方案是在 constructor KEY_TWO class 中分配第二个对象(或在主脚本中调用的初始化方法中.) 在这个阶段,代码仍然可用。所以你上面的脚本变成了:
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。让多个其他对象访问相同的对象。不过有一个警告:注意对象不能保存 "each other" 否则它们不能从内存中释放。 (这可以通过使用 ObjectID 和命令 GetScriptObjectFromID
来避免。请参阅 scripting->Objects[=27 一章中关于 weak referencing 的 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()