Page 1 of 1

copy values of class to other class

Posted: Sat Jan 23, 2010 6:33 am
by hewih
i'm using a 2D vector class to represent a position. one position instance is shared by some other class instances (sprite, mover). one of the class setfs the position, which creates a new instance however and sprite and mover refer to the old instance. is their a setf or something which only copies the values thus all the other classes have the updated position state? sorry for the newbish question...

the copy functions create new instances as well.
edit: something like replace which also works on structures.

Code: Select all

(defclass vec ()
  ((x :initarg :x :accessor x-of)
   (y :initarg :y :accessor y-of)))

(defmethod vec+ ((vec1 vec) (vec2 vec1))
  (make-instance 'vec
        :x (+ (vec-x vec1) (vec-x vec2))
        :y (+ (vec-y vec1) (vec-y vec2))))

(setf position (vec+ position offset))

Re: copy values of class to other class

Posted: Sat Jan 23, 2010 6:34 am
by hewih
btw: does anybody know of a good vector implementation? i found cl-vectors and vecto which seem to be vector graphics, and GSLL which i can't get to install.

Re: copy values of class to other class

Posted: Sat Jan 23, 2010 7:04 am
by ramarren
hewih wrote:'m using a 2D vector class to represent a position. the position is shared with other classes. one of the class setfs the position, which creates a new instance however and the other classes refer to the old instance. is their a setf or something which only copies the values thus all the other classes have the updated position state?
I'm sorry, but I cannot understand what you mean exactly, because you seem to confuse 'instance' and 'class'. Classes do not 'refer' to instances, if you mean instances of some other classes still refer to the old object, the obviously they do, because how would the not? In general in Lisp there is no implicit copying, so if you do not want to have new instances then do not create them. You can either mutate an existing instance, update all the references or have the references be forwarded by some mutable common object.
hewih wrote:btw: does anybody know of a good vector implementation? i found cl-vectors and vecto which seem to be vector graphics, and GSLL which i can't get to install.
Common Lisp already has vectors built-in. If you mean vector algebra, then for two dimensional case it is too trivial to create a library for (mostly applications of MAP and maybe cross-product?).

For higher dimensional vector/matrix algebra usually bindings to external libraries is used, like BLAS/LAPACK (I am not sure which bindings are best, when I needed them I just defined the few functions I needed, maybe lla or cl-blapack) or Gnu Scientific Library (bindings are GSLL which you found), but the do require installing those libraries and are probably overkill for most applications.

I think I have seen some attempts at pure CL vector/matrix libraries (for example clem), but they usually do not get that far, since this is quite hard in general, and there isn't really much point in duplicating the Fortran effort for serious applications and for less involved ones some application specific functions are quite sufficient.

Re: copy values of class to other class

Posted: Sat Jan 23, 2010 7:16 am
by hewih
i updated my post, sorry for the confusion.
what i'm looking for i a function which automatically iterates over all slots and copies them one by one.

Code: Select all

(mysteries-copy-func position (vec+ position offset))
=>
(setf (x-of position) (x-of result))
(setf (y-of position) (y-of result))
thanks for the library hints, i'll have a look at them :)

Re: copy values of class to other class

Posted: Sat Jan 23, 2010 9:18 am
by ramarren
hewih wrote:what i'm looking for i a function which automatically iterates over all slots and copies them one by one.
Something like that is in principle possible, but not a good idea from several perspectives. For one thing, it is slow since the list of slots has to be found at runtime. And usually if you want to do that a lot then your model is constructed badly. If the data is to be treated uniformly then it should be in an uniform data structure, like an array, not slots in an object instance. Then you could use standard sequence functions like MAP and MAP-INTO.

Note that if you want to access the elements by name then you can, even as generic functions/methods, since in Common Lisp methods do not belong to classes. Example, although perhaps not making that much sense:

Code: Select all

(defmethod x-of ((vec vector))
  (aref vec 0))

(defmethod (setf x-of) (new-value (vec vector))
  (setf (aref vec 0) new-value))

(defmethod y-of ((vec vector))
  (aref vec 1))

(defmethod (setf y-of) ((vec vector))
  (setf (aref vec 1) new-value))

(defparameter *test-vec1* (vector 1 2))
(defparameter *test-vec2* (vector 3 4))

Code: Select all

CL-USER> (x-of *test-vec1*)
1
CL-USER> (y-of *test-vec1*)
2
CL-USER> (x-of *test-vec2*)
3
CL-USER> (y-of *test-vec2*)
4
CL-USER> (map-into *test-vec1* #'+ *test-vec1* *test-vec2*)
#(4 6)
CL-USER> (x-of *test-vec1*)
4
CL-USER> (y-of *test-vec1*)
6

Re: copy values of class to other class

Posted: Sat Jan 23, 2010 10:09 am
by hewih
it doesn't have to iterate over the slots per se, but something that does shallow-copy, just without creating a new instance?
in C# f.e. there are classes (heap allocated) and structs (stack allocated). structs are treated just like ints and copied every time they are used.

Re: copy values of class to other class

Posted: Sat Jan 23, 2010 10:23 am
by ramarren
hewih wrote:it doesn't have to iterate over the slots per se, but something that does shallow-copy, just without creating a new instance?
I don't get it, if there is a copy, then there has to be a new instance by the very definition of the word copy, is that not so? Anyway, there is not implicit copying of anything in Common Lisp. Well, bignums maybe, but definitely no implicit copying of anything mutable. Every object has to be explicitly constructed somewhere.

Also, CL has structures which actually define a copier function. They are not automatically copied, though. And I don't really see what you are trying to achieve and how would it help.

Re: copy values of class to other class

Posted: Sat Jan 23, 2010 10:39 am
by hewih
in my game i have:
a "vector2d" class (instanced as "position1").
a method "vec-add" which creates a new instance of "vector2d".
a mover class (mover1), which refers to position1 and should change the values (x and y) every update cycle
a sprite class (sprite1), which also refers to position1

if the mover class would create a new instance every cycle, the sprite class still refers to the old position. thus, after mover has done some vector addition it should setf the position. this however changes the reference, not the values. i need a function like replace which setfs every slot of a class.

Re: copy values of class to other class

Posted: Sat Jan 23, 2010 10:58 am
by ramarren
hewih wrote:a mover class (mover1), which refers to position1 and should change the values (x and y) every update cycle
a sprite class (sprite1), which also refers to position1
It would be probably be better if sprite1 references mover1 and used position only by chaining accessors. At this point the additional memory accesses won't matter for performance, since for that just using and mutating vectors would be better, and it expresses intent better, since it explicitly signals that the sprite1 position is mover1 position, not just a position which happens to be the same.

In any case you can just mutate the object in place. There isn't really much point in automating that, as I written before if you are doing it too often to just type it out, then you are usually doing something wrong with the data model.