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