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

09/04/2014

AutoCAD 2015: вызов команд

Как указывается в предыдущем сообщении, фиберы в AutoCAD 2015 неактивны (соответствующий код остался, в первую очередь для средств тестирования, но его не следует включать для обычного использования продукта).

Фиберы – это технология, которую Microsoft представила очень давно для упрощения перевода однодокументных (и обычно однозадачных) приложений в многодокументный мир МДИ. По крайней мере это мои воспоминания и понимание ситуации. Они были в основном механизмом, посредством которого приложения, такие как AutoCAD, могли управлять состоянием документа, управляя соответствующими данными в зависимости от активного документа. Я слышал, что фиберы еще называют "управляемые вручную задачи", хотя это, вероятно, будет упрощение реальной ситуации.

Так что это означает для разработчиков приложений для AutoCAD, и почему это важно?

Кроме того, что это делает отладку более предсказуемой - Visual Studio не позволял отлаживать приложения, использующие фиберы в нескольких последних релизах - эта работа принесла значительные преимущества для разработчиков.

То, как я понимаю - а очень вероятно, что я понимаю либо неполно, либо ошибочно, так как я не потратил значительное количество времени, рассматривая внутренности этого механизма – выполнение команд AutoCAD  зависит от состояния, связанного с текущим документом. Уход от фиберов означает, что контекст выполнения AutoCAD команды становится совсем другим, но это также приводит к возможностям, которых не было раньше, что делает их первоклассным средством, полностью поддерживает способы использования огромного количества уже существующего кода внутри AutoCAD. По существу это означает, что разработчики AutoCAD больше не должны чувствовать себя плохо (если они когда-либо так себя чувствовали ;-) при вызове команды из своего кода. Сейчас это абсолютно легально, так же как и вызов низкоуровнего API.

До AutoCAD 2015, вы, как правило, запускали команды AutoCAD при помощи запуска имени команды и параметров команды во входной поток команд AutoCAD. Начиная с AutoCAD 2015 года, есть два подхода для вызова команд: подпрограмма и сопрограммы. Подпрограммный подход означает, что вы хотите выполнить команду в полном объеме: вы точно знаете как команда должна выполнится и не может остаться незаконченной. Сопрограммный подход более свободный: у вас нет всех аргументов, которые нужны для команды - и вы не знаете заранее какие могут понадобится - так вы действительно вызываете часть команды.

Без фиберов, которые выступали в качестве каркаса для обработки команд, эти два стиля приходится разделять.

В ObjectARX, к примеру, вы больше не найдете команды acedCommand () или acedCmd (), вы должны использовать либо acedCommandS() / acedCmdS(), либо acedCommandC() / acedCmdC(), в зависимости от того, какой стиль предпочитаете.

С acedCommandS() / acedCmdS() просто: они работают во многом так же, как и привычные acedCommand() / acedCmd(), но только с полными комплектами команда / аргументы. acedCommandC() / acedCmdC() являются более сложными: необходимо предоставить функцию обратного вызова, которая будет вызываться для ввода аргументов дальнейшего процесса (это форма продолженного выполнения, что очень часто используется, когда речь идет о вызовах асинхронных методов). Разработчики ObjectARX должны взглянуть в руководство разработчика ObjectARX, а также файл acedCmdNF.h (NF-видимому означает не-фиберы в данном контексте) для получения дополнительной информации.

Так что разработчикам, использующим ObjectARX, придется поработать если они используют вызов команд в AutoCAD 2015. А что разработчикам использующим другие API?

В AutoLISP всё намного проще: Autodesk полностью контролирует “виртуальную машину” в которой выполняется код LISP внутри AutoCAD, так что мы сами можем выбрать какую из двух функций из ObjectARX вызывать, в зависимости от сценария и без необходимости изменять код вызова команды в LISP. Тем не менее, команда ADN подсказывает мне, что они видели сценарии, в которых разработчику необходимо указать стиль подпрограммы, после чего они смогли вызвать (commands ...).

В VBA – который обновлен до версии 7.1 и доступен как отдельно загружаемый – не думаю что что-то придется менять: по-прежнему есть метод AcadDocument.SendCommand(), который позволяет работать с частью команды (Я обновлю это сообщение если узнаю, что имеются какие-то изменения).

В .NET также просто по-своему: вызовы подпрограмм просты - они  работают синхронно через Editor.Command () - и потому, что AutoCAD 2015 теперь использует .NET 4.5 - который обеспечивает в C # механизм  async/await для вызова асинхронных методов - мы смогли реализовать этот механизм для вызова сопрограмм. Они теперь используют возможности компилятора для автоматической генерацию обратного вызова с помощью ключевого слова await для асинхронной работы – например, await Editor.CommandAsync (...). Вы должны будете помечать любой вызов метода команду, используя CommandAsync () модификатором async, как если бы вы использовали другие await методы.

Разница между C# и C++ та же что и вообще в асинхронном кодировании: изменения были сделаны на уровне языка программирования для облегчения работы с асинхронными операциями и со временем возможны аналогичные изменения и в C++

Имеем в виду, что .NET 4.5 требуется для использования API в AutoCAD 2015 - вы должны будете использовать Visual Studio 2012 или 2013:. VS2010 не могут создавать приложения .NET 4.5.. (Разработчикам использующим ObjectARX придется использовать набор инструментов от VS2012, чтобы  компилировать свои модули C++, так как именно этот компилятор использовался для создания AutoCAD 2015). Я лично сейчас использую VS2013 в качестве основного IDE, но использую набор инструментов VS2012 при построении модулей ObjectARX.

Если вы продолжаете использовать VS2010, вы *должны* использовать в ваших .NET приложениях сборки для AutoCAD 2013 и 2014 (до того момента, пока вы не используете новые или измененные API) и можете выполнять свой код в AutoCAD 2015, но необходимо тщательно все перепроверить.

Обновление:

Чтобы почувствовать разницу между Command() и CommandAsync() при использовании из C#, взгляните на две команды, одна из которых вызывает команду _INSERT синхронно с полным перечнем всех параметров, а вторая вызывает асинхронно, спрашивает у пользователя точку вставки (более общий сценарий,  с использованием  jig для блока, когда показывается графика блока в момент вставки намного более сложная процедура, чем просто вызов _INSERT).

Код - C#: [Выделить]
  1. using Autodesk.AutoCAD.ApplicationServices;
  2. using Autodesk.AutoCAD.EditorInput;
  3. using Autodesk.AutoCAD.Runtime;
  4.  
  5. namespace CommandCalling
  6. {
  7.   public class Commands
  8.   {
  9.     [CommandMethod("IBS")]
  10.     public void InsertBlockSync()
  11.     {
  12.       var doc =
  13.         Application.DocumentManager.MdiActiveDocument;
  14.       var ed = doc.Editor;
  15.  
  16.       // Точка вставки задана явно как 10,10
  17.  
  18.       ed.Command("_.INSERT", "TEST", "10,10", 1, 1, 0);
  19.  
  20.       ed.WriteMessage("\nМы вставили наш блок.");
  21.     }
  22.  
  23.     [CommandMethod("IBA")]
  24.     async public void InsertBlockAsync()
  25.     {
  26.       var doc =
  27.         Application.DocumentManager.MdiActiveDocument;
  28.       var ed = doc.Editor;
  29.  
  30.       // Позволим пользователю указать точку вставки
  31.  
  32.       await ed.CommandAsync(
  33.         "_.INSERT", "TEST", Editor.PauseToken, 1, 1, 0
  34.       );
  35.  
  36.       ed.WriteMessage("\nМы вставили наш блок.");
  37.     }
  38.   }
  39. }

 

Источник: http://through-the-interface.typepad.com/through_the_interface/2014/03/autocad-2015-calling-commands.html

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

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