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

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

На этом этапе мы портируем svg_displayinflash.as, который представляет собой код инициализации приложения.
Код состоит из двух функциональных частей: загрузка данных в SVG формате и отрисовка полученного пути. Загрузка данных - дело известное, начнем с этого. Добавим в класс SVGDisplayInFlash методы инициализации загрузки и обработчик полученных данных:
Код AS3:
private function getSVGData(url:String):void {
	const loader:URLLoader = new URLLoader();
	loader.addEventListener(Event.COMPLETE, onSVGLoaded);
	loader.load(new URLRequest(url));
}
 
private function onSVGLoaded(event:Event):void {
	const loader:URLLoader = event.target as URLLoader;
	const data:String = loader.data as String;
	const svg:XML = new XML(data);
	trace(svg.toXMLString());
}
Обратите внимание на то, что мы можем немедленно протестировать загрузку данных, что и сделаем, добавив в initInstance вызов метода getSVGData, передав ему в качестве параметра url файла данных:
getSVGData(SVG_DATA_URL);

Если в результате компиляции не возникло проблем, то можем переходить к следующему шагу: портированию метода getShapes и процедуре его вызова.
Копируем и вставляем этот метод в класс SVGDisplayInFlash и видим, что FDT подсвечивает множество ошибок. Как это ни странно, но это очень хороший признак, что основная масса ошибок пришлась на последний этап портирования и говорит о правильно избранной стратегии действий. Сейчас у нас развязаны руки и мы можем вносить правки в код, не волнуясь о том, что это может чем-то навредить остальной части проекта. Однако мы не забываем, что на этом этапе наша задача - сделать код работоспособным с минимальными изменениями.
Копируем и вставляем объявления переменных, делаем их приватными. Если мы внимательны, то увидим, что переменная x будет конфликтовать со свойством мувиклипа, в котором мы ее объявили. Если мы невнимательны, то компилятор Flash об этом нам напомнит при первом же тесте.
Переименуем ее в svg:
Код AS3:
private var svg:XMLDocument = new XMLDocument();
private var conv:PathToArray;
private var paths:Array;
private var nPathNodes:Number;
Затем заменяем создание мувиклипа на добавление спрайта и получаем ссылку на объект graphics:
Код AS3:
// holder.createEmptyMovieClip("p"+iPath, iPath+1);
 
const drawLayer:Sprite = new Sprite();
holderMc.addChild(drawLayer);
const drawTarget:Graphics = drawLayer.graphics;
После этого заменяем все обращения holder["p"+iPath] на drawTarget.

Приступаем к портированию обработки загруженных данных. Пока мы можем пропустить обработку ошибок, поэтому просто переносим строки инициализации из оригинального метода xmlLoaded в метод onSVGLoaded:
Код AS3:
msg.text = "";
paths = x.firstChild.firstChild.childNodes;
nPathNodes = paths.length;
getShapes(0);
Заменяем msg на messageTxt и x на svg.
Добавляем парсинг полученных данных перед первым обращением к объекту svg:
Код AS3:
svg.ignoreWhite = true;
svg.parseXML(data);
Вот то, что в итоге должно было быть добавлено в класс:
Код AS3:
private var svg:XMLDocument = new XMLDocument();
svg.ignoreWhite = true;
private var conv:PathToArray;
private var paths:Array;
private var nPathNodes:Number;
 
private function onSVGLoaded(event:Event):void {
	const loader:URLLoader = event.target as URLLoader;
	const data:String = loader.data as String;
 
	messageTxt.text = "";
 
	svg.parseXML(data);
	paths = svg.firstChild.firstChild.childNodes;
	nPathNodes = paths.length;
 
	getShapes(0);
}
 
private function getShapes(iPath:Number):void {
	var dCmds:Array = new Array();
	var d:Array;
	var dp:Array;
 
	conv = new PathToArray(paths[iPath], dCmds);
 
	// draw the shapes in clips in holder movieclip
	// holder.createEmptyMovieClip("p"+iPath, iPath+1);
 
	const drawLayer:Sprite = new Sprite();
	holderMc.addChild(drawLayer);
	const drawTarget:Graphics = drawLayer.graphics;
 
	for (var i:Number=0; i<dCmds.length; i++) {
		d = dCmds[i];
		dp = d[1];
		switch (d[0]) {
			case "F" :
				drawTarget.beginFill(dp[0], dp[1]);
				break;
			case "S" :
				drawTarget.lineStyle(dp[0], dp[1], dp[2]);
				break;
			case "M" :
				drawTarget.moveTo(dp[0], dp[1]);
				break;
			case "L" :
				drawTarget.lineTo(dp[0], dp[1]);
				break;
			case "C" :
				drawTarget.curveTo(dp[0], dp[1], dp[2], dp[3]);
				break;
		}
	}
	// repeat til all paths have been read
	if (++iPath < nPathNodes) getShapes(iPath);
}
Тестируем изменения. Если видим на экране попугая, то всё хорошо. Если нет, а вполне возможно что в ходе объяснений я что-то пропустил или был неточен, то для такого случая я приаттачу необходимые файлы.

Что же нам позволило даже не вникая в суть кода добиться успеха? Методология. Мы следовали простым принципам и в каждый момент делали только то, что соответствовало нашей стратегии:

- мы портировали код в строгом порядке: вначале портировались классы не использовавшие других пользовательских классов, только затем классы, использовавшие уже портированные классы, до тех пор, пока таким образом не закончили последний.
- мы не изменяли код без крайней на то необходимости и оставили это на самый последний момент.
- мы тестировали код при первой возможности.

Чего мы избегали:
- мы не пытались улучшить код, добавить недостающую типизацию, или изменить логику кода.
Мы оставили это для следующих этапов: рефакторинга и оптимизации.
Вложения
Тип файла: zip SVGToFlash.zip (17.8 Кб, 465 просмотров)
__________________
http://realaxy.com


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