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

30/10/2015

Особенности, характерные для C++ - Часть 2

Типы объектов и приведение типов

В отличие от Python и JavaScript, C ++ является строго типизированным языком, а переменные должны быть объявлены как определенный тип и их назначение должно совпадать с типом. Как описано выше, при объявлении новой переменной, вы должны всегда использовать шаблон Ptr чтобы создать смарт-указатель определенного типа. Чтобы проверить тип объекта, который ссылается на переменную, можно использовать свойство OBJECTTYPE, который поддерживается всеми объектами Fusion. Эта функция возвращает строку, которая является фактическим типом объекта, не обязательно типом, которым объявлена переменная. Например, код ниже получает сущность, которая в настоящее время выбрана (которая может быть чем угодно, так что переменная объявлена как Base), и делает проверку, чтобы убедиться что это эскиз строка.

Код - C++: [Выделить]
  1. Ptr<Selection> selection = ui->activeSelections()->item(0);
  2. Ptr<Base> selectedEnt = selection->entity();
  3.  
  4. if (selectedEnt->objectType() == adsk::fusion::SketchLine::classType())
  5.     ui->messageBox("Selected entity is a sketch line.");
  6. else
  7.     ui->messageBox("Selected entity is NOT a sketch line.");

 

Объект SketchLine является производным от класса SketchCurve и наследуется от класса SketchEntity, который в конечном итоге является производным от класса Base. Если вы хотите знать что тип выбранного объекта является одним из типов, которые являются производными от SketchCurve, вы можете использовать следующее.

Код - C++: [Выделить]
  1. Ptr<Selection> selection = ui->activeSelections()->item(0);
  2. Ptr<Base> selectedEnt = selection->entity();
  3.  
  4. if (Ptr<SketchCurve>(selectedEnt))
  5.     ui->messageBox("Selected entity is a sketch curve.");
  6. else
  7.     ui->messageBox("Selected entity is NOT a sketch curve.");

Код выше использует преимущества одной из особенностей интеллектуальных указателей Fusion в том, что они поддерживают автоматическое преобразование типов. Он использует автоматическое преобразование в предоставляемое шаблоном Ptr чтобы преобразовать selectEnt к SketchCurve и если преобразование окажется успешным, в объявлении оно вернет true. Ниже приведен еще один пример общего случая, где используется приведение, где активный продукт получают в виде базового класса класса Product. Затем оно присваивается переменной, объявленной в качестве проекта (Design). Если активный продукт является проектом, это примет значение true и переменная "des" будет ссылаться на активный проект. Если активный продукт является продуктом CAM или Drawing, то переменная "des" будет null, потому что приведение не удалось.

Код - C++: [Выделить]
  1. Ptr<Product> prod = app->activeProduct();
  2. if (!prod)
  3.     return false;
  4.  
  5. Ptr<Design> des = prod;
  6. if (!des)
  7.     // Продукт не активен.
  8.     return false;

События

Реализация событий в C ++ подобно тому, как это сделано в JavaScript и Python. Хотя концепция является одинаковой для всех языков, каждый из них имеет свои собственные уникальные требования. Ниже приведен список шагов для реализации событий в C ++ и пример кода, который иллюстрирует эти действия.

  1. Получить ссылку на объект, который поддерживает событие, (строка 13).
  2. Получить объект события, (строка 18).
  3. Вызовите метод Add объекта события, передавая класс обработчика событий (строка 19).Обратите внимание, что передаваемая переменная объявляется как часть определения класса обработчика событий в строке 56.
  4. Создание класса обработчика событий, который является производным от соответствующего класса Fusion, (строка 21).
  5. Реализовать функцию оповещения с соответствующей подписью, (строка 24).
  6. Добавить код в функцию уведомления которая будет запущена при обращении события, которое также может включать в себя подключение к другим событиям (линии 25-52).

Код - C++: [Выделить]
  1. extern "C" XI_EXPORT bool run(const char* context)
  2. {
  3.      _app = Application::get();
  4.      if (!_app)
  5.          return false;
  6.  
  7.      _ui = _app->userInterface();
  8.      if (!_ui)
  9.          return false;
  10.  
  11. // Создать определение кнопки команды.
  12.     Ptr<CommandDefinitions> cmdDefs = _ui->commandDefinitions();
  13.     sampleCmdDef = cmdDefs->addButtonDefinition("sampleCmdID", "Sample",
  14.                                                 "Sample tooltip",
  15.                                                 "./Resources/Sample");
  16.  
  17. // Подключение к созданному командой событию.
  18.     Ptr<CommandCreatedEvent> commandCreatedEvent = sampleCmdDef->commandCreated();
  19.     commandCreatedEvent->add(&_cmdCreated);
  20. }
  21.  
  22.  
  23. // Обработчик события CommandCreated.
  24. class CommandCreatedEventHandler : public adsk::core::CommandCreatedEventHandler
  25. {
  26. public:
  27.     void notify(const Ptr<CommandCreatedEventArgs>& eventArgs) override
  28.     {
  29.         if (eventArgs)
  30.         {
  31.             Ptr<Command> cmd = eventArgs->command();
  32.             if (cmd)
  33.             {
  34. // Определить входы.
  35.                 Ptr<CommandInputs> inputs = cmd->commandInputs();
  36.  
  37. // Добавить вход, чтобы иметь выбранным эскиз кривой или грани.
  38.                 Ptr<SelectionCommandInput> curveInput;
  39.                 curveInput = inputs->addSelectionInput("curveInput", "Curve",
  40.                                                        "Select the sketch or edge curve.");
  41.                 curveInput->addSelectionFilter("SketchCurves");
  42.                 curveInput->addSelectionFilter("Edges");
  43.  
  44. // Добавить вход, чтобы получить вход true/false.
  45.                 Ptr<BoolValueCommandInput> trueFalseInput;
  46.                 trueFalseInput = inputs->addBoolValueInput("trueFalseInput", "Yes or No",
  47.                                                       true, "", true);
  48.  
  49. // Подключение к выполняемому командой событию.
  50.                 Ptr<CommandEvent> onExec = cmd->execute();
  51.                 bool isOk = onExec->add(&onExecuteHandler_);
  52.             }
  53.         }
  54.     }
  55.  
  56. private:
  57.     OnExecuteEventHander onExecuteHandler_;
  58. } _cmdCreated;

Автор перевода: Дмитрий Емельянов

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

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