Aller au contenu

Messages recommandés

Posté(e)

Salut à toutes et à tous,

J'ai besoin de quelques eclaircissements sur l'utilisation de la fonction *error*, son fonctionnement, son utilité... et je voudrais savoir si c'est la solution pour ce que je vais dire.

Si vous avez déjà jeté un coup d'oeil sur les lisps des express (en l'occurence mstretch.lsp, commande "etirer plusieurs entités"). Ce fichier contient dans sa première partie :

 

 (acet-error-init
(list
 (list   "cmdecho" 0
       "highlight" 0
        "dragmode" (getvar "dragmode")
          "osmode" 0
         "cecolor" "6"
         "celtype" "CONTINUOUS"
        "limcheck" 0
 )
 T
 '(progn
    (acet-temp-segment nil nil nil 1)
    (acet-sysvar-set (list "cmdecho" 0));turn cmdecho off
    (command "_.redraw");do redraw
    (acet-sysvar-restore);re-set cmdecho back
    (princ)
    ;(command "_.redraw")
  )
)
)

 

apparement ce code a un rapport avec la fonction *error*.

Ce que je veux c'est d'exécuter une commande (suppression d'un fichier temporaire) quand l'utilisateur annule la commande en cours de route par la touche echap par exemple, mais je ne veux pas trop changer le fichier lisp original. Une redefinition de la fonction *error* est-elle la solution pour mon besoin et comment opérérer?. merci pour vos explications

Posté(e)

Salut,

 

Comme tu l'as bien noté "Echap" est traité comme une erreur.

AutoLISP fournit la fonction *error* qui peut être redéfinie localement pour répondre aux nécessités de certains programmes, notamment pour restaurer l'environnement initial (variables système, objets temporaires, groupes "undo" ...) au cas où l'évaluation de la routine serait interrompu prématurément.

 

Ensuite, il y a en gros deux écoles (voir ici) :

1 - définir une fonction externe et remplacer localement *error* par cette fonction (dans ce cas on peut essayer de faire la fonction la plus polyvalente possible de manière à pouvoir l'utiliser dans la plupart des cas).

2 - redéfinir *error* localement.

 

Exemple pour la première solution

 

(defun MonErreur (msg)
 (if (/= msg "Fonction annulée")
   (princ (strcat "Erreur: " msg))
 )
 (if tmp_file
   (vl-file-delete tmp_file)
 )
 (setvar "OSMODE" old_osmode)
 (command "_.undo" "_end")
 (setq	*error*	m:err			; restauration de *error*
m:err nil
 )
 (princ)
)

(defun c:MaCommande (/ old_osmode tmp_file)
 ;; initialisation
 (setq	old_osmode (getvar "OSMODE")
m:err	   *error*		; sauvegarde de *error*
*error*	   MonErreur		; redéfinition
 )
 (command "_.undo" "_begin")
 (setvar "OSMODE" 0)

 ;; corps du programme
 (setq tmp_file (vl-filename-mktemp))
 ;; ...

 ;; restauration
 (vl-file-delete tmp_file)
 (setvar "OSMODE" old_osmode)
 (command "_.undo" "_end")
 (setq	*error*	m:err			; restauration de *error*
m:err nil
 )
 (princ)
)

 

Exemple pour la deuxième solution

 

(defun c:MaCommande (/ *error* old_osmode tmp_file) ; déclaration de *error* en local

 ;; redéfinition de *error*
 (defun *error* (msg)
   (if	(/= msg "Fonction annulée")
     (princ (strcat "Erreur: " msg))
   )
   (if	tmp_file
     (vl-file-delete tmp_file)
   )
   (setvar "OSMODE" old_osmode)
   (command "_.undo" "_end")
   (princ)
 )

 ;; initialisation
 (setq old_osmode (getvar "OSMODE"))
 (command "_.undo" "_begin")
 (setvar "OSMODE" 0)

 ;; corps du programme
 (setq tmp_file (vl-filename-mktemp))
 ;; ...

 ;; restauration
 (vl-file-delete tmp_file)
 (setvar "OSMODE" old_osmode)
 (command "_.undo" "_end")
 (princ)
)

 

Tu peux aussi voir du côté de la fonction vl-catch-all-apply qui permet de continuer l'évaluation après une erreur.

 

(defun c:MaCommande (/ old_osmode tmp_file)

 ;; initialisation
 (setq old_osmode (getvar "OSMODE"))
 (command "_.undo" "_begin")
 (setvar "OSMODE" 0)

 (vl-catch-all-apply
   '(lambda ()
      ;; corps du programme

      (setq tmp_file (vl-filename-mktemp))
      ;; ...
    )
 )
 ;; restauration
 (vl-file-delete tmp_file)
 (setvar "OSMODE" old_osmode)
 (command "_.undo" "_end")
 (princ)
)

 

PS : Attention, les Express Tools ne sont pas forcément un bon exemple.

Ils sont organisés autour d'une grosse bibliothèque de routines interdépendantes les unes des autres. Par exemple la fonction acet-error-init que tu montres ici appelle les routines : acet-temp-segment, acet-sysvar-set et acet-sysvar-restore.

On a pu voir, pour certaines commandes des Express (je ne me souviens pas des quelles) des variables systèmes ou la fonction *error* pas restaurées.

Gilles Chanteau - gileCAD - GitHub
Développements sur mesure pour AutoCAD

Posté(e)

Merci beaucoup beaucoup gile pour ces explications détaillées. Le fonctionnement est bien clair maintenant. je m'en servirais dans le futur pour mes propres fonctions.

Pour le fichier mstretch.lsp, si je saisis bien, en redéfinissant la fonction *error* localement (sans toucher aux fichiers acet-temp-segment, acet-sysvar-set et acet-sysvar-restore) je risquerais d'altérer le bon fonctionnement du lisp, n'est-ce pas? Et en gros il est conseillé de ne pas y toucher? C'est bien cela gile. merci merci

 

Créer un compte ou se connecter pour commenter

Vous devez être membre afin de pouvoir déposer un commentaire

Créer un compte

Créez un compte sur notre communauté. C’est facile !

Créer un nouveau compte

Se connecter

Vous avez déjà un compte ? Connectez-vous ici.

Connectez-vous maintenant
×
×
  • Créer...

Information importante

Nous avons placé des cookies sur votre appareil pour aider à améliorer ce site. Vous pouvez choisir d’ajuster vos paramètres de cookie, sinon nous supposerons que vous êtes d’accord pour continuer. Politique de confidentialité