Sat Apr 3 21:12:53 CEST 2010 Tobias Rautenkranz * KDE is split up in kde.ui and kde.core. Sat Apr 3 21:12:32 CEST 2010 Tobias Rautenkranz * C++ member variable access Sun Jan 10 09:57:54 CET 2010 Tobias Rautenkranz * modular smoke. Sun Dec 13 14:22:09 CET 2009 Tobias Rautenkranz * remove mudballs Wed Sep 2 14:08:06 CEST 2009 Tobias Rautenkranz * cl-smoke now supports user conversions for return values. Sun Aug 30 16:26:13 CEST 2009 Tobias Rautenkranz * Multiple inheritance doc & expand tabs in programmlisting. Thu Aug 27 13:47:08 CEST 2009 Tobias Rautenkranz * Update for the new smokegenerator Sun Aug 2 13:24:57 CEST 2009 Tobias Rautenkranz * Remove wrong note about cxx:meta-object Thu Jul 23 00:59:59 CEST 2009 Tobias Rautenkranz * add phonon repository Thu Jul 23 00:53:41 CEST 2009 Tobias Rautenkranz * phonon & :arg0 Mon Jul 6 23:51:20 CEST 2009 Tobias Rautenkranz * OpenGL: origami Fri Jul 3 00:28:43 CEST 2009 Tobias Rautenkranz * cl-smoke.commonqt & Clozure CL support Sun Jun 21 11:29:52 CEST 2009 Tobias Rautenkranz * Link Benchmark Wed Jun 10 14:17:14 CEST 2009 Tobias Rautenkranz * better Lisp source highlighting Fri Jun 5 16:17:33 CEST 2009 Tobias Rautenkranz * Lisp syntax highlighting Thu Jun 4 23:20:49 CEST 2009 Tobias Rautenkranz * interactive development Thu Jun 4 00:31:34 CEST 2009 Tobias Rautenkranz * ASDF & dispatch callback restarts diff -rN -u old-doc/Makefile new-doc/Makefile --- old-doc/Makefile 2014-10-30 08:28:01.000000000 +0100 +++ new-doc/Makefile 2014-10-30 08:28:01.000000000 +0100 @@ -1,22 +1,36 @@ # # Dependancies: -# xmllint xsltproc docbook +# - xmllint +# - saxon +# - docbook +# - xslthl # +# Debian: download the xslthl jar into the doc/ directory; install the remaining dependancies with apt. +# + +SAXON_JAR := /usr/share/java/saxon.jar +XSLTHL_JAR := $(firstword $(wildcard xslthl*.jar)) +CLASSPATH := "$(SAXON_JAR):$(XSLTHL_JAR)" +SAXON := java -classpath $(CLASSPATH) \ + -Dxslthl.config="file://$(realpath xslthl-config.xml)" \ + com.icl.saxon.StyleSheet all: manual.html index.html DEPENDANCIES := *.xml *.xsl ../qt.examples/src/*.lisp ../kde.examples/src/*.lisp *.dtd -manual.html: $(DEPENDANCIES) - xmllint --xinclude --postvalid manual.xml > /dev/null - xsltproc --xinclude -o $@ manual.xsl manual.xml - -index.html: $(DEPENDANCIES) -# xsltproc --xinclude --stringparam base.dir "manual/" chunk.xsl manual.xml - xsltproc --xinclude chunk.xsl manual.xml +# validate & process xincludes +manual.tmp: $(DEPENDANCIES) + xmllint --xinclude --postvalid manual.xml > manual.tmp + + +manual.html: manual.tmp + $(SAXON) -o manual.html manual.tmp manual.xsl + - +index.html: manual.tmp + $(SAXON) manual.tmp chunk.xsl .PHONY: clean clean: - rm -f -- *.html + rm -f -- *.html *.tmp diff -rN -u old-doc/chunk.xsl new-doc/chunk.xsl --- old-doc/chunk.xsl 2014-10-30 08:28:01.000000000 +0100 +++ new-doc/chunk.xsl 2014-10-30 08:28:01.000000000 +0100 @@ -2,13 +2,18 @@ - - + + + + + + + - + Binary files old-doc/commonqt-t14.png and new-doc/commonqt-t14.png differ diff -rN -u old-doc/introduction.xml new-doc/introduction.xml --- old-doc/introduction.xml 2014-10-30 08:28:01.000000000 +0100 +++ new-doc/introduction.xml 2014-10-30 08:28:01.000000000 +0100 @@ -14,49 +14,61 @@ Lisp-CFFI-Qt4 (dead) -
Status - -GUI creation should work and API will probably remain compatible. -The next goal is to reorganize the argument conversion / overload resolution and to -integrate more conversions between Lisp and C++ (QList etc.). - - -
Limitations +
Limitations - Limited conversions. E.g. QList<T> is missing. - - 10 seconds startup time + Ownership transfer to / from C++ of non QObject objects is seldom known to cl-smoke. + E.g.: cl-smoke might delete an instance even though it is still needed by C++. + (One that is known is QUndoStack::push().) + + Limited conversions to and from C++. You will get an NO-APPLICABLE-CXX-METHOD error + when a Lisp to C++ conversion is missing and a pointer will be returned when there is no C++ to Lisp + conversion. + + 6 seconds startup time - Using an image it is around 1 second. + Using a core image it is around 1 second. (see ) (for qt.examples) on a - Pentium M 1.7GHz. (Compilation ~20 seconds) + Pentium M 1.7GHz. Needs to be recompiled when the Smoke library is updated. - Does not recover well from errors - Thus you often need to restart the Lisp process - during interactive development.. - No const-correctness + Could be faster +
Performance + +Method calling is near 3000 times slower than native C++. The overhead is mainly in the overload +resolution and to/from foreign object translation. Some measurements by +:cl-smoke.benchmark +are in +benchmark.pdf. +
-
Installation +
Installation
Dependencies Smoke2 - bindings 4.2 or later + bindings from svn. + + The new smokegenerator is needed (developed by Arno Rehn for the GSOC 09). + + Qt (development package) CMake 2.6 - a make program (preferably Gnu Make) a C++ compiler (GCC) -On the Lisp side you need mudballs -and sysdef.cmake. + +alexandria +bordeaux-threads +cffi +closer-mop +trivial-garbage +
@@ -66,14 +78,8 @@ SBCL on Linux x86 (and x86_64) - -
-
Partial - - Clozure CL - There are some test suite failures and - it is to slow to be usable.on Linux x86. + Clozure CL on Linux x86.
@@ -93,22 +99,31 @@ You need to checkout the darcs repositories: cd SOME_DIR -for r in smoke qt qt.test qt.tests qt.examples qt.uitools qt.webkit kde kde.tests kde.examples; do +for r in smoke qt.core qt.gui qt.network qt.test qt.tests qt.examples qt.uitools qt.webkit qt.phonon; do darcs get "http://tobias.rautenkranz.ch/lisp/cl-smoke/$r" done - Then add the directory SOME_DIR to the mudballs search paths by adding - -(push (wildcard-searcher "SOME_DIR/*/*.mbd") - *custom-search-modules*) - - to ~/.mudballs. - - - - Loading the packages with mb:load compiles the C wrapper libraries as needed. - - + + + There are also the following repositories: qt.svg qt.dbus kde.core kde.ui kde.tests kde.examples + + + + + Build and install the :smoke and :qt.core C wrapper libraries with: + + cmake ./ && make && sudo make install + + in the smoke/ and qt/ directories. + + + When you have symlinked the .asd system files, you + should be able to load the systems. The system name has a + :cl-smoke. prefix. e.g.: + + (asdf:oos 'asdf:load-op :cl-smoke.qt.examples) + +
diff -rN -u old-doc/kde.xml new-doc/kde.xml --- old-doc/kde.xml 2014-10-30 08:28:01.000000000 +0100 +++ new-doc/kde.xml 2014-10-30 08:28:01.000000000 +0100 @@ -4,19 +4,23 @@ KDE -Besides the :kde package there +To use the KDE libraries use the :cl-smoke.kde.ui +(Depends on :cl-smoke.kde.core). + + +Besides these packages there is :kde.tests for the unit tests and :kde.examples containing the examples. -
Examples +
Examples The examples can be run with: - -(mb:load :kde.examples) + +(asdf:oos 'asdf:load-op :cl-smoke.kde.examples) -An the running the function of the example; e.g.: - +And then running the function of the example; e.g.: + (kde.examples:mandelbrot) diff -rN -u old-doc/lisp-hl.xml new-doc/lisp-hl.xml --- old-doc/lisp-hl.xml 1970-01-01 01:00:00.000000000 +0100 +++ new-doc/lisp-hl.xml 2014-10-30 08:28:01.000000000 +0100 @@ -0,0 +1,167 @@ + + + + + call-next-method + do-external-symbols + do + do* + eval-when + handler-bind + handler-case + in-package + let* + multiple-value-bind + restart-bind + restart-case + return-from + signal + unwind-protect + + + + + + assert + block + case + catch + ccase + cerror + check-type + declaim + declare + defclass + defconstant + defgeneric + define-condition + defmacro + defmethod + defpackage + defparameter + defstruct + deftype + defun + defvar + dolist + dotimes + ecase + error + flet + go + if + labels + lambda + let + loop + proclaim + prog1 + prog2 + progn + progv + return + tagbody + throw + typecase + unless + warn + when + + + + + + (?<=\()(\S+[:])?(with-\S+) + + + + + + #| + |# + + + + ; + + + + + " + + + + + + (?<=[ \(])(:[^\s\)]+) + + + + + + &allow-other-keys + &aux + &body + &environment + &key + &optional + &rest + &whole + + + + + + + + + (?<=defclass\s)(\S+) + + CASE_INSENSITIVE + + + + (?<=defun\s)(\S+) + + + + + (?<=defmacro\s)(\S+) + + + + + (?<=defgeneric\s)(\S+) + + + + + (?<=defmethod\s)(\S+) + + + + + (?<=defvar\s)(\S+) + + + + + (?<=defparameter\s)(\S+) + + + + + (?<=defconstant\s)(\S+) + + + + + (?<=defstruct\s)(\S+) + + + + + (?<=define-condition\s)(\S+) + + + diff -rN -u old-doc/manual.xsl new-doc/manual.xsl --- old-doc/manual.xsl 2014-10-30 08:28:01.000000000 +0100 +++ new-doc/manual.xsl 2014-10-30 08:28:01.000000000 +0100 @@ -2,7 +2,13 @@ - - + + + + + + + + diff -rN -u old-doc/nonlink-apidoc.xsl new-doc/nonlink-apidoc.xsl --- old-doc/nonlink-apidoc.xsl 1970-01-01 01:00:00.000000000 +0100 +++ new-doc/nonlink-apidoc.xsl 2014-10-30 08:28:01.000000000 +0100 @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + Binary files old-doc/origami.ogg and new-doc/origami.ogg differ Binary files old-doc/origami.png and new-doc/origami.png differ diff -rN -u old-doc/qt.xml new-doc/qt.xml --- old-doc/qt.xml 2014-10-30 08:28:01.000000000 +0100 +++ new-doc/qt.xml 2014-10-30 08:28:01.000000000 +0100 @@ -4,26 +4,40 @@ Qt -Besides the :qt there are these packages: with +Besides the :cl-smoke.qt.gui there are these modules: - - :qt.uitools - - QtUiTools - :qt.test - - QtTest - :qt.webkit - - QtWebKit - + + :cl-smoke.qt.uitools + + QtUiTools + :cl-smoke.qt.test + + QtTest + :cl-smoke.qt.webkit + + QtWebKit + + :cl-smoke.qt.phonon + + Phonon + + :cl-smoke.qt.network + The network classes of Qt. + + :cl-smoke.qt.core + the nogui Qt core. + -which provide bindings for their Qt module. -Additionally there is the :qt.tests system, containing -the unit tests and :qt.examples for various examples. +which provide bindings for their Qt module. The class names of this modules are in +the :qt package. (E.g. Phonon::VideoPlayer is 'qt:phonon.video-player +and QTest is 'qt:test) + + +Additionally there is the :cl-smoke.qt.tests system, containing +the unit tests and :cl-smoke.qt.examples for various examples. -
qt:application +
qt:application The qt:application object should created with: qt:with-app. In its body the event loop can be @@ -34,17 +48,41 @@ - + - + + +Subclasses of qt:paint-device (e.g. qt:widget) can only be used when +a qt:application instance exists. When there are, for example, qt:widget instances +at the end of qt:with-app, they are deleted by the qt:application destructor. + + +Custom cxx:paint-event methods can use qt:with-painter +to ensure that the qt:painter is deactivated at the end of the method. + + +
Interactive Development + +The :cl-smoke.repl allows you to start a qt:application event loop in the background for +interactive development in SLIME. +To start the event loop use cl-smoke.repl:start-event-loop-in-background (or +cl-smoke.repl:start-event-loop-in-repl). + + +Currently START-EVENT-LOOP-IN-BACKGROUND is recommended. + + +As long as you do not kill the thread or unwind over a foreign function, you should be fine. + +
-
Signal-Slot +
Signal-Slot qt:connect connects a signal to a slot. The signal is either a qt:qsignal created with @@ -54,14 +92,15 @@ or a C++ slot a return from qt:get-slot. Quit - + When the argument types for a slot or signal are not specified they are determined when the first connection is made. Note that when connecting a qt:qsignal -to a qt:qslot at least one must have its arguments types specified. +to a qt:qslot at least one must have its arguments types specified. Type specifier T +allows to pass a Lisp object as is from a Lisp signal to a Lisp slot. @@ -70,23 +109,24 @@
-
Properties +
Properties qt:object properties can be accessed with qt:property (setf-able). The name of the property can be either a string in C++ style or a symbol in Lisp style. +The predefined Qt properties can be accessed with symbols in the keyword package. - + (let ((object (make-instance 'qt:object))) - (setf (qt:property object 'object-name) "Foo") - (assert (string= "Foo" (qt:property object "objectName")))) + (setf (qt:property object :object-name) "Foo") + (assert (string= "Foo" (qt:property object "objectName"))))
-
Variant +
Variant A qt:variant can be constructed with qt:make-variant or to pass a Lisp object with qt:make-lisp-variant. @@ -94,7 +134,7 @@
-
i18n +
i18n You can use qt:tr to translate strings. @@ -103,22 +143,22 @@ - + - + - + <filename>hello-world_de.po</filename> - + @@ -127,15 +167,15 @@ Gettext is used to extract the i18n strings and compile the message catalog. See CMakeLists.txt and UseClQti18n.cmake -in the src directory of :qt.examples how to do this. +in the src/ directory of :cl-smoke.qt.examples on how to do this.
-
Examples +
Examples You can run the examples with: - -(mb:load :qt.examples) + +(asdf:oos 'asdf:load-op :cl-smoke.qt.examples) (qt.examples:launcher) @@ -149,33 +189,60 @@ - + - + Class Browser -Qt Classes browser using :qt.webkit to display the +Qt Classes browser using :cl-smoke.qt.webkit to display the API doc and a custom qt:list-model for the qt:list-view of the available classes. - + - +
+
OpenGL + +For OpenGL a binding is needed (e.g.: +cl-opengl). + +Origami + +Origami +draws a pleated hyperbolic paraboloid using the method described in +(Non)existence of Pleated Folds: How Paper Folds Between Creases + + + + + + + + + +Axiom is needed to generate the lisp source to that +calculates the vertices. + + + + +
+ diff -rN -u old-doc/smoke.xml new-doc/smoke.xml --- old-doc/smoke.xml 2014-10-30 08:28:01.000000000 +0100 +++ new-doc/smoke.xml 2014-10-30 08:28:01.000000000 +0100 @@ -1,7 +1,7 @@ - + Usage
Symbols @@ -10,82 +10,100 @@ to camel-case. Underscores #\_ are replaced with #\- and a leading uppercase K or Q is removed. + E.g.: QHelloWorld_foo becomes hello-world-foo. +
-
Class +
Class C++ classes have a corresponding CLOS class. The can be used like any CLOS class; E.g: to make a QObject instance: - + (make-instance 'qt:object) Supply arguments as list to the :args keyword: - + +(let ((parent (make-instance 'qt:object))) + (make-instance 'qt:object :args (list parent))) + + +or use :arg0, :arg1 and :arg2. + + (let ((parent (make-instance 'qt:object))) - (make-instance 'qt:object :args (list parent))) + (make-instance 'qt:object :arg0 parent)) To extend a C++ class you have to use cxx:class as metaclass: - + (defclass my-object (qt:object) - () - (:metaclass cxx:class)) + () + (:metaclass cxx:class)) + +(make-instance 'my-object) + + +The first superclass must be a Smoke class. When you define a class that has several Smoke superclasses, +they will be constructed with their default constructor. For the first Smoke superclass you can supply arguments +with the :args and :arg0 etc. keywords. + + +(defclass my-graphics-object (qt:object qt:graphics-item) + () + (:metaclass cxx:class))
-
Methods +
Methods -C++ methods are generic functions in the :cxx package. +C++ methods are generic functions in the :cxx package. The C++ method call: myInstance->frob(1); is in Lisp: -(frob my-instance 1) +(frob my-instance 1)
Overload Resolution C++ style overload resolution with conversion sequences is supported. For example this: - + (cxx:set-pen (make-instance 'qt:painter) (make-instance 'qt:color :args '("green"))) is equivalent to: - + (cxx:set-pen (make-instance 'qt:painter) "green") In the second case a temporary qt:color instance is implicitly created. - -User defined conversions for return values are currently not supported (in defmethods). -
Setter Methods Instead of calling a setter method that takes no additional arguments, - + (cxx:set-object-name (make-instance 'qt:object) "foo") you can use its setfable getter. - + (setf (cxx:object-name (make-instance 'qt:object)) "foo") @@ -99,13 +117,13 @@ and (call-next-method) are supported. -(defclass the-object-does-nothing (qt:object) - () - (:metaclass cxx:class)) +(defclass the-object-does-nothing (qt:object) + () + (:metaclass cxx:class)) (defmethod cxx:timer-event ((object the-object-does-nothing) event) - (declare (ignore object event)) - (call-next-method)) + (declare (ignore object event)) + (call-next-method)) @@ -116,6 +134,21 @@ Make sure you have the right number of arguments when adding a method; otherwise it will not be called. + +The arguments of the method might have dynamic extend; i.e.: they are only valid in the body of the method. + +
Condition + +Unwinding of the C++ stack is not supported. This means that you must not invoke a restart that skips any foreign function. +You will most likely encounter this problem when an error is signaled in a virtual method you have overwritten. + + +For example an event handler that is called from the C++ library. + +. For this case restarts are provide that allow to return a value for the failed method, +call the default C++ implementation instead (something like #'call-next-method) or retry. + +
Operators @@ -152,54 +185,60 @@
-
Static Methods +
Static Methods The static C++ method QByteArray::number(int n, int base=10) can be called by: -(qt:byte-array.number 37) +(qt:byte-array.number 37) which is equivalent to the C++ code QByteArray::number(37);. Or with: -(cxx:number (find-class 'qt:byte-array) 37) +(cxx:number (find-class 'qt:byte-array) 37) or: -(cxx:number (make-instance 'qt:byte-array) 37) +(cxx:number (make-instance 'qt:byte-array) 37)
-
Constants +
Constants + + C++ Class enums available as constants. E.g.: + QColor::Rgb is qt:color.+rgb+. + See :cxx-support. + +
+ +
Member variables - C++ Class enums available as constants. E.g.: - QColor::Rgb is qt:color.+rgb+. - See :cxx-support. +C++ member variables of an instance can be accessed by using slot-value; e.g.: + +(slot-value (make-instance 'qt:object) :static-meta-object) + +or + +(slot-value (find-class 'qt:object) :static-meta-object) + +Usually they can also be accessed using methods from the :cxx package.
-
Garbage Collection +
Garbage Collection You should be able to use C++ Class instances like normal Lisp object. -C++ classes are automatically deleted when their lisp object gets garbage collected; +C++ classes are automatically deleted when their Lisp object gets garbage collected; except when they (QObjects) have a parent and thus the parent is responsible for their deletion. When a qt:object has a parent, a strong -reference is kept to prevent its garbage collection until the parent is deleted. +reference is kept to prevent the garbage collection removing it until the parent is deleted. -An instance may depend on an other one. -It is a bad idea to do something like this: - -(defvar *meta* (cxx:meta-object (make-instance 'qt:object))) - -*meta* references a qt:meta-class -that can become invalid at any time, since the qt:object instance can -be garbage collected, and then the QMetaObject instance is deleted along -with the QObject. + Ownership transfer for non QObject instances is mostly unimplemented.
diff -rN -u old-doc/video.xsl new-doc/video.xsl --- old-doc/video.xsl 1970-01-01 01:00:00.000000000 +0100 +++ new-doc/video.xsl 2014-10-30 08:28:01.000000000 +0100 @@ -0,0 +1,27 @@ + + + + + + + + + diff -rN -u old-doc/xslthl-config.xml new-doc/xslthl-config.xml --- old-doc/xslthl-config.xml 1970-01-01 01:00:00.000000000 +0100 +++ new-doc/xslthl-config.xml 2014-10-30 08:28:01.000000000 +0100 @@ -0,0 +1,5 @@ + + + + +