25/06/2014
Итерация системных переменных AutoCAD через .NET, часть 2
В предыдущей части был предоставлен код, показывающий реализацию двух доступных механизмов итерации по системным переменным AutoCAD: SystemObects.Variables и новый класс SystemVariableEnumerator.Сегодня мы посмотрим внимательнее на оба эти механизма, кратко сопоставив их возможности и результаты работы. За основу взят код из предыдущей части статьи. Код упрощен, удалены "проходы" по БД чертежа - все для улучшения сопоставимости результатов.
Ниже представлен код C# с обновленными вариантами команд ESV и ESV2, которые создают соответствующие txt-файлы в каталоге c:\temp. Это получается быстрее, чем вывод в командную строку Windows. Кроме того, игнорируется информация Primary/SecondaryType - все только ради того, чтобы получить сопоставимые результаты.
Код - C#: [Выделить]
После запуска кода мы увидим, что команда ESV (использующая SystemObject.Variables) отработала быстрее, но нашла только 274 (при установленном SP1 для AutoCAD 2015 будет найдено 275 - включая CURSORBADGE) системные переменные. В то же время ESV2 обнаружит 912 (соответственно при установленном SP1 - 913) за сопоставимое время. Так что вопрос производительности можно сбросить со счетов.- using Autodesk.AutoCAD.ApplicationServices;
- using Autodesk.AutoCAD.ApplicationServices.Core;
- using Autodesk.AutoCAD.Geometry;
- using Autodesk.AutoCAD.Runtime;
- using System;
- using System.Diagnostics;
- using System.IO;
- using System.Text;
- namespace SystemVariableEnumeration
- {
- public class Commands
- {
- public void MeasureTime(
- Document doc, Func func, string name
- )
- {
- // Get the name of the running command(s)
- // (might also have queried the CommandMethod attribute
- // via reflection, but that would be a lot more work)
- var cmd = (string)Application.GetSystemVariable("CMDNAMES");
- // Start a Stopwatch to time the execution
- var sw = new Stopwatch();
- sw.Start();
- // Run the function, getting back the count of the results
- var cnt = func();
- // Stop the Stopwatch and print the results to the command-line
- sw.Stop();
- doc.Editor.WriteMessage(
- "\n{0} found {1} {2} in {3}.", cmd, cnt, name, sw.Elapsed
- );
- }
- [CommandMethod("ESV")]
- public void EnumerateSysVars()
- {
- var doc = Application.DocumentManager.MdiActiveDocument;
- if (doc == null)
- return;
- MeasureTime(
- doc,
- () =>
- {
- int numVars = 0;
- using (var sw = new StreamWriter("c:\\temp\\esv.txt"))
- {
- // Use the existing SystemObjects iteration mechanism
- foreach (var v in SystemObjects.Variables)
- {
- sw.WriteLine(GetVariableInfo(v));
- numVars++;
- }
- }
- return numVars;
- },
- "variables"
- );
- }
- [CommandMethod("ESV2")]
- public void EnumerateSysVars2()
- {
- var doc = Application.DocumentManager.MdiActiveDocument;
- if (doc == null)
- return;
- MeasureTime(
- doc,
- () =>
- {
- int numVars = 0;
- using (var sw = new StreamWriter("c:\\temp\\esv2.txt"))
- {
- // Use the new system variable enumerator
- var sve = new SystemVariableEnumerator();
- while (sve.MoveNext())
- {
- var v = sve.Current;
- if (v != null)
- {
- sw.WriteLine(GetVariableInfo(v));
- numVars++;
- }
- }
- }
- return numVars;
- },
- "variables"
- );
- }
- // Helper function to get the information for a particular
- // variable
- private static string GetVariableInfo(Variable v)
- {
- var t = GetType(v.PrimaryType);
- var sb = new StringBuilder();
- sb.AppendFormat(
- "{0} ({1}): {2}", // Skip the additional type info
- v.Name,
- t == null ? "null" : t.Name,
- /*v.PrimaryType, v.SecondaryType,*/ v.TypeFlags
- );
- if (v.Range != null)
- {
- sb.AppendFormat(
- " [{0}...{1}]",
- v.Range.LowerBound, v.Range.UpperBound
- );
- }
- return sb.ToString();
- }
- // Determine the type of a system variable based on
- // the internal representation
- 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;
- }
- }
- }
Весьма интересно (и, можно сказать, даже обнадеживает), что новый механизм находит настолько больше системных переменных. С одной стороны, старый механизм (SystemObjects.Variables) позволяет менять значение системной переменной через возвращаемый объект:
Код - C#: [Выделить]
Но, с другой стороны, это работает только для подмножества системных переменных (и пока автор еще не выяснил, какие именно... Известно, что новый счетчик пропускает анонимные системные переменные, и все равно находит втрое больше переменных).
- [CommandMethod("TOGCB")]
- public void ToggleCursorBadge()
- {
- var doc = Application.DocumentManager.MdiActiveDocument;
- if (doc == null)
- return;
- var ed = doc.Editor;
- const string curbadge = "CURSORBADGE";
- // Get our CURSORBADGE system variable object
- var cb = SystemObjects.Variables[curbadge];
- // Report its initial value
- ed.WriteMessage(
- "\nInitial value of {0} is {1}.", curbadge, cb.Value
- );
- // Set the new value, toggling between 1 & 2
- // (with too many casts for my liking, but hey)
- cb.Value = (short)((short)cb.Value == 1 ? 2 : 1);
- // And report the new value to make sure it worked
- ed.WriteMessage(
- "\nNew value of {0} is {1}.", curbadge, cb.Value
- );
- }
Если есть желание, можно рассмотреть подробнее результаты работы как команды ESV, так и команды ESV2.
Источник: http://through-the-interface.typepad.com/...-system-variables-using-net-part-2.html
Перевел: Алексей Кулик
Обсуждение: http://adn-cis.org/forum/index.php?topic=826
Опубликовано 25.06.2014