ADN Open CIS
Сообщество программистов Autodesk в СНГ

25/06/2014

Итерация системных переменных AutoCAD через .NET, часть 1

Просматривая документацию по .NET API AutoCAD (раздел "Что нового"), можно увидеть новый класс SystemVariableEnumerator.

Это очень интересно, поскольку уже есть способ получить системные переменные AutoCAD'a, используя коллекции Autodesk.AutoCAD.Runtime.SystemObjects.Variables. В качестве первого приближения сравнения этих классов был использован код, реализующий пару простых команд-итераторов системных переменных. Эти команды используют одну и ту же функцию, выводящую некоторую информацию о переменной.

Вот код самих команд:

Код - C#: [Выделить]
  1. using Autodesk.AutoCAD.ApplicationServices;
  2. using Autodesk.AutoCAD.ApplicationServices.Core;
  3. using Autodesk.AutoCAD.EditorInput;
  4. using Autodesk.AutoCAD.Geometry;
  5. using Autodesk.AutoCAD.Runtime;
  6. using System;
  7.  
  8. namespace SystemVariableEnumeration
  9. {
  10.   public class Commands
  11.   {
  12.     [CommandMethod("ESV")]
  13.     public static void EnumerateSysVars()
  14.     {
  15.       var doc = Application.DocumentManager.MdiActiveDocument;
  16.       if (doc == null)
  17.         return;
  18.       var ed = doc.Editor;
  19.       // Используем старый механизм итерации через SystemObjects
  20.       foreach (var v in SystemObjects.Variables)
  21.       {
  22.         PrintVariable(ed, v);
  23.       }
  24.     }
  25.  
  26.     [CommandMethod("ESV2")]
  27.     public static void EnumerateSysVars2()
  28.     {
  29.       var doc = Application.DocumentManager.MdiActiveDocument;
  30.       if (doc == null)
  31.         return;
  32.       var ed = doc.Editor;
  33.       // Используем новый механизм
  34.       var sve = new SystemVariableEnumerator();
  35.       while (sve.MoveNext())
  36.       {
  37.         var v = sve.Current;
  38.         if (v != null)
  39.         {
  40.           PrintVariable(ed, v);
  41.         }
  42.       }
  43.     }
  44.  
  45.     // Вспомогательная функция, выводящая информацию о
  46.     // конкретной переменной
  47.     private static void PrintVariable(Editor ed, Variable v)
  48.     {
  49.       var t = GetType(v.PrimaryType);
  50.       ed.WriteMessage(
  51.         "\n{0} ({1}, {2} - {3}): {4}",
  52.         v.Name,
  53.         t == null ? "null" : t.Name,
  54.         v.PrimaryType, v.SecondaryType, v.TypeFlags
  55.       );
  56.  
  57.       if (v.Range != null)
  58.       {
  59.         ed.WriteMessage(
  60.           " [{0}...{1}]",
  61.           v.Range.LowerBound, v.Range.UpperBound
  62.         );
  63.       }
  64.     }
  65.  
  66.     // Определение типа системной переменной на основе
  67.     // внутреннего представления
  68.     private static System.Type GetType(short v)
  69.     {
  70.       Type ret = null;
  71.       switch (v)
  72.       {
  73.         case 1:
  74.         case 5001: // RTREAL real number
  75.           {
  76.             ret = typeof(Double);
  77.             break;
  78.           }
  79.         case 2:
  80.         case 5002: // RTPOINT: 2D point X and Y only
  81.           {
  82.             ret = typeof(Point2d);
  83.             break;
  84.           }
  85.         case 3:
  86.         case 5003: // RTSHORT: short integer
  87.           {
  88.             ret = typeof(Int16);
  89.             break;
  90.           }
  91.         case 4:
  92.         case 5004: // RTANG: angle
  93.           {
  94.             ret = null; // Angle
  95.             break;
  96.           }
  97.         case 5:
  98.         case 5005: // RTSTR: string
  99.           {
  100.             ret = typeof(String);
  101.             break;
  102.           }
  103.         case 6:
  104.         case 5006: // RTENAME: entity name
  105.           {
  106.             ret = null;
  107.             break;
  108.           }
  109.         case 7:
  110.         case 5007: // RTPICKS: pick set
  111.           {
  112.             ret = null;
  113.             break;
  114.           }
  115.         case 8:
  116.         case 5008: // RTORIENT: orientation
  117.           {
  118.             ret = null; // Orientation
  119.             break;
  120.           }
  121.         case 9:
  122.         case 5009: // RT3DPOINT: 3D point - X, Y and Z
  123.           {
  124.             ret = typeof(Point3d);
  125.             break;
  126.           }
  127.         case 10:
  128.         case 5010: // RTLONG: long integer
  129.           {
  130.             ret = typeof(Int32);
  131.             break;
  132.           }
  133.         case 11:
  134.         case 5011: // 2D extents of some kind
  135.           {
  136.             ret = typeof(Point2d);
  137.             break;
  138.           }
  139.       }
  140.       return ret;
  141.     }
  142.   }
  143. }

Поскольку лог выполнения очень большой, приводить его здесь не имеет смысла. В принципе формат выводимых данных должен быть понятен из кода.

Большой кусок предствленного кода на самом деле всего лишь "декодирует" информацию о типе, возвращая объект System.Type, когда он может быть приведен к осмысленному числовому представлению (в зависимости от способа записи это либо число 50хх, либо более короткое значение).

Хотелось бы отметить, что использовать foreach в новом API не представилось возможным: похоже, что метод GetEnumerator() попросту отсутствует, поэтому и пришлось использовать подход с MoveNext().

Новый счетчик пропускает из обработки т.н. "скрытые" переменные (т.е. начинающиеся с символа "*" (звездочка). Эти переменные возвращаются коллекцией SystemObjects.

Коллекция SystemObjects позволяет установить значение системной переменной, что достаточно интересно. В следующей статье мы посмотрим на эту возможность и сравним скорость работы каждой из команд.

Источник: http://through-the-interface.typepad.com/...system-variables-using-net-part-1.html
Перевел: Алексей Кулик

Обсуждение: http://adn-cis.org/forum/index.php?topic=825

Опубликовано 25.06.2014