Кук-бук. Класс настроек в ActionScript

При разработке почти любого проекта, реализуемого с помощью технологии Flash, разработчик встречается с необходимостью хранить разнообразные данные и настройки во время сеанса исполнения программы. Сегодня мы познакомимся с одним из рецептов AS3-класса для хранения настроек.

Решение, которое я хочу вам сегодня предложить, используется в качестве саморасширяемого хранилища данных и реализуется с помощью класса, наследуемого от 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

©1997-2024 Компьютерная газета