Kenny, Cell'ers:
I have defined a macro defapp as a convenience macro for defining Cello applications:
;;; ------------------------------------------------------------------------ ---- ;;; defapp - Define an applicatin window to be run as a Cello app. MACRO ;;; ------------------------------------------------------------------------ ---- ;;; Arguments are normal defclass arguments. Creates a class as a subclass of ;;; gt.app using Cells' defmodel. ;;; ;;; Side effects: ;;; Two other functions %%RUN-... and RUN-... are defun'd (all %%... named fns ;;; are purely internal functions not to be called outside of this package!!!) ;;; A (defapp my-app ... ) defines the user callable fn RUN-MY-APP. ;;; This function is to be called to run the application my-app. ;;; ;;; STATUS: Released.
(defmacro defapp (class directsupers slotspecs &rest options) `(prog1 (defmodel ,class ,(or directsupers '(gt.app)) ,slotspecs ,(car options)) (finalize-inheritance (find-class ',class)) (defun ,(intern (conc$ "%%RUN-" (symbol-name class))) (w-t-f) (declare (ignore w-t-f)) (cl-user::gc t) ;; Oddity in ACL: without gc-ing here ACL errors (cells-reset 'ctk:tk-user-queue-handler) (wands-clear) (ctk::test-window ',class)) (defun ,(intern (conc$ "RUN-" (symbol-name class))) () (mk-thread ,(with-output-to-string (stream) (format stream "APPLICATION-THREAD-~A" (symbol-name class))) ',(intern (conc$ "%%RUN-" (symbol-name class))))) (export ',(intern (conc$ "RUN-" (symbol-name class)))) (export ',(intern (symbol-name class))) ))
The class gt.app is defined as:
;;; ------------------------------------------------------------------------ ---- ;;; gt.app - Application Base Class CLASS ;;; ------------------------------------------------------------------------ ---- ;;; STATUS: Released.
(defmodel gt.app ( cello-window ) ((.md-name :cell t :accessor id :initform (c-in nil) :initarg :id :documentation "The model ID of the instance of the application.") (init-fn :cell nil :accessor init-fn :initform nil :initarg :initfn :documentation "Function to be called before running the application.") (status :cell t :accessor status :initform (c-in nil) :initarg :status :documentation "Status := { :CREATED | :INITIALIZING | :RUNNING | :SHUTTDING- DOWN | :HALTED | :BLOCKED }") (opcode :cell t :accessor opcode :initform (c-in nil) :initarg :opcode :documentation "Operation Code := { :INIT | :RUN | :SHUTDOWN }") (current-opcode-task :cell t :accessor current-opcode-task :initform (application-current-opcode-task-cell-rule) :initarg :current-opcode-task :documentation "Holds the Cell Rule to execute a task depending on the opcode slot.") (main-thread :cell t :accessor main-thread :initform (c-in nil) :initarg :main-thread :documentation "Holds the thread object created by RUN-... (which calls mk- thread)")) (:documentation "gt.app - Application Base Class CLASS"))
Using the macro like this:
(defapp my-app () () (:default-initargs :id :my-app :kids (c? (the-kids (mk-stack (:packing (c?pack-self)) (mk-row () (mk-label :text "Status : " :width 15) (mk-label :text (c_? (status (fm-other :my-app))))) (mk-row () (mk-label :text "Opcode : " :width 15) (mk-label :text (c_? (opcode (fm-other :my-app))))))))))
expands into:
(PROG1 (DEFMODEL MY-APP (GT.APP) NIL (:DEFAULT-INITARGS :ID :MY-APP :KIDS (C? (THE-KIDS (MENUBAR) (MK-STACK (:PACKING (C?PACK-SELF)) (MK-ROW NIL (MK-LABEL :TEXT "Status : " :WIDTH 15) (MK-LABEL :TEXT (C_? (STATUS (FM-OTHER :MY-APP))))) (MK-ROW NIL (MK-LABEL :TEXT "Opcode : " :WIDTH 15) (MK-LABEL :TEXT (C_? (OPCODE (FM-OTHER :MY-APP)))))))))) (FINALIZE-INHERITANCE (FIND-CLASS 'MY-APP)) (DEFUN %%RUN-MY-APP (GT.APP.BASE::W-T-F) (DECLARE (IGNORE GT.APP.BASE::W-T-F)) (EXCL:GC T) (CELLS-RESET 'TK-USER-QUEUE-HANDLER) (MGK:WANDS-CLEAR) (TEST-WINDOW 'MY-APP)) (DEFUN RUN-MY-APP () (GT.APP.BASE::MK-THREAD "APPLICATION-THREAD-MY-APP" '%%RUN-MY-APP)) (EXPORT 'RUN-MY-APP) (EXPORT 'MY-APP))
I can see no error in this. Yet there are undefined functions status and opcode:
;;; Compiling file /tmp/tempa24242105201 ;;; Writing fasl file /tmp/tempa24242105201.fasl ;;; Fasl write complete Warning: While compiling these undefined functions were referenced: STATUS from position 336 in #1=test.lisp;483 OPCODE from position 336 in #1#
While this is a clear error message I don't see what I can against nor where my error is.... Any help really appreciated !!! TIA!
Frank
On 8/27/06, Frank Goenninger fgoenninger@prion.de wrote:
Am 27.08.2006 um 21:39 schrieb Ken Tilton:
Looking at it. Why the finalize-inheritance? kt
Because ACL says, upon inspecting the returned class object, that the class is not finalized yet.
The bastards! <g> Actually, there is no harm in that and it is the normal case with CLOS. CLOS does not finalize until it has to (when we make an instance) which is why superclasses can be defined after subclasses.
kt
On 8/27/06, Ken Tilton kentilton@gmail.com wrote:
Looking at it. Why the finalize-inheritance? kt
Good thing you included the macro-expansion. :) I see:
GT.APP.BASE::
...a couple of places. Your error sounds like a package issue. So I think you need to cobble together a fuller code chunk (including all relevant defpackages and maybe adding some in-package forms) and make sure the only errors you get are status and opcode and send that along. (A couple of functions are missing as well.)
If you want to research on your own, just use (apropos "OPCODE") and see how many symbols pop up and to what package they belong, etc etc.
hth, kt
Am 27.08.2006 um 21:48 schrieb Ken Tilton:
Good thing you included the macro-expansion. :) I see:
GT.APP.BASE::
...a couple of places. Your error sounds like a package issue.
It was. Now solved. Had export those two functions from the gt.app.base package.
Thx! Excellent help, Kenny! You should charge for it. (Just kidding ... <g>)
Frank
On 8/27/06, Frank Goenninger fgoenninger@prion.de wrote:
Am 27.08.2006 um 21:48 schrieb Ken Tilton:
Good thing you included the macro-expansion. :) I see:
GT.APP.BASE::
...a couple of places. Your error sounds like a package issue.
It was. Now solved. Had export those two functions from the gt.app.base package.
Thx! Excellent help, Kenny! You should charge for it. (Just kidding ... <g>)
I have to say, it takes me even now more than a few seconds for the light to go on when I get one of these errors, perhaps because the error is never "unknown symbol", CL just makes a new one in the current package and then finally gives the warning "function undefined". This gets especially nasty when we are doing GFs and we really do have methods defined that miraculously are not being run (because we end up with two GFs, one on each symbol).
So anyway, the moral is, "When an error makes absolutely no sense, or when a method that should run is not running, think "package error".)
hth, kt
On 8/27/06, Ken Tilton kentilton@gmail.com wrote:
On 8/27/06, Ken Tilton kentilton@gmail.com wrote:
Looking at it. Why the finalize-inheritance? kt
Good thing you included the macro-expansion. :) I see:
GT.APP.BASE::
...a couple of places. Your error sounds like a package issue.
My guess is that you are defining my-app in a different package (which is why ACL on macroexpand is loudly announcing the different package of certain symbols from gt.app.base). I see status and opcode are not so qualified, meaning ACL thinks you are using symbols from the package of my-app. That would not be the case if you simply export status and opcode from gt.app.base, as well as any other symbols you think will be part of the interface. Alternatively, you could qaulify status and opcode with gt.app.base::.
hth, kenny