由来
在使用HDes 3进行项目(Windows Application)时,如果使用了Window类,就会导致HDes3的窗口不断闪烁。
在昨日做项目时,使用了如下代码:
require 'Windows'
require 'Windows Application'
require 'Window'
require 'Math'
public function main(Windows WINDOWS,WindowsApplication APP,Window WINDOW,XthJ XTHJ){
const myApp = window WINDOW()
myApp.use(WINDOWS,APP)
const control = XthJ myApp()
control.set("WindowName") = "MyApp"
control.set("WindowTheme") = "GSTV1" // 选用GSTV1作为窗口格式
control.set("WindowIcon") = ""
control.set("ShowCloseButton") = true
control.set("ShowMinButton") = false
control.set("ShowMaxButton") = false
control.set("WindowSize") = "auto" // 自动变化
control.set("Resize") = "fasle" // 不许拉动
while (1){
control.show()
addListener(WINDOWS.onAppClose(myApp),function(){
outWhile(0);
})
}
addListener(WINDOWS.onWindowShow(myApp),function(){
control.text("这个窗口为自定义窗口",{
"NoneAutoTop": 0,
"NoneAutoLeft": 0,
"TextFont": WINDOWS.getFont("auto"),
"TextColor": WINDOWS.getColor("black"),
"Cursor": WINDOWS.getCursor("pointer")
})
})
return 0;
}
。
这段代码创建的窗口,使用了自定义窗口格式(GSTV1),这个窗口格式为大部分Windows中都存在的,并且例如使用Java等语言编写时,也不会存在窗口闪烁的问题。
观察
如图(“频率强度与时间变化规律图”),其中长波峰,短波峰,频振峰三者之中,如果两两相交,窗口就会闪烁。这是因为在HDes中的Windows模块,仅仅存在一个线程,若两峰相交,就会出现其中窗口峰被占用的情况。可以通过十字图表示:
相交处(紫圆)区域即会产生频闪。我们再观察代码:
其中我们可以看到,while(1)是主波,在图1中,我们可以看到绿色的波是正常的,因此问题不出在主波上,其次是有两个addListener,观察图1,黑波持续在while(1)下,就可以看到正常画面,这是因为在HDes3中,会强制将addListener,Watcher,Shower三个观察器与ExecFor,ExecWhile与ExecTimeout三个持时器启用HQP2.1调度:
通过分析,答案已然出现。便是第二个addListener与第一个while(0)组成的ExecPerevaer任务组发生冲突。
分析
通过分析addListener的源代码:
public APPLICATION (HDES) all function addListener(APP1,APP2){
if (APP1 & APP2){
while (EXM(APP1)){
if (watcher(APP1) && has(APP1)){
APP2(countArgsLength(APP2)?lastWatcher(APP1).e:null);
}
}
}
}
我们可以看到是一个由EXM吊起的小型while,即小型Longlong,即Short波。当watcher发现到要观测的内容时才会吊起。
再观察我们想要观测的是:WINDOWS.onWindowShow(myApp)。这与前面的WINDOWS.onAppClose(myApp)发生了冲突。什么冲突?因为我们向onWindowShow还是onAppClose,传递的都是myApp。当我们传递时,myApp本身就发生了调用,即ExecReadFor(“已读且不影响”调用)。当onWindowShow不断观察时,myApp就发生变化,onAppClose就会检测到变化。这就会造成EmerOverm(栈冲突)。
解决
当我们试图使用*进行指示时,会发生报错:无法向处于工作的监听组发送指示器。所以我们需要解决指示器报错问题。当我们将代码在HDes2编译器中编译,然后使用HDes3通过分析器转义,发现会多出一段
public APPLICATION (HDES) all function addListener(APP1,APP2)....
代码,它就是新的addListener函数,使用时就不会发生变化。因为他使用了lastWatcherQuestion指示器,而不是lastWatcher指示器。这样他只会在真正变化时触发(即“已读且影响”态)。
若要解决,也可直接在文件中添加如下代码:
public APPLICATION (HDES) all function addListener(APP1,APP2){
if (APP1 & APP2){
while (EXM(APP1)){
if (watcher(APP1) && has(APP1)){
APP2(countArgsLength(APP2)?lastWatcherQuestion(APP1).e:null);
}
}
}
}
没有回复内容