macOS 上如何让创建 GUI 的 lisp 代码在 sly 主线程上运行?

问题的起因是我最近在尝试用大佬的

写应用时遇到了一个问题: FLOATING-POINT-INVALID-OPERATION

一番搜索后发现不仅在 cl-gtk4 会遇到这个问题,其他包也会遇到

总结下来问题大概就是在 sly/slime 里编译 gtk 代码的时候,默认是在另一条线程执行的,编译结束后线程自动关闭,编译线程里的环境设置没有带到 sly/slime 的 repl 环境中,所以直接 C-c C-c 运行文件一类的操作就会报错

cl-gtk4 的作者也给出了解决方案

(sb-int:set-floating-point-modes :traps nil)

想请教下大家,我加上后在 Emacs 里执行虽然不报错了,但是 gtk 直接卡死,没有弹出窗口;与之对应的是如果直接在命令行环境下运行就一切正常

sbcl --load main.lisp

想请教下是我代码出了问题,导致设置的代码并没有在 repl 线程上执行吗?有啥办法能让 sly-eval 时的代码直接在 repl 的线程上运行呀?

(defpackage example.gui
  (:use #:cl #:gtk4))

(in-package #:example.gui)

(define-application (:name example.gui :id "org.example.gui")
  (define-main-window (main-window (make-application-window :application *application*))
    (setf (window-title main-window) "Example GUI")
    (unless (widget-visible-p main-window)
      (window-present main-window))))

(defun main ()
  (sb-int:set-floating-point-modes :traps nil)
  (example.gui))

(main)

发现 cl-sdl2 库也有类似的问题

这个问题像是 macOS + sbcl 独有的

mac 只允许主线程创建 GUI 。你可以试试单独启动一个 slynk server:

(defun main ()
  (slynk:create-server)
  (sb-int:set-floating-point-modes :traps nil)
  (example.gui))

emacs 执行 M-x sly-connect RET 4005 RET

1 个赞

非常感谢,按照你给出的方法已经成功实现了热重载 :+1:

单独启动的话,这行代码

(sb-int:set-floating-point-modes :traps nil)

也就不必要了,看来这种开发还是在 linux 上好做,不过能在 Mac 上热重载我就很满足了 :partying_face:

今天发现了这个库,大概也能解决你的问题

1 个赞