55 lines
1.7 KiB
Common Lisp
55 lines
1.7 KiB
Common Lisp
;; Copyright (c) Camden Dixie O'Brien
|
|
;; SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
(in-package :ham)
|
|
|
|
(defclass simulation ()
|
|
((state :initarg :start)
|
|
(params :initarg :params)
|
|
(width :initarg :width :initform 800)
|
|
(height :initarg :height :initform 600)
|
|
(running :initform nil)
|
|
simulation-thread))
|
|
|
|
(defgeneric update (simulation dt))
|
|
(defgeneric render (simulation))
|
|
|
|
(defmethod initialize-instance :after ((sim simulation) &key)
|
|
(start sim))
|
|
|
|
(defmethod run ((sim simulation))
|
|
(sdl2:make-this-thread-main
|
|
(lambda ()
|
|
(with-slots (width height running) sim
|
|
(with-graphics-context (ctx :width width :height height)
|
|
(loop while running do
|
|
(update sim (/ 1.0 60.0)) ; assume 60 Hz
|
|
(let ((frame (render sim)))
|
|
(display-frame ctx frame))))))))
|
|
|
|
(defmethod start ((sim simulation))
|
|
(with-slots (running simulation-thread) sim
|
|
(setf running t)
|
|
(setf simulation-thread
|
|
(sb-thread:make-thread (lambda () (run sim))
|
|
:name "ham-simulation-thread"))))
|
|
|
|
(defmethod stop ((sim simulation))
|
|
(with-slots (running simulation-thread) sim
|
|
(setf running nil)
|
|
(sb-thread:join-thread simulation-thread)))
|
|
|
|
(defmacro define-simulation (name &key lagrangian coords render start params)
|
|
`(progn
|
|
(defclass ,name (simulation)
|
|
()
|
|
(:default-initargs :start ',start :params ',params))
|
|
(defmethod update ((sim ,name) dt)
|
|
(with-slots (state params) sim
|
|
(setf state ,(let ((eqns (hamilton-eqns lagrangian coords)))
|
|
(update-body eqns coords params)))))
|
|
(defmethod render ((sim ,name))
|
|
(with-slots (state) sim
|
|
(let ,(mapcar (lambda (q) `(,q (getf state ',q))) coords)
|
|
,render)))))
|