Skip to content

Commit

Permalink
Merge pull request #44 from AlecTroemel/ecs-hotfix
Browse files Browse the repository at this point in the history
fix sneaky bug in sparse set and ECS view
  • Loading branch information
AlecTroemel authored Dec 23, 2022
2 parents a15c991 + a227a4e commit 8ea84fa
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 31 deletions.
19 changes: 10 additions & 9 deletions junk-drawer/ecs.janet
Original file line number Diff line number Diff line change
Expand Up @@ -140,19 +140,18 @@ This implimentation uses a (relatively naive) sparse set data structure.
(monster))
```
[world & components]

# Use a free ID (from deleted entity) if available
(let [eid (or (array/pop (world :reusable-ids))
(get world :id-counter))]
(let [eid (cond (> (length (world :reusable-ids)) 0)
(array/pop (world :reusable-ids))

(let [id (get world :id-counter)]
(+= (world :id-counter) 1) id))]

# Add individual component data to database
(each component components
(add-component world eid component))

# increment the id counter when there are no more
# free id's to use
(when (empty? (world :reusable-ids))
(put world :id-counter (inc (world :id-counter))))

# Return the new eid just created
eid))

Expand All @@ -178,8 +177,9 @@ This implimentation uses a (relatively naive) sparse set data structure.
(register-system world move-sys)
```
[world sys]
(array/push (get world :systems) sys))
[world & systems]
(each sys systems
(array/push (get world :systems) sys)))

(defn- smallest-pool [pools]
"Length (n) of smallest pool."
Expand Down Expand Up @@ -217,6 +217,7 @@ This implimentation uses a (relatively naive) sparse set data structure.
(database $)) query)
all-not-empty? (empty? (filter nil? pools))
view-result (map |(view-entry pools $) (intersection-entities pools))]

(:insert view-cache query view-result)
(:insert view-cache query []))))

Expand Down
39 changes: 17 additions & 22 deletions junk-drawer/sparse-set.janet
Original file line number Diff line number Diff line change
@@ -1,22 +1,18 @@
(defn- debug-print
"Pretty Prints contents of set."
[{:entity-indices entity-indices :entities entities :components components :n n}]
(print "entities-indices:")
(pp entity-indices)

(print "entities:")
# (printf "entities (dense): %q" entities)
# (printf "entities-indices (sparse): %q" entity-indices)
(for i 0 n
(printf "%q -> %q" (entities i) (components i))))

(defn- search
"If element is present, returns index of element in :entities, Else returns -1."
[self eid]
(if
# the first condition verifies that 'x' is
# within 'n' in this set and the second
# condition tells us that it is present in
# the data structure.
(and (<= (get-in self [:entity-indices eid]) (self :n))
# the first condition verifies that 'x' is within 'n' in this set
# and the second condition tells us that it is present in the data structure.
(and (< (get-in self [:entity-indices eid]) (self :n))
(= (get-in self [:entities (get-in self [:entity-indices eid])]) eid))
(get-in self [:entity-indices eid])

Expand All @@ -33,27 +29,26 @@
:components components} self
ents-not-full? (<= n capacity)
eid-not-present? (= (search self eid) -1)]

(put entity-indices eid n)
(put entities n eid)
(put components n cmp-data)

(+= (self :n) 1)))

(defn- delete
"Deletes an element from set. Returns bool on whether anything was deleted."
[self eid]
(if-let [element-exists? (>= (search self eid) 0)

{:n n
:entities entities
:entity-indices entity-indices
:components components} self

dense-i (entity-indices eid)]
(do (put entities dense-i nil)
(put entity-indices eid nil)
(put components dense-i nil)
(if-let [element-exists? (not= (search self eid) -1)
{:n n
:entities entities
:entity-indices entity-indices
:components components} self
# take elements from end
temp (entities (- n 1))
temp-cmp (components (- n 1))]
(do (put entities (entity-indices eid) temp)
(put components (entity-indices eid) temp-cmp)
(put entity-indices temp (entity-indices eid))
(-= (self :n) 1)
true)
false))
Expand Down Expand Up @@ -84,7 +79,7 @@
:entities (array/new-filled capacity)

# dense list of component type, it is aligned with entitylist such that
# the element at entitylist[n] has component data of componentlist[n]
# the element at (entity-list n) has component data of (component-list n)
:components (array/new-filled capacity)}
@{:search search
:insert insert
Expand Down

0 comments on commit 8ea84fa

Please sign in to comment.