使用Emacs在开发过程中管理客户端和服务器
在支持并研究了有关开发在线多人游戏的书籍三部曲之后,我开始在Emacs中使用Python和Pygame开发自己的在线2D标题。 Python的简单性使我几乎可以用伪代码来表达游戏引擎,而带有exwm的Emacs允许任何代码库使用Lisp控制其自身的环境,工作流和窗口管理。
在开发过程中,我经常同时编辑服务器和客户端文件。 经过一系列更改后,我通常希望同时重新启动客户端和服务器。 理想情况下(但并非总是如此),服务器将游戏世界的状态挂起到内存缓存之类的状态,然后在重新启动时重新加载。
在我的.emacs.d/
我保留了按键Cx c
来运行当前缓冲区中存在的任何代码或项目。 通过统一所有语言和项目中的经典IDE“运行”行为,这节省了我一些精神上的工作。 默认行为设置为compile
:
(global-set-key(kbd“ Cx c”)'compile)
但是,我有一些模式和项目会覆盖编译命令或按键本身。 例如,此按键的elisp挂钩将其设置为eval-buffer
:
(添加钩子'emacs-lisp-mode-hook
(lambda()
(local-set-key(kbd“ Cx c”)'eval-buffer)))
对于Python脚本,我通常喜欢在python3
运行当前缓冲区:
(添加挂钩'python-mode-hook
(lambda()
(设置(make-local-variable'compile-command))
(concat“ python3”(缓冲区名称)))))
但是,仅运行当前的Python文件对我的游戏不起作用。 因此,我决定使用.dir-locals.el文件,该文件可让我为文件夹中的所有文件创建本地缓冲区设置。 该文件位于我的游戏项目目录的根目录下。 看起来像:
((nil。((eval。
(progn(defun游戏运行()
“编译并运行游戏服务器和客户端”
(互动)
;; 移至保留的工作区
(exwm-workspace-switch-create 9)
;; 杀死已经运行的游戏
(删除其他窗口)
(如果(获取缓冲区“游戏”)
(杀死缓冲区“游戏”))
(defun启动服务器()
“启动游戏服务器”
(让((默认目录“〜/ src / Game / server /”))
(启动进程“ my-process”“游戏”“〜/ src / Game / server / bin / python3.6”“ server.py”)))
(defun start-client()
“启动游戏客户端”
(让((默认目录“〜/ src / Game / client /”))
(启动进程“ my-process”“游戏”“〜/ src / Game / client / bin / python3.6”“ client.py”“ enzuru”“ 0”“ 0.0.0.0”)))
(取消启动的进程(进程状态)
“打印过程状态”
(消息(concat进程的“状态”状态)))
(defun setup-workspace()
“使用exwm在我的工作区上设置拼贴”
(切换到缓冲区“游戏”)
(垂直分割窗口)
(其他窗口1)
(水平分割窗口)
(切换到缓冲区其他帧(获取缓冲区“ server.py”))
(exwm-floating-toggle-floating)
(其他窗口1)
(切换到缓冲区其他帧(获取缓冲区“ client.py”))
(exwm-floating-toggle-floating)
(切换到缓冲区其他窗口“游戏”)
;; 启动由哨兵监控的流程,并在5秒钟的延迟后设置工作空间
(让((进程(启动服务器)))
(当服务器进程
(前进
(set-process-sentinel服务器进程'process-launched')
(让((client-process(start-client)))
(当客户程序
(前进
(set-process-sentinel客户进程'process-launched')
(在运行时间“ 5秒”(nil'setup-workspace)为零))))))))
(local-set-key(kbd“ Cx c”)'game-run))))))
现在,当我在编辑游戏文件夹(仅该文件夹)中的任何文件时运行Cx c
时,它将:
- 通过exwm切换或创建保留的工作区:
(exwm-workspace-switch-create 9)
- 删除除以下窗口外的所有窗口:(
(delete-other-windows)
- 如果该进程已经存在,则将其删除:
(if (get-buffer "Game") (kill-buffer "Game"))
- 启动服务器并使用哨兵对其进行监视:
(set-process-sentinel server-process 'process-launched)
- 启动客户端并使用哨兵对其进行监视:
(set-process-sentinel client-process 'process-launched)
- 等待5秒钟,使这些浮动窗口出现,然后进行一些繁琐的工作,以使客户端,服务器和日志窗口彼此相邻地平铺:(
(run-at-time "5 sec" nil 'setup-workspace)
当我最终杀死这个Game
缓冲区时,客户端和服务器也都被杀死了。 如果我继续迭代游戏代码,那么简单的Cx c
将会杀死所有正在运行的服务器和客户端,并启动新的服务器和客户端。
我的 .emacs.d/
可能会提供进一步的帮助,可以在此处查看: https : //github.com/enzuru/.emacs.d