Показать сообщение отдельно
Старый 18.03.2008, 22:02
Iv вне форума Посмотреть профиль Отправить личное сообщение для Iv Посетить домашнюю страницу Iv Найти все сообщения от Iv
  № 51  
Iv
 
Аватар для Iv

Регистрация: Apr 2001
Адрес: Moscow
Сообщений: 1,475
По умолчанию Третий путь

Я решил пойти по третьему пути: создать коллекцию методов и брать методы из нее.
Это быстрый вариант, понятный большинству разработчиков и в нем можно задействовать константы класса FormatSVG. Хотя без некоторых переделок не обойтись.

Опять протестируем на коротком примере.
Объявим статической константой коллекцию методов и добавим ссылку на метод:
Код AS3:
private static const DRAW_METHODS:Object = new Object();
	DRAW_METHODS[FormatSVG.MOVE_TO_ABSOLUTE] = createMoveToCommand;
Тестируем и обнаруживаем, что статическая константа не видит метод экземпляра класса. Ну, в общем это правильно, особенно учитывая то, что каждый метод привязан к экземпляру класса.

Мы можем создать такой экземпляр перед объявлением коллекции:
Код AS3:
private static const INSTANCE:PathToArray = new PathToArray(null, null);
Тестируем, получаем ошибку. Причина ошибки понятна: мы передали невалидные аргументы. Чтобы от нее избавиться, достаточно в конструктор класса добавить проверку:
Код AS3:
if (svgNode == null || dCmds == null) {
	return;
}
Теперь добавляем тестовый вызов:
Код AS3:
case FormatSVG.MOVE_TO_ABSOLUTE :
	var drawMethod:Function = DRAW_METHODS[FormatSVG.MOVE_TO_ABSOLUTE];
	trace("drawMethod: " +drawMethod);
	j = drawMethod.call(this, svgCmds, j);
	// j = createMoveToCommand(svgCmds, j);
	break;
и опять обламываемся. Функция в коллекции найдена, но внутри функции всё равно идет обращение к экземплярам пустого объекта.
Чтобы избежать этого, передадим текущий объект в аргументах и внутри методов будем использовать обращение используя только его. А поскольку пустой экземпляр в таком случае не нужен, удаляем объявление константы INSTANCE и делаем метод createMoveToCommand статическим.
Вот что получается:

Код AS3:
private static const DRAW_METHODS:Object = new Object();
	DRAW_METHODS[FormatSVG.MOVE_TO_ABSOLUTE] = createMoveToCommand;
 
private function makeDrawCmds(svgCmds:Array):void {
	....
	case FormatSVG.MOVE_TO_ABSOLUTE :
 
		var drawMethod:Function = DRAW_METHODS[FormatSVG.MOVE_TO_ABSOLUTE];
		j = drawMethod(this, svgCmds, j);
		// j = createMoveToCommand(svgCmds, j);
		break;
	....
}
private static function createMoveToCommand(instance:PathToArray, svgCmds:Array, j:int) : int {
	// moveTo point
	instance.firstP = instance.lastP = new Point(Number(svgCmds[j]), Number(svgCmds[j + 1]));
	instance.drawingCommands.push(new FillCommand(instance.fill.color, instance.fill.alpha));
	instance.drawingCommands.push(new StyleCommand(instance.stroke.width, instance.stroke.color, instance.stroke.alpha));
	instance.drawingCommands.push(new MoveCommand(instance.firstP.clone()));
	j += 2;
	if (j < svgCmds.length && !isNaN(Number(svgCmds[j]))) {  
		do {
			// if multiple points listed, add the rest as lineTo points
			instance.lastP = new Point(Number(svgCmds[j]), Number(svgCmds[j + 1]));
			instance.drawingCommands.push(new LineCommand(instance.lastP.clone()));
			instance.firstP = instance.lastP;
			j += 2;
		} while (j < svgCmds.length && !isNaN(Number(svgCmds[j])));
	}
	return j;
}
Если мы аналогично заменим обращения ко всем методам, станет ли наш код от этого лучше? Нет, только не это.

Мы честно пытались сделать makeDrawCmds лучше и достигли определенных успехов: теперь он читабелен. Но структура кода пока очень жесткая и мы столкнулись с тем, что не можем сделать этот участок лучше.
Стоит ли продолжать?
Нужно уметь остановиться и сказать себе, что время этой части кода еще не наступило.
Позднее, когда архитектура проекта станет лучше, мы вернемся к этому вопросу.
__________________
http://realaxy.com


Последний раз редактировалось iNils; 20.12.2010 в 13:34.