Динамические переменные

From Resonite Wiki
Revision as of 02:40, 25 April 2024 by Maksim789456 (talk | contribs) (Created page with "В следующих примерах будет продемонстрировано несколько вариантов использования динамических переменных.")

Обзор

Динамические переменные позволяют вам читать и писать данные по имени в контексте иерархии слотов. Это упрощает управление данными в больших системах; каждый бит данных четко помечен, и вы можете разбивать данные на несколько пространств, чтобы разделять ваши системы.

Ограничения именования

При использовании динамических переменных существуют некоторые ограничения на именование пространств и переменных внутри этих пространств.

Пространства и имена переменных не могут содержать:

  • Любые символы
  • Любую пунктуацию / Пустые строки
  • За исключением точки (.), нижнего подчеркивания (_) и пробела ( ).
Какую концепцию или свойства предоставляют ваши пространства и переменные? Не торопитесь и назовите их как следует!
Эти имена будут использоваться в разных местах или даже другими пользователями. Изменения этих имен потом может оказаться довольно сложной задачей.

Использование

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

Некоторые допустимые имена:

  • Health -- нет определенного пространства, имя Health
  • World/Color -- имя Color, в пространстве World
  • MyCoolSystem/Score -- имя Score, в пространстве MyCoolSystem

Пространства

Динамические переменные могут находиться в слоте содержащий компонент DynamicVariableSpace или в его дочерних слотах.

Таким образом, пространство для переменных находящиеся в корневом слоте мира можно использовать из любого места, но пространство для переменных на вашем аватаре можно использовать из всех слотов, что хранятся в вашем аватаре.

Переменные

Самый простой способ использовать динамические переменные - это использовать компоненты DynamicValueVariable<T> и DynamicReferenceVariable<T>. Они предназначены для значимых (int, float, String, etc.) и ссылочных (Slot, User, etc.) типов, соответственно. Компонент DynamicTypeVariable существует для хранения типов.

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

Поля

Если вы хотите использовать существующее поле или ссылку на него в качестве содержимого динамической переменной, вы можете использовать компоненты DynamicField<T> или DynamicReference<T>. Вместо того чтобы сохранять что-либо напрямую, они указывают на поле, содержащее значение или ссылочный тип, соответственно.

Как и в случае с переменными, существует вариант для полей содержащие Тип : DynamicTypeField

(TODO: clarify value vs. reference types; I think this isn't fully correct)

Drivers

Вы можете использовать содержимое динамической переменной для управления поля или ссылкой, используя компоненты DynamicValueVariableDriver<T> и DynamicReferenceVariableDriver<T>.

Не представленные типы

При создании компонента динамической переменной вам будет предоставлен список "распространённых типов". Если нужного вам типа нету в этом списке, вам придется ввести его вручную. Смотрите Сложные типы в компонентах.

Привязка

Создание, дублирование или перемещение динамической переменной требует привязки этой переменной к пространству. Это процесс, который выполняется автоматически, но пока что еще не совершенен. (cмотри Warning)

По сути, компонент начинает поиск подходящего пространства для динамической переменной в слоте в котором находится переменная. Если совпадений нет, он попробует поискать в родительском слоте, затем в родителе родителя и так далее, пока подходящее пространство не будет найдено. Переменные с явно заданными именами динамического пространства соответствуют только пространствам с таким же именем. Переменные без явного указания имени пространства соответствуют всем пространствам, в которых не включен OnlyDirectBinding.

На следующем изображении показаны различия в привязке:

изображение, демонстрирующее, что пространства для динамических переменных с включенным OnlyDirectBinding игнорируются, за исключением переменных, которые явно объявили одно и тоже имя пространства

  • I: A связана с Inner потому что в пространстве Inner не включен OnlyDirectBinding.
  • II/III: Обе переменных привязаны явно.
  • IV: A игнорирует пространство Inner потому что в пространстве Inner включен OnlyDirectBinding.
  • V/VI: Обе переменных привязаны явно.
  • VII/IX: Нет соответствующего пространства для динамических переменных. Обе переменных не привязаны.
  • VIII: Переменная привязана к пространству World.
  • I и II имеют одно и тоже значение.
  • III, IV и VI имеют одно и тоже значение.

Предупреждение

В некоторых случаях привязка может занять небольшое время, до истечения которого динамическая переменная может казаться существующей, но недоступной для чтения или записи. Таким образом, если вы создаете динамическую переменную с помощью Create Dynamic Variable или Write Or Create Dynamic Variable ProtoFlux ноды, или дублируете её с помощью Duplicate Slot ProtoFlux ноды, или перемещаете её с помощью Set Parent ProtoFlux ноды, возможно, вам потребуется добавить Updates Delay или Updates Delay With Value ProtoFlux ноду после действия, чтобы убедиться, что динамические переменные были привязаны к моменту их использования. Обычно достаточно задержки на 1-3 обновления.


Примеры использования

В следующих примерах будет продемонстрировано несколько вариантов использования динамических переменных. Основное внимание уделяется тому, как использовать их для создания отдельных объектов

Модули внутри объекта

Dynamic variables within an object allow modularization. Different modules would be connected via dynamic variables within the space located at the root of the object. If all hard-coded references going in or out of a module are eliminated you can replace it with a different variant/version without additional setup. Module-local variables can be created with a dynamic variable space located at the root of the module. Use appropriately named spaces to differentiate between the two. To make available variables more obvious to other people - including you in 6 months - it is recommended to place all dynamic variables within a dedicated slot hierarchy.

Commonly used names for such hierarchies are:

  • DV
  • DynVar
  • Vars
  • etc.

A modular object could look like this:

  • Project (Space: MyProject)
    • Dynamic Variables
      • projectVar: String (Dynamic variable projectVar of type String)
    • Module: UI (i.e. MeshRenderer or Canvas plus Colliders), may contain:
    • Module: Logic (Space: Logic)
      • Dynamic Variables
        • logicVar: int (Dynamic variable logicVar of type int)
        • MyProject/Logic:
  • français
  • русский

Slot (Dynamic variable Logic of type Slot for space MyProject, driven with reference to Slot of module to make it accessible to other modules)

      • ProtoFlux (may read, write or even drive dynamic variables of space MyProject)

Configurable objects

Dynamic variables make it possible to access other object's properties.

Assuming objects with a dynamic variable space, a collider and a string variable named Description you could then create a separate tool that reads and displays the Description of the object it is pointed at. The same tool could be extended to edit descriptions.

The same concept can also be applied to template slots used within a project. Their instances can be interacted with using dynamic variables.

World/User variables

There are already pre-made dynamic variable spaces:

They can be used for states that are shared by many objects (i.e. day/night toggle, performance) or to broadcast information into the world. (BeatLink, library objects like the Redprint manager)


See Dynamic Variable Naming Standard for a more detailed listing.