Compare commits

..

3 commits

Author SHA1 Message Date
f9b419109a Another comment 2026-03-27 16:17:00 +08:00
cf72a7983f Minor spelling mistake fix 2026-03-27 16:16:00 +08:00
022b24533f Basic component add and remove with queuing 2026-03-27 16:15:00 +08:00
2 changed files with 106 additions and 2 deletions

View file

@ -8,8 +8,8 @@ Imugi is an ECS engine.
** Entities ** Entities
Entities are game objects stored in an SRFI-69 hash table. A hash table is used for O(1) lookup. Entities are game objects stored in an SRFI-69 hash table. A hash table is used for O(1) lookup.
Entity keys within the hash table are symbols, either set intentionally or automatically generated via gensym. Entity keys within the hash table are symbols, either set intentionally or automatically generated via gensym.
Entities are identified by their hash, and are each a list of components. Entities are identified by their key, and are each a list of components.
Entities are queued for addition and removal to/form the hash table ~world~. Entities are queued for addition and removal to/from the hash table ~world~.
Entity removal and addition is performed at the beginning of each frame, with removal occuring first. Entity removal and addition is performed at the beginning of each frame, with removal occuring first.
There exists a hash map of SRFI-113 sets, ~component-sets~. There exists a hash map of SRFI-113 sets, ~component-sets~.

104
engine/core.scm Normal file
View file

@ -0,0 +1,104 @@
(module (engine core) *
(import scheme
(chicken base)
raylib
(srfi 69)
(srfi 99)
(srfi 113)
(srfi 128))
;; The world hash table
(define world (make-hash-table))
;; The component-sets hash table
(define component-sets (make-hash-table))
;; Insert an entity into component-sets, either creating
;; a new set or updating an existing one for the component
;; type provided.
(define (classify-entity-by id component)
(let ((component-type (rtd-name (record-rtd component))))
(if (hash-table-exists? component-sets component-type)
(let ((component-set (hash-table-ref component-sets component-type)))
;; TODO: this could be nicer with set-adjoin! but I'm not sure if hash-table-ref is locative
(hash-table-set! component-sets
component-type
(set-adjoin component-set
id)))
(hash-table-set! component-sets
component-type
(set (make-eq-comparator) id)))))
;; Create an entity in the world immediately,
;; and add it to the requisite component-sets
(define (create-entity id components)
(hash-table-set! world id components)
(for-each
(lambda (component)
(classify-entity-by id component))
components))
;; Remove a single matching item from a set
(define (set-remove! set element)
(set-search! set element
(lambda (insert ignore)
(ignore #f))
(lambda (old update remove)
(remove old))))
;; Remove an entity from the world immediately,
;; as well as from all component sets.
(define (remove-entity id)
(hash-table-delete! world id)
(for-each
(lambda (set)
(set-remove! set id))
(hash-table-values component-sets)))
;; Queues for entity creation and deletion
(define add-entity-queue '())
(define del-entity-queue '())
;; Add an entity to the incoming queue
;; TODO: append! doesn't work here and IDK why
(define (queue-add-entity id components-lst)
(set! add-entity-queue
(append add-entity-queue (list (cons id components-lst)))))
;; Add an entity to the deletion queue
(define (queue-del-entity id)
(set! del-entity-queue
(append del-entity-queue (list id))))
;; Resolve all new entity creations
(define (add-queued-entities)
(for-each
(lambda (entity)
(let ((id (car entity))
(components (cdr entity)))
(create-entity id components)))
add-entity-queue)
(set! add-entity-queue '()))
;; Resolve all queued entity deletions
(define (remove-queued-entities)
(for-each
(lambda (id)
(remove-entity id))
del-entity-queue)
(set! del-entity-queue '()))
;; Create an instance of an entity in the world and return it's ID
(define (add-instance-named id . components)
(queue-add-entity id components)
id)
;; Shortcut for anonymous instancing
(define (add-instance . components)
(apply add-instance-named (gensym) components))
;; Remove an instance from the world
(define (remove-instance id)
(queue-del-entity id)
id)
)