]> git.donarmstrong.com Git - lilypond.git/blob - lily/include/smobs.hh
48922083a9ac54c7d0e658787a62a42d0d43972a
[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--2003 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 protected: \
104         friend class Non_existant_class ; \
105         SCM smobbed_self () const; \
106 private:\
107         static scm_t_bits smob_tag_;                            \
108         static SCM mark_smob (SCM);                             \
109         static size_t free_smob (SCM s);                        \
110         static int print_smob (SCM s, SCM p, scm_print_state*); \
111 public: \
112         static SCM equal_p (SCM a, SCM b);\
113         static CL * unsmob (SCM s){\
114   if (SCM_NIMP (s) && SCM_CELL_TYPE (s) == smob_tag_)           \
115     return (CL*) SCM_CELL_WORD_1 (s);                           \
116   else                                                          \
117     return 0;                                                   \
118 }                                                               \
119         static SCM smob_p (SCM);\
120         static void init_smobs ();                              \
121 private:
122
123
124 #define DECLARE_SMOBS(CL,dummy)                                 \
125         DECLARE_SIMPLE_SMOBS (CL,dammy) \
126 protected:\
127         virtual ~CL ();\
128         SCM unprotected_smobify_self ();\
129 private: \
130         SCM smobify_self ();                                    \
131         SCM self_scm_; \
132 public: \
133         SCM self_scm () const { return self_scm_; } \
134 private:
135
136 #define DECLARE_UNSMOB(CL,name) \
137 inline CL *                                             \
138 unsmob_ ## name (SCM s)                 \
139 {                                               \
140 return  CL::unsmob (s);                         \
141 }
142
143
144
145 #endif /* SMOBS_HH */
146