]> git.donarmstrong.com Git - lilypond.git/blob - lily/include/smobs.hh
* lily/global-context.cc (run_iterator_on_me): fix grace note
[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--2004 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7   
8  */
9
10 #ifndef SMOBS_HH
11 #define SMOBS_HH
12
13 #include "lily-guile.hh"
14
15
16 /*
17
18    Each smobbed C-object may only be interfaced by a single, unique
19    smob cell. Therefore NEVER provide a public function that will
20    create a smobcell for an existing object pointer.
21
22    There are two ways to reach this goal:
23
24    simple smobs:
25
26    - Data structures that are encapsulated by GUILE. If constructed
27    through GUILE, you may only store them as protected SCMs, and may
28    not copy the pointer the object itself. Typical interface
29
30    struct Ssmob {
31    public:
32      SCM make_copy_scm () const {
33        Ssmob *sp = new Ssmob (*this);
34        return sp->smobbed_self ();
35      }
36    };
37
38    or
39
40    struct Ssmob {
41    public:
42      DECLARE_SIMPLE_SMOBS;
43      static SCM make_scm (void initdata) {
44        Ssmob * sp = new Ssmob (initdata);
45        return sp->smobbed_self ();
46      }
47    private:
48      Ssmob (initdata);
49    }
50
51    Objets of type Ssmob may live on the stack, or on the heap, or as
52    part of other objects.  However, as soon as the object is smobbed,
53    by definition (by definition of the constructors, in this example),
54    lives on the heap as a separate object
55    
56    - complex smobs: data structures whose identity is referenced and
57    stored both in C++ and in GUILE form. From going from C++ to GUILE,
58    you use smob_ptr->self_scm_
59
60    class Csmob {
61      DECLARE_SMOBS;
62      Csmob () { smobify_self (); }
63      Csmob (Csmob const & s) {
64        // don't copy self_scm_
65        smobify_self ();
66      }
67    };
68    
69    A complex smob is a C++ class with static member functions to glue
70    it with Scheme. Every instance carries SELF_SCM_, a pointer to the
71    unique Scheme smob cell of itself.
72
73    Upon creation, SELF_SCM_ is protected, so if you choose to store it
74    in C++ structures, you need to do
75
76    class Bla {
77    Csmob *ptr;
78    ~Bla () {  scm_gc_unprotect_object (ptr->self_scm_); }
79    
80    };
81
82    If protection is done via GUILE, don't forget to unprotect AFTER putting
83    stuff into the GUILE datastructs
84
85
86    guile_data = gh_cons (ptr->self_scm_, guile_data);
87    ptr->self_scm_
88
89    Since GUILE takes care of the freeing the object, the destructor
90    is private.
91
92    DUMMY a thing to make sure compiles only work if this header
93    if this file is there.
94
95
96    WARNING:
97
98    smobify_self () might trigger a GC, so make sure that objects are  
99    sane when you do smobify_self ().
100 */
101
102 #define DECLARE_SIMPLE_SMOBS(CL,dummy) \
103 public: \
104         SCM smobbed_copy () const; \
105 DECLARE_BASE_SMOBS(CL)
106
107
108 #define DECLARE_BASE_SMOBS(CL) \
109         friend class Non_existant_class ; \
110 private:\
111         static scm_t_bits smob_tag_;                            \
112         static SCM mark_smob (SCM);                             \
113         static size_t free_smob (SCM s);                        \
114         static int print_smob (SCM s, SCM p, scm_print_state*); \
115 public: \
116         static SCM equal_p (SCM a, SCM b);\
117         static CL * unsmob (SCM s){\
118   if (SCM_NIMP (s) && SCM_CELL_TYPE (s) == smob_tag_)           \
119     return (CL*) SCM_CELL_WORD_1 (s);                           \
120   else                                                          \
121     return 0;                                                   \
122 }                                                               \
123         static SCM smob_p (SCM);\
124         static void init_smobs ();                              \
125 private:
126
127
128 #define DECLARE_SMOBS(CL,dummy)                                 \
129         DECLARE_BASE_SMOBS (CL) \
130 protected:\
131         virtual ~CL ();\
132         SCM unprotected_smobify_self ();\
133 private: \
134         SCM smobify_self ();                                    \
135         SCM self_scm_; \
136 public: \
137         SCM self_scm () const { return self_scm_; } \
138 private:
139
140 #define DECLARE_UNSMOB(CL,name) \
141 inline CL *                                             \
142 unsmob_ ## name (SCM s)                 \
143 {                                               \
144 return  CL::unsmob (s);                         \
145 }
146
147
148
149 #endif /* SMOBS_HH */
150