Page 1 of 1

Classes as slots in other classes and package definition

Posted: Tue Nov 02, 2010 2:35 pm
by indianerrostock
Hello,

I wrote three classes (each in a single file) and wanted to use two of the classes as slots in the first class.

Two of the slots in the unit class are the unit-type and the unit-attributes class.

The unit class:

Code: Select all

(defclass unit()
  ((unit-name
     :initarg :unit-name
     :initform (error "Must supply an unit name.")
     :accessor unit-name
     :documentation "Name of the unit.")
   (unit-race
     :initarg :unit-race
     :initform (error "Must supply an unit race.")
     :accessor unit-race
     :documentation "Race of the unit.")
   (unit-type
     :initarg :unit-type
     :initform (error "Must supply an unit type.")
     :accessor unit-type
     :documentation "Type of the unit.")
   (unit-attributes
     :initarg :unit-attributes                                                                                                                                              
     :initform (error "Must supply unit attributes.")
     :accessor unit-attributes
     :documentation "The attributes of the unit.")
   (unit-size)
   (unit-equipment)
   (unit-rules)
   (unit-options))
  (:documentation "A figure or a group of figures that represent one unit."))
The unit-type and the unit-attributes classes:

Code: Select all

(defclass unit-type()
  ((name
     :initarg :name
     :initform (error "Must supply a type name.")
     :accessor name            
     :documentation "Name of the unit."))
  (:documentation "Type of the unit like hero, specialist or squad."))

(defclass unit-attributes()    
  ((strength
     :initarg :strength        
     :initform (error "Must supply a strength.")
     :accessor strenth         
     :documentation "Strength of the unit.")
   (dexterity
     :initarg :dexterity
     :initform (error "Must supply a dexterity.")
     :accessor dexterity
     :documentation "Dexterity of the unit."))
  (:documentation "Attributes of the unit like strength, dexterity, etc."))
My questions:

(1)
If I initialize the unit class with make-instance, do I also have to initialize the slot values of the unit-type and the unit-attributes classes with make-instance?

(2)
These classes are in an adt directory. I read about the packages macro (defpackage) and the in-package method. Where do I have to put the defpackage definition and where do I have to use in-package? I did not really understand the way, where to put the methods and where to load the classes.

Many thanks for any answers.

Re: Classes as slots in other classes and package definition

Posted: Wed Nov 03, 2010 5:06 pm
by Paul Donnelly
indianerrostock wrote:(1)
If I initialize the unit class with make-instance, do I also have to initialize the slot values of the unit-type and the unit-attributes classes with make-instance?
That depends. Is there a reasonable default? You could supply it as an :initform. What you probably want to do is define a constructor. That way you can't forget required parameters.

Code: Select all

(defun make-unit (name type)
  (make-instance 'unit :unit-name name :unit-type (make-instance type)))
indianerrostock wrote:(2)
These classes are in an adt directory. I read about the packages macro (defpackage) and the in-package method. Where do I have to put the defpackage definition and where do I have to use in-package? I did not really understand the way, where to put the methods and where to load the classes
You put in-package at the top of a file. A defpackage can go anywhere (including being typed at the REPL, although that would not be convenient), as long as it's been encountered before you try to use the package. Methods and classes can also go where you like, although I think a class may need to be defined before you define methods operating on it, or at least defined in the same file.

Re: Classes as slots in other classes and package definition

Posted: Fri Nov 05, 2010 10:34 am
by Warren Wilkinson
To your first question: Yes.

However, you could do something like this

Code: Select all

(defvar *hero-type* (make-instance 'unit-type :name "Hero"))
And pass *hero-type* instead of constantly creating new instances. Just be careful because if your code modifies a units type destructively [for example (setf (name (unit-type self)) "AntiHero")] , its modified for every unit that shared that type instance.

To your second question:

I always put something like this at the top of my files.

Code: Select all

(defpackage :web.render
  (:use :common-lisp :cl-who :util.util :util.tree :util.tagged :http.http :web.uivar :web.designer :web.parser)
  (:export render pretend render-text))

(in-package :web.render)
But can I make some super cool suggestions for you?

A lot of video games manage constant unit information as structures in a big array and they keep variable sized information OUT of the structure. This makes data management easy, especially for languages that aren't as high level as Lisp.

Code: Select all

(defstruct info
   (id 0 :type (unsigned-byte 16))
   (race 0 :type (unsigned-byte 2))  ;; 0 - 3
   (size 2 :type (unsigned-byte 6))  ;; 0 - 63
   (flags 0 :type (unsigned-byte 32)))
You would try to boil down your custom rules and options to a set of flags (http://en.wikipedia.org/wiki/Flag_(computing)). Then you would build
your INFO array as a constant in memory:

Code: Select all

(defvar *types* (make-array 10 :initial-contents (list (make-info 0 0 2 #xFFFFFFFF)
                                                                              (make-info 1 0 2 #xFFFFFFFF)
                                                                              ...
                                                                              (make-info 9 0 2 #xFFFFFFFF)))
Your runtime information (like unit name, changable attributes, equipment, current hit points/mana, etc) goes into class instances (or whatever) that refer to an info ID. Its not a bad way to organize this sort of data, most RTS's operate this way.

Re: Classes as slots in other classes and package definition

Posted: Sat Nov 13, 2010 2:42 pm
by indianerrostock
Thank you for these interesting answers.