Closed porky11 closed 8 years ago
On Sat, Sep 10, 2016 at 05:42:43AM -0700, Fabio Krapohl wrote:
https://github.com/porky11/planets/blob/iterator-test/src/game.dt#L145
From the branch:
(idle-func (void)
(let ((e \ (end world)))
(for (b \ (begin world)) (< b e) (setv b (successor b))
(let ((planet (p (UniquePtr Planet)) (source b)))
(incf ($ (@:@ (@ planet) pos) 0) (@$ (@:@ (@ planet) vel) 0))
(incf ($ (@:@ (@ planet) pos) 1) (@$ (@:@ (@ planet) vel) 1)))))
(glutPostRedisplay)
(return))
'(@:@ (@ planet) pos)' expands internally to '(@ (: (@ (@ planet)) pos))'. The inner '(@ planet)' evaluates to a '(UniquePtr Planet)'. The subsequent dereference of that value (i.e. '(@ (@ planet))') copies the Planet value from the UniquePtr, so the addition operations are happening against a value that is effectively transient.
Something like the following will work:
(idle-func (void)
(let ((e \ (end world)))
(for (b \ (begin world)) (< b e) (setv b (successor b))
(let ((planet (p Planet) (get (@ (source b)))))
(incf ($ (@:@ planet pos) 0) (@$ (@:@ planet vel) 0))
(incf ($ (@:@ planet pos) 1) (@$ (@:@ planet vel) 1)))))
(glutPostRedisplay)
(return))
The main difference being the use of 'get', which returns the pointer to the memory that the UniquePtr manages, rather than copying the underlying value.
https://github.com/porky11/planets/blob/iterator-test/src/game.dt#L145