emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

how to wait for a process to be alive?


From: joakim
Subject: how to wait for a process to be alive?
Date: Fri, 22 Oct 2010 11:19:21 +0200
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/24.0.50 (gnu/linux)

I'm working on a mode to integrate Inkscape and Emacs. So far its only
rudimentary.

I want to start Inkscape from Emacs, with code looking like this:

,----
| 
| (defun inkscape-start ()
|  (interactive)
|  (if (not (dbus-ping :session   "org.inkscape" 100))
|      (let*
|          ((ping-count 0)
|           (inkproc (start-process "inkscape" "*inkscape*" inkscape-path )))
|        (while (not(inkscape-alive))
|          (setq ping-count (+ 1 ping-count))
|          (message "pinging inkscape %d" ping-count)
|          (inkscape-sleep-for)
|          )
|        (message "registering dbus proxies")
|        (setq inkscape-application (inkscape-app-dbus-proxy-create))
|        (setq inkscape-desktop (inkscape-document-dbus-proxy-create 
inkscape-desktop-name))
|        (message "registering inkscape verb proxies")
|        (inkscape-make-verb-list)
|        (message "emacs-inkscape bridge ready for action!")
|        )
|    (message "inkscape already started and responding to ping")))
| 
| (defun inkscape-sleep-for ()
|   (sleep-for 10);;this call doesnt seem to wait at all.
|   (read-string "sleep-for, just press enter");; so do this as a workaround
|   ;;if the sleep-for doesnt work, we get a busy loop and we DOS dbus, and all 
manner of bad things happen
|   ;;TODO therefore ive factored out the sleep-for until a proper resolution 
is found
| )
`----

Inkscape starts asynchronously, so I need to poll it, and after its
properly living, do a number of calls.

The problem is that sleep-for doesnt sleep at all, it just
returns. Therefore I have a read-string workaround in the code above.

I suppose the sleep-for is interupted by some kind of event, but I cant
figure out which, or how to do this properly. The best would be for
Inkscape to send Emacs some kind of event rather than Emacs polling
Inkscape, but I'm not sure how to do that either.

I include all of inkscape.el below for reference.
;; inkscape.el -- experimental emacs/inkscape bridge
;; (c) fsf 2010
;; author:joakim verona
;; license:gpl

(require 'dbus)
(require 'dbus-introspection)

(require 'dbus-proxy) ;;TODO work around deftest problem

;;Experimental integration between inkscape and emacs using dbus.

;;Currently needs bleeding edge versions of a number of components.
;; - trunk version of inkscape with dbus enabled (see inkscape dbus bugs)
;; - trunk version of Eieio(needs a change which hasnt been merged downstream)
;; - trunk version of Jan Moringen dbus-proxy 
;; - emacs 23(i use emacs from trunk, but 23 should be ok)

;;If you accept that all this really is bleeding edge for real, and
;;not something i just say, controling inkscape from emacs is rather
;;fun!

;; the long term goal is to make an emacs that does things quickly
;;  that currently inhibits creative flow with inkscape. In
;;  particular I want to make a framework that supports specialized
;;  workflows, such as producing sketches for blog entries and web comics.
;; so, when inspiration hits you: m-x inkscape-blog-sketch, 
;;rather than fiddling about in menus etc until you loose inspiration.

;, for this we want to:
;; - make the xwidget emacs branch usable, so inkscape can be embedded in emacs
;; - make inkscape support xembed, so it can be embedded in emacs
;; - make an inkscape mode that shows just the canvas
;; - make an emacs inkscape control mode that implements a proper emacs ui on 
top of inkscape
;; - somehow implement the emacs buffer model with inkscape
;; - implement a form of OLE:
;;  - display svg images inline muse-mode org org mode for example(this is 
already mostly possible)
;;  - edit the svg inside inkscape when desired

;; very important is to support text editing in emacs. nodes in an outline-mode
;; document should preferably be bound to nodes in the inkscape document.


;;check alive
;;(dbus-ping :session   "org.inkscape" 100)

;;(dbus-introspect-xml :session   "org.inkscape" "/")

;;(dbus-introspect-get-all-nodes :session   "org.inkscape" "/")

;;(dbus-introspect-get-interface :session   "org.inkscape" 
"/org/inkscape/application" "org.inkscape.application")
;;(dbus-introspect-get-method-names :session   "org.inkscape" 
"/org/inkscape/application" "org.inkscape.application")
;;(dbus-introspect-get-method-names  :session "org.inkscape"  
"/org/inkscape/desktop_24" "org.inkscape.document")
;; (dbus-introspect-get-method  :session "org.inkscape"  
"/org/inkscape/desktop_24" "org.inkscape.document" "rectangle")
(defcustom inkscape-path
  "/home/joakim/build_myprojs/inkscape/inkscape/src/inkscape"
  "path to dbus-enabled inkscape")

(defvar inkscape-desktop-name "desktop_0"
  "this is currently hardcoded, since the inkscape dbus api isnt feature 
complete yet")

(defvar inkscape-desktop nil)
(defvar inkscape-application nil)

(defun inkscape-alive ()
  (dbus-ping :session   "org.inkscape" 100))



(defun inkscape-start ()
 (interactive)
 (if (not (dbus-ping :session   "org.inkscape" 100))
     (let*
         ((ping-count 0)
          (inkproc (start-process "inkscape" "*inkscape*" inkscape-path )))
       (while (not(inkscape-alive))
         (setq ping-count (+ 1 ping-count))
         (message "pinging inkscape %d" ping-count)
         (inkscape-sleep-for)
         )
       (message "registering dbus proxies")
       (setq inkscape-application (inkscape-app-dbus-proxy-create))
       (setq inkscape-desktop (inkscape-document-dbus-proxy-create 
inkscape-desktop-name))
       (message "registering inkscape verb proxies")
       (inkscape-make-verb-list)
       (message "emacs-inkscape bridge ready for action!")
       )
   (message "inkscape already started and responding to ping")))

(defun inkscape-sleep-for ()
  (sleep-for 10);;this call doesnt seem to wait at all.
  (read-string "sleep-for, just press enter");; so do this as a workaround
  ;;if the sleep-for doesnt work, we get a busy loop and we DOS dbus, and all 
manner of bad things happen
  ;;TODO therefore ive factored out the sleep-for until a proper resolution is 
found
)

;; call-verb support
;; inkscape doesnt export all functionality through proper dbus interfaces atm.
;; there is an older "verb" interface, and a dbus bridge.
;; here is some code that tries to aproximate the dbus-proxy api for the verb 
api

(defun inkscape-make-verb-list ()
  (start-process "inkscape-verb-list" "*inkscape-verb-list*" inkscape-path 
"--verb-list")
  (with-current-buffer  "*inkscape-verb-list*"
    (goto-char (point-min))
    (while (re-search-forward  "^\\([^:]+\\):\\(.*\\)$" nil t)
      (message "[%s][%s]" (match-string 1) (match-string 2))
      (inkscape-make-verb-method (match-string 1)(match-string 2)))))

(defun inkscape-make-verb-method (name doc)
  (eval `(defmethod ,(intern (inkscape-transform-method-name "inkverb" name))
           ((this ,(object-class inkscape-desktop)));;inkscape-desktop must be 
initialized
     ,doc
     (inkdoc-call-verb this ,name))))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;creating the dbus proxies, using Jan Moringen fantastic
;;dbus-proxy library. The way emacs dbus integration was meant to be


(defun inkscape-transform-method-name (prefix name)
  "Transform NAME. prepend PREFIX.
 PREFIX can be inkapp- or inkdoc- for
 example. un-camelcase. switch underscore to dash."
  (concat prefix "-" (replace-regexp-in-string "_" "-" 
(dbus-proxy-transform-camel-case name))))




(defun inkscape-app-dbus-proxy-create ()
  "create dbus-proxy to talk to inkscape app"
  (let* ((dbus-proxy-transform-method-name-function (lambda (name) 
(inkscape-transform-method-name "inkapp" name)))
         (obj (dbus-proxy-make-remote-proxy
                    :session "org.inkscape"
                    "/org/inkscape/application" t))
         )
obj   )
)


(defun inkscape-document-dbus-proxy-create (desktop)
  "create dbus-proxy to talk to inkscape desktop"
  (let* ((dbus-proxy-transform-method-name-function (lambda (name) 
(inkscape-transform-method-name "inkdoc" name)))
         (obj (dbus-proxy-make-remote-proxy
                    :session "org.inkscape"
                    (concat "/org/inkscape/" desktop) t))
         )
obj   )
)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;test code
(defun inkscape-dbus-proxy-test ()
  (inkscape-app-dbus-proxy-create)
  (let*
      ((doc (inkscape-document-dbus-proxy-create "desktop_0")))
    (inkdoc-rectangle doc 100 100 100 100)))

;;get all defined inkscape methods
;;(remove-if-not (lambda (x)(string-match "^ink.*-" (symbol-name x)) ) 
(eieio-all-generic-functions))



(defun  inkscape-test ()
  "Opens inkscape, draws a black rectangle. a dbus compatible
Inkscape needs to be running 1st. this test doesnt use the dbus-proxy."
  (let*
    ((desktop "/org/inkscape/desktop_0")
     (rect (dbus-call-method
               :session "org.inkscape" desktop
               "org.inkscape.document" "rectangle" :int32 100 :int32  100 
:int32  100 :int32  100))
           )))

(provide 'inkscape)

-- 
Joakim Verona

reply via email to

[Prev in Thread] Current Thread [Next in Thread]