2 <!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
3 "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
7 <section><title>Symbols</title>
9 C++ names are converted to Lisp symbols by converting <code>camelCase</code>
10 to <code>camel-case</code>. Underscores <code>#\_</code> are replaced with
11 <code>#\-</code> and a leading uppercase K or Q is removed.
15 E.g.: <code>QHelloWorld_foo</code> becomes <code>hello-world-foo</code>.
20 <section id="classes"><title>Class</title>
22 C++ classes have a corresponding CLOS class. The can be used like any CLOS class; E.g:
23 to make a <code>QObject</code> instance:
25 <programlisting language="lisp">
26 (make-instance '<classname>qt:object</classname>)
29 Supply arguments as list to the <code>:args</code> keyword:
31 <programlisting language="lisp">
32 (let ((parent (make-instance '<classname>qt:object</classname>)))
33 (make-instance '<classname>qt:object</classname> :args (list parent)))
36 or use <code>:arg0</code>, <code>:arg1</code> and <code>:arg2</code>.
38 <programlisting language="lisp">
39 (let ((parent (make-instance '<classname>qt:object</classname>)))
40 (make-instance '<classname>qt:object</classname> :arg0 parent))
45 To extend a C++ class you have to use <classname>cxx:class</classname> as metaclass:
47 <programlisting language="lisp">
48 (defclass my-object (<classname>qt:object</classname>)
50 (:metaclass <classname>cxx:class</classname>))
52 (make-instance 'my-object)
55 The first superclass must be a Smoke class. When you define a class that has several Smoke superclasses,
56 they will be constructed with their default constructor. For the first Smoke superclass you can supply arguments
57 with the <code>:args</code> and <code>:arg0</code> etc. keywords.
59 <programlisting language="lisp">
60 (defclass my-graphics-object (<classname>qt:object</classname> <classname>qt:graphics-item</classname>)
62 (:metaclass <classname>cxx:class</classname>))
68 <section id="methods"><title>Methods</title>
70 C++ methods are generic functions in the <package>:cxx</package> package.
73 The C++ method call: <code>myInstance->frob(1);</code> is in Lisp:
75 <programlisting language="lisp">(frob my-instance 1)</programlisting>
78 <section><title>Overload Resolution</title>
80 C++ style overload resolution with conversion sequences is supported. For example this:
82 <programlisting language="lisp">
83 (<genericfunction>cxx:set-pen</genericfunction> (make-instance '<classname>qt:painter</classname>) (make-instance '<classname>qt:color</classname> :args '("green")))
88 <programlisting language="lisp">
89 (<genericfunction>cxx:set-pen</genericfunction> (make-instance '<classname>qt:painter</classname>) "green")
92 In the second case a temporary <classname>qt:color</classname> instance is implicitly created.
96 <section><title>Setter Methods</title>
98 Instead of calling a setter method that takes no additional arguments,
100 <programlisting language="lisp">
101 (<genericfunction>cxx:set-object-name</genericfunction> (make-instance '<classname>qt:object</classname>) "foo")
104 you can use its <code>setf</code>able getter.
106 <programlisting language="lisp">
107 (setf (<genericfunction>cxx:object-name</genericfunction> (make-instance '<classname>qt:object</classname>)) "foo")
113 <section><title><code>defmethod</code></title>
115 You can extend the <package>:cxx</package> generic functions by
116 adding methods. <code>:around</code>, <code>:before</code>, <code>:after</code>
117 and <code>(call-next-method)</code> are supported.
120 <programlisting language="lisp">(defclass the-object-does-nothing (<classname>qt:object</classname>)
122 (:metaclass <classname>cxx:class</classname>))
124 (defmethod <genericfunction>cxx:timer-event</genericfunction> ((object the-object-does-nothing) event)
125 (declare (ignore object event))
130 <package>:cxx</package> generic functions can be overload by argument count. Lambda list
131 keywords (e.g.: <code>&rest</code> and <code>&key</code>) are not supported.
134 Make sure you have the right number of arguments when adding a method; otherwise it will
138 The arguments of the method might have dynamic extend; i.e.: they are only valid in the body of the method.
140 <section><title>Condition</title>
142 Unwinding of the C++ stack is not supported. This means that you must not invoke a restart that skips any foreign function.
143 You will most likely encounter this problem when an error is signaled in a virtual method you have overwritten.
146 For example an event handler that is called from the C++ library.
148 </footnote>. For this case restarts are provide that allow to return a value for the failed method,
149 call the default C++ implementation instead (something like <code>#'call-next-method</code>) or retry.
153 <section><title>Operators</title>
155 Instead of using the various <code>cxx:operator</code> methods you can use their Lisp equivalent
156 in the <package>:cxx</package> package.
157 <simplelist type='horiz' columns='4'>
158 <member><code>cxx:></code></member> <!-- FIXME mb.document handling of no alphnum chars !-->
159 <member><code>cxx:>=</code></member>
161 <simplelist type='horiz' columns='4'>
162 <member><code>cxx:=</code></member>
163 <member><code>cxx:/=</code></member>
165 <simplelist type='horiz' columns='4'>
166 <member><code>cxx:<=</code></member>
167 <member><code>cxx:<</code></member>
169 <simplelist type='horiz' columns='4'>
170 <member><code>cxx:+</code></member>
171 <member><code>cxx:-</code></member>
172 <member><code>cxx:*</code></member>
173 <member><code>cxx:/</code></member>
174 <member><code>cxx:1+</code></member>
175 <member><code>cxx:1-</code></member>
177 <simplelist type='horiz' columns='4'>
178 <member><methodname>cxx:incf</methodname></member>
179 <member><methodname>cxx:decf</methodname></member>
182 <member><methodname>cxx:aref</methodname></member>
188 <section id="static_methods"><title>Static Methods</title>
190 The static C++ method <code>QByteArray::number(int n, int base=10)</code>
193 <programlisting language="lisp">(<methodname>qt:byte-array.number</methodname> 37)</programlisting>
195 which is equivalent to the C++ code <code>QByteArray::number(37);</code>.
198 <programlisting language="lisp">(<genericfunction>cxx:number</genericfunction> (find-class '<classname>qt:byte-array</classname>) 37)</programlisting>
202 <programlisting language="lisp">(<genericfunction>cxx:number</genericfunction> (make-instance '<classname>qt:byte-array</classname>) 37)</programlisting>
207 <section id="constants"><title>Constants</title>
209 C++ Class enums available as constants. E.g.:
210 <code>QColor::Rgb</code> is <constant>qt:color.+rgb+</constant>.
211 See <package>:cxx-support</package>.
215 <section id="members"><title>Member variables</title>
217 C++ member variables of an instance can be accessed by using <code>slot-value</code>; e.g.:
219 <programlisting language="lisp">(slot-value (make-instance 'qt:object) :static-meta-object)</programlisting>
223 <programlisting language="lisp">(slot-value (find-class 'qt:object) :static-meta-object)</programlisting>
225 Usually they can also be accessed using methods from the <package>:cxx</package> package.
229 <section id="gc"><title>Garbage Collection</title>
231 You should be able to use C++ Class instances like normal Lisp object.
234 C++ classes are automatically deleted when their Lisp object gets garbage collected;
235 except when they (QObjects) have a parent and thus the parent is responsible for
236 their deletion. When a <classname>qt:object</classname> has a parent, a strong
237 reference is kept to prevent the garbage collection removing it until the parent is deleted.
241 Ownership transfer for non QObject instances is mostly unimplemented.
246 <section id="core-image"><title>Saving a Core Image</title>
248 For near instant startup you can save an image. Since saving C++ instances is not supported,
249 it is best to save the image immediately after loading the packages.
253 Initializing the Smoke bindings when the image is loaded is implementation dependent. It is implemented
254 for SBCL and Clozure CL.
257 <section><title>SBCL</title>
258 <para>To save an image in SBCL you can use:
259 <ulink url="http://www.sbcl.org/manual/Saving-a-Core-Image.html"><code>sb-ext:save-lisp-and-die</code></ulink>
262 <section><title>Bundle</title>
264 To create a bundle containing an SBCL image and the required C wrappers libraries you can use
265 <methodname>smoke:save-bundle</methodname>.
266 The bundle is created using <ulink url="http://megastep.org/makeself/">makeself</ulink>.
268 <ulink url="http://tobias.rautenkranz.ch/darcsweb/darcsweb.cgi?r=cl-smoke/qt.examples;a=headblob;f=/make-bundle.sh">make-bundle.sh</ulink> in <package>:qt.examples</package> for an example.
273 <section><title>Clozure CL</title>
275 To save an image in CCL
276 <ulink url="http://ccl.clozure.com/manual/chapter4.7.html#Saving-Applications">
277 <code>ccl:save-application</code></ulink> is usually used.
281 To allow the image to find the C wrapper libraries, they have to be installed with:
287 run in the <filename>smoke/</filename> and <filename>qt/</filename> directory.