]> git.donarmstrong.com Git - lilypond.git/blob - lily/include/smobs.hh
* The grand 2005-2006 replace.
[lilypond.git] / lily / include / smobs.hh
1 /*
2   smobs.hh -- declare smob related stuff.
3
4   source file of the GNU LilyPond music typesetter
5
6   (c) 1999--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
7 */
8
9 #ifndef SMOBS_HH
10 #define SMOBS_HH
11
12 #include "lily-guile.hh"
13
14 /*
15   Smobs are GUILEs mechanism of exporting C(++) objects to the Scheme
16   world.  They are documented in the GUILE manual.
17
18
19   In LilyPond, smobs are created from C++ objects through macros.
20   There are two types of smob objects.
21
22   1. Simple smobs are intended for simple objects like numbers:
23   immutable objects that can be copied without change of meaning.
24
25   To obtain an SCM version of a simple smob, use the member function
26   SCM smobbed_copy ().
27
28   Simple smobs are created by adding the
29   DECLARE_SIMPLE_SMOBS(Classname, ) to the declaration
30
31   2. Complex smobs are objects that have an identity. These objects
32   carry this identity in the form of a self_scm () method, which is a
33   SCM pointer to the object itself.
34
35   The constructor for a complex smob should have 3 steps:
36
37   * initialize all SCM members to a non-immediate value (like SCM_EOL)
38
39   * call smobify_self ()
40
41   * initialize SCM members
42
43   For example,
44
45   Complex_smob::Complex_smob () {
46   scm_member_ = SCM_EOL;
47   smobify_self ();
48   scm_member_ = <..what you want to store..>
49   }
50
51   after construction, the self_scm () field of a complex smob is
52   protected from Garbage Collection.  This protection should be
53   removed once the object is put into another (reachable) Scheme data
54   structure, i.e.
55
56   Complex_smob *p = new Complex_smob;
57   list = scm_cons (p->self_scm (), list);
58   scm_gc_unprotect_object (p->self_scm ());
59
60   Complex smobs are made with DECLARE_SMOBS (Classname, ) in the class
61   declaration.
62
63   CALLING INTERFACE
64
65   Common public methods to C++ smob objects:
66
67   unsmob (SCM x)  - unpacks X and returns pointer to the C++ object, or 0
68   if it has the wrong type.
69
70   SCM equal_p (SCM a, SCM b) - compare A and B. Returns a Scheme boolean
71
72
73   IMPLEMENTATION
74
75   For implementating a class, the following should be provided
76
77   - an equal_p () function (a default is in the
78   IMPLEMENT_DEFAULT_EQUAL_P macro in ly-smobs.icc)
79
80   - mark_smob () function, that calls scm_gc_mark () on all Scheme
81   objects in the class
82
83   - a print_smob () function, that displays a representation for
84   debugging purposes
85
86   - A call to one of the IMPLEMENT_SMOBS or IMPLEMENT_SIMPLE_SMOBS macros
87   from file "ly-smobs.icc"
88 */
89
90 #define DECLARE_SIMPLE_SMOBS(CL, dummy)         \
91   public:                                       \
92   SCM smobbed_copy () const;                    \
93   DECLARE_BASE_SMOBS (CL)
94
95 #define DECLARE_BASE_SMOBS(CL)                                  \
96   friend class Non_existent_class;                              \
97   private:                                                      \
98   static scm_t_bits smob_tag_;                                  \
99   static SCM mark_smob (SCM);                                   \
100   static size_t free_smob (SCM s);                              \
101   static int print_smob (SCM s, SCM p, scm_print_state*);       \
102   public:                                                       \
103   static SCM equal_p (SCM a, SCM b);                            \
104   static CL *unsmob (SCM s)                                     \
105   {                                                             \
106     if (SCM_NIMP (s) && SCM_CELL_TYPE (s) == smob_tag_)         \
107       return (CL *) SCM_CELL_WORD_1 (s);                        \
108     else                                                        \
109       return 0;                                                 \
110   }                                                             \
111   static SCM smob_p (SCM);                                      \
112   static void init_smobs ();                                    \
113   private:
114
115 #define DECLARE_SMOBS(CL, dummy)                \
116   DECLARE_BASE_SMOBS (CL)                       \
117     protected:                                  \
118   virtual ~CL ();                               \
119   SCM unprotected_smobify_self ();              \
120   private:                                      \
121   void smobify_self ();                         \
122   SCM self_scm_;                                \
123   SCM protection_cons_;                         \
124   public:                                       \
125   SCM unprotect ();                             \
126   void protect ();                              \
127   SCM self_scm () const { return self_scm_; }   \
128   private:
129
130 #define DECLARE_UNSMOB(CL, name)                \
131   inline CL *                                   \
132   unsmob_ ## name (SCM s)                       \
133   {                                             \
134     return CL::unsmob (s);                      \
135   }
136
137 #define DECLARE_TYPE_P(CL) extern SCM CL ## _type_p_proc
138
139 void protect_smob (SCM smob, SCM *prot_cons);
140 void unprotect_smob (SCM *prot_cons);
141
142 #endif /* SMOBS_HH */
143