Compare commits
3 commits
6d000f41aa
...
f9b419109a
| Author | SHA1 | Date | |
|---|---|---|---|
| f9b419109a | |||
| cf72a7983f | |||
| 022b24533f |
2 changed files with 106 additions and 2 deletions
|
|
@ -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
104
engine/core.scm
Normal 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)
|
||||||
|
|
||||||
|
)
|
||||||
Loading…
Add table
Add a link
Reference in a new issue