更新窗口以响应CLIM帧命令

时间:2015-06-10 15:46:43

标签: common-lisp clim mcclim

在试图找出CLIM时,我遇到了this example program。这是一个简单的迷宫游戏。作者声称已经在LispWorks中测试过它(甚至在那里有#+Genera,暗示这个程序可以在真正的Lisp机器上运行),但是我试图让它在使用McCLIM的SBCL中工作。

在SBCL / McCLIM下,窗口绘制,但按下移动键时没有任何可见的情况。非移动键会导致文本与游戏说明一起输入到窗格中。

我发现游戏命令键正在改变游戏的内部状态,所以唯一的问题是屏幕不会更新。

然后我意识到你无法编写代码以从实现命令的代码范围重绘迷宫。绘制的所有方法都从CLIM接收stream参数,必须将其传递给图形基元。例如:

(defun draw-stone (stream x y cell-width cell-height)
  (let ((half-cell-width (/ cell-width 2))
        (half-cell-height (/ cell-height 2)))
    (draw-ellipse* stream
                   (+ (* x cell-width) half-cell-width)
                   (+ (* y cell-height) half-cell-height)
                   half-cell-width 0
                   0 half-cell-height
                   :ink +red+)))

但处理击键的代码不会收到stream参数:

(defmacro define-stone-move-command (name keystroke dx dy)
  `(define-maze-frame-command (,name :keystroke ,keystroke) ()
     (let ((maze-array (maze-array *application-frame*)))
       (move-stone maze-array ,dx ,dy)
       (check-for-win maze-array))))

我最终要做的是将stream参数从第一个(也是唯一的)调用draw-maze-array保存到全局变量,以便我可以将更新代码添加到{{ 1}}宏如下:

define-stone-command

这种轻微的改变在使用McCLIM的SBCL上给出了期望的行为,但是这似乎不正确。毕竟,作者声称代码在LispWorks上运行良好。我有几个问题:

  1. 有LispWorks的人可以证实这个程序在LispWorks上按原样运行吗?
  2. 我对代码的更改是否使它在LispWorks上失败?
  3. 在CLIM应用程序中处理屏幕更新的可接受方式是什么?

1 个答案:

答案 0 :(得分:1)

在命令中绘制迷宫不是正确的方法。将迷宫流放入全局变量也很糟糕。 ; - )

显示窗格有:display-function。这个想法是在命令之后整个应用程序框架自动更新。例如,对于:display-time :command-loop,显示窗格将在命令运行后自动更新。还有其他方法可以更新窗格,但在这种情况下,按键会运行一个命令,然后顶级循环只会为每个适用的窗格调用 display-function 。默认的toplevel-loop读取命令(通过鼠标,命令行,按键等...),执行它并更新应用程序框架 - 循环。

整个重新显示的东西非常棘手/强大。它允许从完全自动化的重新显示机制到极细粒度的控制。

您可以在此处阅读:CLIM 2 Spec。注意:规范与实现提供的内容之间可能存在相当大的差异......