В A-Frame системы используются для управления глобальным состоянием приложения, обеспечивая централизованное хранение данных, которые могут использоваться компонентами на разных сущностях. Системы создаются аналогично компонентам, но они не привязаны к конкретной сущности и живут на уровне сцены. Основная задача системы — инкапсулировать логику и состояние, доступное для компонентов, обеспечивая единый источник правды.
Система определяется через метод
AFRAME.registerSystem(name, definition). Параметр
name задает уникальное имя системы, а
definition — объект, содержащий свойства и методы.
Стандартная структура системы включает:
schema — описание конфигурации с типами данных и
значениями по умолчанию.init() — инициализация системы при загрузке сцены.update(oldData) — реагирование на изменения
конфигурации.tick(time, timeDelta) — вызов на каждом кадре
рендеринга.Пример создания системы для управления глобальным светом:
AFRAME.registerSystem('lighting', {
schema: {
intensity: { type: 'number', default: 1.0 },
color: { type: 'color', default: '#ffffff' }
},
init: function () {
this.lights = [];
},
addLight: function (lightEl) {
this.lights.push(lightEl);
lightEl.setAttribute('light', {
intensity: this.data.intensity,
color: this.data.color
});
},
update: function (oldData) {
this.lights.forEach(lightEl => {
lightEl.setAttribute('light', {
intensity: this.data.intensity,
color: this.data.color
});
});
}
});
В этом примере система хранит массив всех источников света сцены и обеспечивает синхронизацию их свойств с глобальным состоянием.
Компоненты могут обращаться к системе через объект сцены:
this.el.sceneEl.systems['systemName']. Это позволяет
компонентам получать и изменять глобальное состояние, не дублируя
логику.
Пример компонента, который регистрирует себя в системе света:
AFRAME.registerComponent('dynamic-light', {
init: function () {
const lightingSystem = this.el.sceneEl.systems['lighting'];
lightingSystem.addLight(this.el);
}
});
Такой подход обеспечивает единую точку управления и исключает необходимость хранения состояния на каждой отдельной сущности.
Системы могут создавать и обрабатывать собственные события, чтобы
компоненты реагировали на изменения состояния. Для этого используется
emit и addEventListener на объекте сцены:
AFRAME.registerSystem('game', {
init: function () {
this.score = 0;
},
increaseScore: function (points) {
this.score += points;
this.el.sceneEl.emit('score-changed', { score: this.score });
}
});
AFRAME.registerComponent('score-display', {
init: function () {
const gameSystem = this.el.sceneEl.systems['game'];
this.el.addEventListener('score-changed', evt => {
this.el.setAttribute('text', 'value', `Score: ${evt.detail.score}`);
});
}
});
Такой подход делает систему реактивной, позволяя компонентам автоматически обновлять своё состояние при изменении глобальных данных.
A-Frame предоставляет встроенные системы, которые управляют общим состоянием сцены:
Понимание принципа работы встроенных систем помогает проектировать собственные системы, соблюдая архитектурный стиль A-Frame и обеспечивая согласованное управление состоянием.