Кук-бук. Класс настроек в ActionScript
При разработке почти любого проекта, реализуемого с помощью технологии Flash, разработчик встречается с необходимостью хранить разнообразные данные и настройки во время сеанса исполнения программы. Сегодня мы познакомимся с одним из рецептов AS3-класса для хранения настроек.
Решение, которое я хочу вам сегодня предложить, используется в качестве саморасширяемого хранилища данных и реализуется с помощью класса, наследуемого от flash.utils.Proxy. Этот класс имеет одну особенность, которую нельзя реализовать штатными возможностями Flash/ActionScript – он может перехватывать обращения к несуществующим методам и свойствам объекта.
Вот как мог бы выглядеть такой класс на языке AS3:
Давайте последовательно разберем этот пример. Для начала – строки импорта классов. С Proxy и flash_proxy все понятно, так как мы наследуемся от Proxy, но зачем понадобился спрайт и события? Все просто. В конструкторе класса происходит создание события, а класс Proxy на это не способен. Поэтому при создании первого экземпляра нашего класса Config в качестве параметра мы передадим ему Root нашего флеш-приложения, который будет заниматься генерацией событий. Первое событие создается уже в конструкторе и оповещает приложение о том, что создание нашего класса настроек завершено.
В теле класса определяются несколько статических переменных. Это означает, что существует всего один их экземпляр, который используется всеми объектами данного класса. Например, в переменной _singletone_exist у меня хранится информация о том, был ли экземпляр данного класса создан раньше. Это позволяет создать пусть и не очень совершенное по устройству, но весьма убедительное в эксплуатации подобие Singleton- объекта. В переменной _root_object хранится Root флеш-ролика, переданный в конструктор первого экземпляра Config. И, наконец, в массиве (вернее, динамическом объекте) _properties хранятся все данные, которые мы захотим поместить в наше хранилище.
Настоящая магия начинается при переопределении функций getProperty и setProperty. Встретившись с обращением к незнакомому свойству класса, Proxy передаст в эти функции параметры обращения (начиная с имени свойства). Вот как выглядит использование данного класса на практике:
Данный пример, разумеется, предельно упрощен для понимания основной идеи. На практике в него следует многое добавить. Вам понадобятся события, сообщающие об ошибках инициализации, подгрузка параметров из файла и, соответственно, события инициализации, вынесенные из конструктора, а со временем – использование Bindable-данных, чтобы не возиться с обновлением экрана при изменении одной переменной в Config. Однако это пример полностью работоспособен и даже в таком виде может быть использован в реальных проектах.
Поляков Александр, Lecosson@mail.ru
Решение, которое я хочу вам сегодня предложить, используется в качестве саморасширяемого хранилища данных и реализуется с помощью класса, наследуемого от flash.utils.Proxy. Этот класс имеет одну особенность, которую нельзя реализовать штатными возможностями Flash/ActionScript – он может перехватывать обращения к несуществующим методам и свойствам объекта.
Вот как мог бы выглядеть такой класс на языке AS3:
package |
{ |
import flash.utils.Proxy; |
import flash.utils.flash_proxy; |
import flash.display.Sprite; |
import flash.events.Event; |
dynamic public class Config extends Proxy |
{ |
// СВОЙСТВА |
private static var _singletone_exist:Boolean=false; |
private static var _root_object:Sprite=null; |
private static var _properties:Object=new Object(); |
// ПРЕДОПРЕДЕЛЕННЫЕ ПАРАМЕТРЫ |
public const text1:String="example text 1"; |
// КОНСТРУКТОР |
public function Config(rootObject:Sprite=null) |
{ |
super(); |
if (!_singletone_exist) |
{ |
_singletone_exist=true; |
_root_object=rootObject; |
_root_object.dispatchEvent(new Event("conf_ok", true)); |
}; |
} |
// МЕТОДЫ Proxy-хранилища |
override flash_proxy function getProperty(name:*):* |
{ |
return (name in _properties) ? (_properties[name]) : ('Свойство "' + name + '" не существует!'); |
} |
override flash_proxy function setProperty(name:*, value:*):void |
{ |
_properties[name]=value; |
} |
} |
} |
Давайте последовательно разберем этот пример. Для начала – строки импорта классов. С Proxy и flash_proxy все понятно, так как мы наследуемся от Proxy, но зачем понадобился спрайт и события? Все просто. В конструкторе класса происходит создание события, а класс Proxy на это не способен. Поэтому при создании первого экземпляра нашего класса Config в качестве параметра мы передадим ему Root нашего флеш-приложения, который будет заниматься генерацией событий. Первое событие создается уже в конструкторе и оповещает приложение о том, что создание нашего класса настроек завершено.
В теле класса определяются несколько статических переменных. Это означает, что существует всего один их экземпляр, который используется всеми объектами данного класса. Например, в переменной _singletone_exist у меня хранится информация о том, был ли экземпляр данного класса создан раньше. Это позволяет создать пусть и не очень совершенное по устройству, но весьма убедительное в эксплуатации подобие Singleton- объекта. В переменной _root_object хранится Root флеш-ролика, переданный в конструктор первого экземпляра Config. И, наконец, в массиве (вернее, динамическом объекте) _properties хранятся все данные, которые мы захотим поместить в наше хранилище.
Настоящая магия начинается при переопределении функций getProperty и setProperty. Встретившись с обращением к незнакомому свойству класса, Proxy передаст в эти функции параметры обращения (начиная с имени свойства). Вот как выглядит использование данного класса на практике:
package |
{ |
import flash.utils.Proxy; |
import flash.utils.flash_proxy; |
import flash.display.Sprite; |
import flash.events.Event; |
dynamic public class Config extends Proxy |
{ |
// СВОЙСТВА |
private static var _singletone_exist:Boolean=false; |
private static var _root_object:Sprite=null; |
private static var _properties:Object=new Object(); |
// ПРЕДОПРЕДЕЛЕННЫЕ ПАРАМЕТРЫ |
public const text1:String="example text 1"; |
// КОНСТРУКТОР |
public function Config(rootObject:Sprite=null) |
{ |
super(); |
if (!_singletone_exist) |
{ |
_singletone_exist=true; |
_root_object=rootObject; |
_root_object.dispatchEvent(new Event("conf_ok", true)); |
}; |
} |
// МЕТОДЫ Proxy-хранилища |
override flash_proxy function getProperty(name:*):* |
{ |
return (name in _properties) ? (_properties[name]) : ('Свойство "' + name + '" не существует!'); |
} |
override flash_proxy function setProperty(name:*, value:*):void |
{ |
_properties[name]=value; |
} |
} |
} |
Данный пример, разумеется, предельно упрощен для понимания основной идеи. На практике в него следует многое добавить. Вам понадобятся события, сообщающие об ошибках инициализации, подгрузка параметров из файла и, соответственно, события инициализации, вынесенные из конструктора, а со временем – использование Bindable-данных, чтобы не возиться с обновлением экрана при изменении одной переменной в Config. Однако это пример полностью работоспособен и даже в таком виде может быть использован в реальных проектах.
Поляков Александр, Lecosson@mail.ru
Компьютерная газета. Статья была опубликована в номере 08 за 2010 год в рубрике soft