Система компонентов C ++
Система компонентов позволяет реализовать логику вашего приложения с помощью набора строительных блоков - компонентов и назначать эти блоки узлам, предоставляя им дополнительную функциональность. Комбинируя эти маленькие и простые блоки, вы можете создать очень сложную логическую систему.
Логический компонент объединяет узел , класс C++, содержащий логическую реализацию (действия, которые необходимо выполнить), и свойство (property), определяющее набор дополнительных параметров, которые должны быть используемы. Список параметров, а также их типы одинаковы как для компонента, так и для соответствующего свойства.
Компоненты дают вам больше гибкости в реализации вашей логики, позволяя:
- Управляйте тем, какие части кода (реализованные как методы компонентов) должны выполняться, а какие нет.
- Контролировать порядок выполнения этих частей кода.
- Неоднократно используйте части кода, написанные один раз, для любого количества объектов без каких-либо изменений. Если вы хотите изменить свой код, вы изменяете единственный источник (аналогично NodeReference, если мы говорим о контенте).
- Объедините определенные части кода, которые будут выполняться для определенных узлов. Создайте очень сложную систему из множества маленьких и простых блоков (например, вы использовали бы NodeReference для построения большой сложной структуры с использованием множества простых узлов).
Смотрите также#
- API Системы компонентов C++ для получения дополнительных сведений об управлении компонентами через C++ API.
- Пример использования Системы компонентов C++ для получения дополнительных сведений о реализации логики с использованием системы компонентов.
- Пример C ++: source/samples/Api/Logics/ComponentSystem
Логика#
Логика компонентов реализована с помощью набора методов, которые вызываются соответствующими функциями скрипта world :
- init() - создаются и инициализируются все необходимые ресурсы
- updateAsyncThread() — указываются все логические функции, которые вы хотите вызывать в каждом кадре независимо от потока рендеринга. Этот метод не имеет защитных блокировок, поэтому не рекомендуется изменять другие компоненты внутри этого метода, если вы не уверены, что эти компоненты не будут изменены или удалены где-либо еще.
- updateSyncThread() — указываются все параллельные функции логики, которые вы хотите выполнить до update(). Этот метод можно использовать для выполнения некоторых ресурсоемких вычислений, таких как поиск пути, создание процедурных текстур и т.д.
Этот метод следует использовать для вызова только тех методов API, которые относятся к текущему узлу: самому узлу, его материалам и свойствам.
- update() - указываются все логические функции, которые должны вызываться в каждом кадре
- postUpdate() - корректируется поведение в соответствии с обновленными состояниями узлов в том же кадре
- updatePhysics() - выполняется симуляция физики: выполнение непрерывных операций (толкание машину вперед в зависимости от оборотов двигателя, имитация постоянного ветра, выполнение немедленных реакций на столкновение и т. д.).
- swap() — работа с результатами метода updateAsyncThread() все остальные методы (потоки) уже выполнены и ждут. После этой функции происходят только два действия:
- Все объекты, поставленные в очередь на удаление, удаляются.
- Выполняется визуализация Профайлера.
- shutdown() — выполняется очистка при выключении мира.
Рабочий процесс#
Базовый рабочий процесс выглядит следующим образом:
- Унаследуйте новый класс C ++, представляющий ваш компонент, от класса ComponentBase. Шаблон этого класса доступен в заголовке UnigineComponentSystem.h в виде комментария.
- В заголовочном файле определите и объявите список параметров, которые будут использоваться этим компонентом. Все эти параметры со значениями по умолчанию (если они указаны) будут сохранены в специальном файле свойств.
- Реализуйте компонентную логику внутри определенных методов (init(), update(), postUpdate()и т. д.), которые будут вызываться соответствующими функциями основного цикла движка .
- Скомпилируйте проект и запустите его один раз, чтобы сгенерировать свойства (property) для всех компонентов.
- Назначьте созданное свойство узлу, чтобы придать ему желаемую функциональность.
Каждый раз, когда свойство, зарегистрированное в Системе компонентов, назначается узлу, создается экземпляр соответствующего компонента. Этот экземпляр будет удален, когда соответствующее свойство будет заменено другим или удалено из списка узла, или когда узел будет удален.
Логика определенного компонента активна только тогда, когда соответствующий узел и свойство включены. Таким образом, при необходимости вы можете включать / отключать логику каждого конкретного компонента во время выполнения.
Вы можете назначить несколько свойств, соответствующих различным компонентам, одному узлу. Последовательность, в которой выполняется логика компонентов, определяется значением order, указанным для соответствующих методов (если значения order совпадают или не указаны, последовательность определяется в соответствии с иерархией узлов).
Вы также можете создавать компоненты для существующих свойств.
Компоненты могут взаимодействовать с другими компонентами и узлами.
Применение#
В качестве примера вы можете использовать компоненты для реализации логики преследования врагов в вашей игре: независимо от их размера, формы, скорости, все они будут проверять позицию игрока и пытаться найти путь, к которому можно приблизиться. это так быстро, как они могут. Код будет в основном таким же, он просто будет использовать другие параметры (скорость, сетку или звуки, возможно), поэтому вы можете поместить все эти параметры в свойство (чтобы иметь возможность изменять их на в любое время) и код соответствующего класса компонента (например, поместите врагов в мире в init() и преследуйте игрока методом update()).
Затем вы должны просто назначить свойство всем вражеским объектам и настроить параметры (определить сетки, звуки и т. д.). Система компонентов сделает все остальное: выполните ваш код на соответствующих этапах основного цикла движка для всех вражеских объектов, используя их определенные параметры. Если вы решите изменить свой код позже, вы можете сделать это в едином исходном классе компонентов.
Интеграция с инструментом Microprofile позволяет отслеживать общую производительность системы компонентов, а также добавлять информацию о профилировании для ваших компонентов.