68 lines
1.9 KiB
Common Lisp
68 lines
1.9 KiB
Common Lisp
;;;; cl-scopes/csys/space
|
|
;;;; definitions for (spatial) registering and retrieving objects by location
|
|
|
|
(defpackage :scopes/csys/space
|
|
(:use :common-lisp)
|
|
(:local-nicknames (:alx :alexandria)
|
|
(:util :scopes/util))
|
|
(:export #:create #:put #:del #:fetch #:query
|
|
#:neighbors #:free-loc-at #:distance-sq
|
|
#:loc-iterator))
|
|
|
|
(in-package :scopes/csys/space)
|
|
|
|
(defun create ()
|
|
(make-hash-table :test #'equalp))
|
|
|
|
(defun put (spc loc obj)
|
|
(let ((current (gethash loc spc)))
|
|
(if current
|
|
(error "location already occupied! space: ~s, loc: ~s, current: ~s, new: ~s"
|
|
spc loc current obj)
|
|
(setf (gethash loc spc) obj))))
|
|
|
|
(defun del (spc loc)
|
|
(remhash loc spc))
|
|
|
|
(defun fetch (spc loc)
|
|
(gethash loc spc))
|
|
|
|
(defun query (spc pattern)
|
|
nil)
|
|
|
|
(defun neighbors (spc loc &key (dist 2))
|
|
(let* ((to (floor (sqrt dist)))
|
|
(from (- to))
|
|
nbrs)
|
|
(util:with-iterator (loc-iterator from to)
|
|
(lambda (rloc)
|
|
(let* ((cloc (loc-add rloc loc))
|
|
(cell (fetch spc cloc)))
|
|
(when cell (push cell nbrs)))))
|
|
nbrs))
|
|
|
|
(defun free-loc-at (spc loc &key (dist 2)))
|
|
|
|
(defun distance-sq (spc loc1 loc2))
|
|
|
|
(defun loc-iterator (from to &key (dim 2))
|
|
(labels (
|
|
(inc (cur idx)
|
|
(when (< idx dim)
|
|
(let ((new (1+ (aref cur idx))))
|
|
(setf (aref cur idx) new)
|
|
(when (> new to)
|
|
(setf (aref cur idx) from)
|
|
(setf cur (inc cur (1+ idx))))
|
|
cur))))
|
|
(let ((cur (make-array dim :initial-element from)))
|
|
(lambda ()
|
|
(when cur
|
|
(prog1 (make-array dim :initial-contents cur)
|
|
(setf cur (inc cur 0))))))))
|
|
|
|
(defun loc-add (l1 l2)
|
|
(let* ((dim (car (array-dimensions l1)))
|
|
(loc (make-array dim :initial-contents l1)))
|
|
(loop for i to (1- dim) do (setf (aref loc i) (+ (aref l1 i) (aref l2 i))))
|
|
loc))
|