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

27/12/2016

Использование атрибута JournalingAttribute

Андрей Бушман задал интересный вопрос по использованию атрибута JournalingAttribute и свойству JournalMode. Какой-либо информации по их назначению не нашлось, добираться до истины пришлось самому.

Вот что мне удалось выяснить, после небольшого анализа.

С помощью Revit API можно писать данные в файл журнала. Делается это с помощью свойства CommandData.JournalData, которое как раз и является словарем Dictionary<string, string>.

Если посмотреть в раздел справки этого свойства, в описании увидим вот такой текст:


 

The data map is a string to string map that can be used to store data in the Revit journal file at the end of execution of the external command. If the command is then executed from the journal file during playback this data is then passed to the external command in this Data property so the external command can execute with this passed data in a UI-less mode, hence providing non interactive journal playback for automated testing purposes. For more information on Revit's journaling features contact the Autodesk Developer Network.


 

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

Но в команде могут быть действия, которые требуют участия пользователя. Например, выбор объекта в модели, или выбор действия в диалоге.

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

На возможность получить эти действия, влияет атрибут JournalingAttribute и свойство JournalMode.

Для того, чтобы проверить поведение записи в файл журнала, я создал две одинаковые команды, но с различным значением атрибута JournalingAttribute. В команде два метода, требующие реакции пользователя – выбрать объект и закрыть диалог.

По умолчанию используется значение JournalModel.UsingCommandData.

Код - C#: [Выделить]
  1.     [Transaction(TransactionMode.Manual)]
  2.     [Journaling(JournalingMode.UsingCommandData)]
  3.     public class JournalingModeUsingCommandData : IExternalCommand
  4.     {
  5.         public Result Execute(
  6.           ExternalCommandData commandData,
  7.           ref string message,
  8.           ElementSet elements)
  9.         {
  10.             UIApplication uiapp = commandData.Application;
  11.             UIDocument uidoc = uiapp.ActiveUIDocument;
  12.             Application app = uiapp.Application;
  13.             Document doc = uidoc.Document;
  14.  
  15.             commandData.JournalData.Add("Журнал 1", "Начинаем выбирать элемент");
  16.  
  17.             Reference r = null;
  18.             try
  19.             {
  20.                 r = uidoc.Selection.PickObject(ObjectType.Element, "Выберите элемент");
  21.             }
  22.             catch (OperationCanceledException)
  23.             {
  24.                 commandData.JournalData.Add("Журнал 2", "Выбор отменен");
  25.                 return Result.Cancelled;
  26.             }
  27.  
  28.             TaskDialog.Show("JournalMode", "Вы выбрали объект " + r.ElementId.IntegerValue);
  29.  
  30.             commandData.JournalData.Add("Журнал 3", "Вы выбрали объект " + r.ElementId.IntegerValue);
  31.  
  32.             using (Transaction tx = new Transaction(doc))
  33.             {
  34.                 tx.Start("Change ProjectInfo");
  35.                 doc.ProjectInformation.Author = "Victor Chekalin";
  36.                 commandData.JournalData.Add("Журнал 4", "Изменили автора проекта");
  37.                 tx.Commit();
  38.             }
  39.  
  40.             return Result.Succeeded;
  41.         }
  42.     }

В этом случае, файл журнала получается таким:


Jrn.RibbonEvent "Execute external command:152ee89c-6296-4b44-8579-3f5b5669f5a5:JournalModeTest.JournalingModeUsingCommandData"

 ' 1:< ::28:: Delta VM: Avail -13 -> 134182735 MB, Used +0 -> 664 MB; RAM: Avail 6204 MB, Used +0 -> 768 MB

 ' 1:< GUI Resource Usage GDI: Avail 9233, Used 767, User: Used 850403525016

 'E 27-Dec-2016 11:36:13.985;   1:<

 Jrn.MouseMove    0 ,    579 ,    646

 'E 27-Dec-2016 11:36:13.986;   1:<

 Jrn.LButtonDown    1 ,    579 ,    646

 ' 1:< Candidates (curIdx = 0): 688547 (-51.059711, +19.175648, -2.040027) 

' 1:< TaskDialog "Вы выбрали объект 688547"

'CommonButtons : Close

'DefaultButton : Close

' 2:< ::30:: Delta VM: Avail -22 -> 134182714 MB, Used +21 -> 685 MB; RAM: Avail -2 -> 6203 MB, Used 768 MB

' 2:< GUI Resource Usage GDI: Avail 9227, Used 773, User: Used 850403525022

'  1.246561!!! 2:!!!BIG_GAP API External Command Time

'  3.367165   1:<<API External Command Time

'H 27-Dec-2016 11:36:15.438;   0:<

Jrn.Data "APIStringStringMapJournalData"  _

        , 3, "Журнал 1", "Начинаем выбирать элемент" _

        , "Журнал 3", "Вы выбрали объект 688547", "Журнал 4" _

        , "Изменили автора проекта"

' 0:< ::30:: Delta VM: Avail +12 -> 134182726 MB, Used +2 -> 687 MB; RAM: Avail 6203 MB, Used +1 -> 770 MB

' 0:< GUI Resource Usage GDI: Avail 9219, Used 781, User: Used 850403525022

' 0:< Method PathNameFromControl: the control is neither hosted on Window nor APIDockablePane.

' 0:< Method PathNameFromControl: the control is neither hosted on Window nor APIDockablePane.

 'E 27-Dec-2016 11:36:17.103;   0:<

 Jrn.MouseMove    0 ,     45 ,     99

 'E 27-Dec-2016 11:36:17.103;   0:< 


 

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

Теперь выполним ту же самую команду, но со значением атрибута JournalingMode.NoCommandData:

Код - C#: [Выделить]
  1.     [Transaction(TransactionMode.Manual)]
  2.     [Journaling(JournalingMode.NoCommandData)]
  3.     public class JournalingModeNoCommandDataCommand : IExternalCommand
  4.     {
  5.         public Result Execute(
  6.           ExternalCommandData commandData,
  7.           ref string message,
  8.           ElementSet elements)
  9.         {
  10.             UIApplication uiapp = commandData.Application;
  11.             UIDocument uidoc = uiapp.ActiveUIDocument;
  12.             Application app = uiapp.Application;
  13.             Document doc = uidoc.Document;
  14.  
  15.             commandData.JournalData.Add("Журнал 1", "Начинаем выбирать элемент");
  16.  
  17.             Reference r = null;
  18.             try
  19.             {
  20.                 r = uidoc.Selection.PickObject(ObjectType.Element, "Выберите элемент");
  21.             }
  22.             catch (OperationCanceledException)
  23.             {
  24.                 commandData.JournalData.Add("Журнал 2", "Выбор отменен");
  25.                 return Result.Cancelled;               
  26.             }
  27.  
  28.             TaskDialog.Show("JournalMode", "Вы выбрали объект " + r.ElementId.IntegerValue);
  29.  
  30.             commandData.JournalData.Add("Журнал 3", "Вы выбрали объект " + r.ElementId.IntegerValue);
  31.  
  32.             using (Transaction tx = new Transaction(doc))
  33.             {
  34.                 tx.Start("Change ProjectInfo");
  35.                 doc.ProjectInformation.Author = "Victor Chekalin";
  36.                 commandData.JournalData.Add("Журнал 4", "Изменили автора проекта");
  37.                 tx.Commit();
  38.             }
  39.  
  40.             return Result.Succeeded;
  41.         }
  42.     }

И посмотрим на файл журнала в этом случае:


 Jrn.RibbonEvent "Execute external command:5fe25c77-0532-49e8-a629-5c5606032884:JournalModeTest.JournalingModeNoCommandDataCommand"

 ' 1:< ::32:: Delta VM: Avail +7 -> 134182734 MB, Used -21 -> 667 MB; RAM: Avail -3 -> 6201 MB, Used 770 MB, Peak +2 -> 778 MB

 ' 1:< GUI Resource Usage GDI: Avail 9233, Used 767, User: Used 850403525016

 'E 27-Dec-2016 11:36:19.029;   1:<

 Jrn.MouseMove    0 ,    647 ,    301

 'E 27-Dec-2016 11:36:19.029;   1:<

 Jrn.LButtonDown    1 ,    647 ,    301

 ' 1:< Candidates (curIdx = 0): 577642 (-45.055455, +15.781763, +29.725250) 577643 (-45.055455, +22.343443, +29.725250) 

 'H 27-Dec-2016 11:36:19.030;   1:<

 Jrn.Data "Selection action"  _

         , "REPLACE",  _

          "SEL RESULT: Generic Models : Stahlbalkon : Stahlbalkon"

' 1:< TaskDialog "Вы выбрали объект 577642"

'CommonButtons : Close

'DefaultButton : Close

'H 27-Dec-2016 11:36:20.044;   1:<

Jrn.Data "TaskDialogResult"  _

        , "Вы выбрали объект 577642",  _

         "Close", "IDCLOSE"

'  3.018461   1:<<API External Command Time


 

Как мы видим, данных в файле журнала стало меньше. Исчезла информация, которую мы записывали в словарь с помощью свойства JournalData.

Таким образом, перевод получается примерно следующий:

  • JournalMode.NoCommandData – Содержимое словаря ExternalCommandData.JournalData не записывается в файл журнала. В этому случае, можно точно воспроизвести действия команды, которые требовали участия пользователя, такие как выбор объектов и действия в диалогах.
  • JournalMode.UsingCommandData – Используется словарь IDictionary<String, String> (который представлен в виде свойства ExternalCommandData.JournalData). В этом случае, невозможно воспроизвести действия команды, которые требовали участия пользователя, такие как выбор объектов и действия в диалогах. Это значение атрибута используется по умолчанию.

 По прежнему не ясны значения некоторых предложений. This will hide all Revit journal entries between the external command invocation and the IDictionary<String, String> entry. Выглядит это как В файл журнала ничего не будет записываться, между началом вызова команды и записью в JournalData, но как мы видим выше, все равно что-то туда записывается.

This option allows Revit API calls to write to the journal as needed. Позволяет записывать вызовы методов RevitAPI в файл журнала при необходимости. Но что конкретно имеется ввиду – не очень понятно.

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

Проект для Visual Studio с тестовыми командами можно скачать на Github.

Автор: Виктор Чекалин

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

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