Aller au contenu

Un timer pour LISP


(gile)

Messages recommandés

Suite à ce sujet, j'ai essayer d'implémenter un 'Timer' utilisable de façon polyvalente en LISP.

 

Il s'agit de deux fonctions LISP (AutoCAD 2011 à 2013):

  • gc-TimerOn lance un Timer qui exécutera la fonction LISP spécifiée à intervalles réguliers en fonction du temps spécifié.
    Requiert deux arguments : le nom de la fonction* sous forme de chaîne et le nombre de secondes de l'intervalle auquel exécuter la fonction.
  • gc-TimerOff arrête le Timer.

* la fonction ne doit avoir aucun argument et être soit préfixée avec 'c:' ; soit être enregistrée avec vl-acad-defun.

 

Exemple d'utilisation :

(defun foo ()
 (alert "Une fois !")
 (defun foo ()
   (alert "Deux fois !")
   (defun foo ()
     (alert "Trois fois !\nMaintenant, ça suffit !")
     (gc-TimerOff)
     (princ)
   )
   (princ)
 )
 (princ)
)
(vl-acad-defun 'foo)

(gc-timerOn "foo" 5)

 

Le code (C#)

// (C) Copyright 2012 by Gilles Chanteau 
//
using System;
using System.Windows.Forms;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Runtime;
using AcAp = Autodesk.AutoCAD.ApplicationServices.Application;

[assembly: CommandClass(typeof(Gile.LispTimer.LispFunctions))]

namespace Gile.LispTimer
{
   public class LispFunctions
   {
       private Timer _timer;
       private string _fun;
       private int _interval;
       private Document _doc;

       public LispFunctions()
       {
           _interval = -1;
           _doc = AcAp.DocumentManager.MdiActiveDocument;
           _doc.CloseWillStart += OnCloseWillStart;
           _doc.CloseAborted += OnCloseAborted;
       }

       private void StartTimer()
       {
           if (_timer == null && _interval > 0)
           {
               _timer = new Timer();
               _timer.Interval = _interval;
               _timer.Enabled = true;
               _timer.Tick += OnTick;
               _timer.Start();
           }
       }

       private void CloseTimer()
       {
           if (_timer != null)
           {
               _timer.Stop();
               _timer.Dispose();
               _timer = null;
           }
       }

       void OnTick(object sender, EventArgs e)
       {
           try
           {
               using (_doc.LockDocument())
               {
                   AcAp.Invoke(new ResultBuffer(new TypedValue((int)LispDataType.Text, _fun)));
               }
           }
           catch (System.Exception ex)
           {
               AcAp.ShowAlertDialog(ex.Message == "eInvalidInput" ?
                   string.Format("Fonction LISP incorrecte: '{0}'", _fun) :
                   ex.Message);
               CloseTimer();
           }
       }

       void OnCloseWillStart(object sender, EventArgs e)
       {
           CloseTimer();
       }

       void OnCloseAborted(object sender, EventArgs e)
       {
           StartTimer();
       }

       [LispFunction("gc-TimerOn")]
       public TypedValue TimerOn(ResultBuffer resbuf)
       {
           try
           {
               if (resbuf == null)
                   throw new TooFewArgsException();

               TypedValue[] args = resbuf.AsArray();
               if (args.Length < 2)
                   throw new TooFewArgsException();
               if (args.Length > 2)
                   throw new TooManyArgsException();

               if (args[0].TypeCode != (int)LispDataType.Text)
                   throw new ArgumentTypeException("stringp", args[0]);
               _fun = (string)args[0].Value;

               if (!args[1].TryConvertToInt(ref _interval))
                   throw new ArgumentTypeException("numberp", args[1]);
               _interval *= 1000;

               CloseTimer();
               StartTimer();
               return new TypedValue((int)LispDataType.Nil);
           }
           catch (System.Exception ex)
           {
               AcAp.ShowAlertDialog(ex.Message);
               throw;
           }
       }

       [LispFunction("gc-TimerOff")]
       public TypedValue TimerOff(ResultBuffer resbuf)
       {
           try
           {
               if (resbuf != null)
                   throw new TooManyArgsException();
               CloseTimer();
               return new TypedValue((int)LispDataType.Nil);
           }
           catch (System.Exception ex)
           {
               AcAp.ShowAlertDialog(ex.Message);
               throw;
           }
       }
   }

   static class LispFunctionExtensions
   {
       public static bool TryConvertToInt(this TypedValue tv, ref int i)
       {
           if (tv.TypeCode == (int)LispDataType.Int16 ||
               tv.TypeCode == (int)LispDataType.Int32)
           {
               i = Convert.ToInt32(tv.Value);
               return true;
           }
           else
           {
               return false;
           }
       }
   }

   class LispException : System.Exception
   {
       public LispException(string msg) : base(msg) { }
   }

   class TooFewArgsException : LispException
   {
       public TooFewArgsException() : base("nombre d'arguments insuffisant") { }
   }

   class TooManyArgsException : LispException
   {
       public TooManyArgsException() : base("nombre d'arguments trop important") { }
   }

   class ArgumentTypeException : LispException
   {
       public ArgumentTypeException(string msg, TypedValue tv)
           : base(string.Format(
           "type d'argument incorrect: {0}: {1}",
           msg, tv.TypeCode == (int)LispDataType.Nil ? "nil" : tv.Value))
       { }
   }
}

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

Lien vers le commentaire
Partager sur d’autres sites

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é