Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Паралельная загрузка нескольких XML файлов. (http://www.flasher.ru/forum/showthread.php?t=134144)

proxiServer 22.12.2009 16:20

Паралельная загрузка нескольких XML файлов.
 
Идет процесс инициализации. Нужно в середине процесса подгрузить несколько XML файлов. Как мне сначала загрузить все что нужно, а потом запустить процесс далее. Я начинаю грузить несколько файлов. Событий на завершение загрузки тоже несколько. Кто закончит раньше знать не могу.

Первое, что пришло, это цепочка. Начинаю грузить первый файл. В событии окончания загрузки разбираю файл и начинаю грузить второй. В событии завершения загрузки второго файла разбираю файл и начинаю грузить третий. И так далее по всем файлам. В функции события окончания загрузки последнего файла продолжаю работу основной программы.

И что-то с ходу нормальной альтернативы придумать не могу.

Gaen 22.12.2009 16:24

Для каждого файла заведите флаг загрузки. При завершении загрузки файла устанавливаете его флаг и проверяете все остальные - если все стоят, значит все файлы загружены.

proxiServer 22.12.2009 16:47

Хм... А если файлов много, то кучу флагов делать? Про флаги была идея, но не очень нравиться. Может есть еще какой метод?

Jewelz 22.12.2009 17:06

я делаю либо флаги, либо цепочкой :)

ИМХО флаги лучше, а что не нравится?

proxiServer 22.12.2009 17:22

Jewelz, и там и там не удобно изменять структуру. У меня файлов много. И на этапе разработки их перечень постоянно меняется. Да и сомнения берут, что это правильный подход. Потому то собственно и интересуюсь.

iflamberg 22.12.2009 17:25

Можно сделать счетчик вместо флагов. Еще есть bulk-loader, готовая библиотека для таких дел, но я ее ни разу не использовал.

veisss 22.12.2009 17:25

можно еще запомнить в начале кол-во файлов в переменную и при окончании загрузки минусовать, и тут-же проверять если ноль то все уже загрузились

random13 22.12.2009 17:55

а в чем проблема закинуть кучу лодеров в массив и слушать когда же она закачают

proxiServer 22.12.2009 17:57

iflamberg Спасибо за наводку. То что нужно.

Код AS3:

    import br.com.stimuli.loading.BulkLoader;
 
        /*
        * Грузить можно что угодно и как угодно.
        * Просто и удобно.
        */

    var bulkLoader : BulkLoader = new BulkLoader("main loading");
    bulkLoader.add("my_xml_file.xml");
    bulkLoader.add("main.swf");
    var backgroundURL : URLRequest = new URLRequest("background.jpg");
    bulkLoader.add(backgroundURL);
 
        //Событие завершения загрузки.
    bulkLoader.addEventListener(BulkLoader.COMPLETE, onCompleteHandler);
    //Событие для прогрессбара
    bulkLoader.addEventListener(BulkLoader.PROGRESS, _onProgressHandler);
 
    //Собственно запустили загрузку.
    bulkLoader.start();
 
        //Это прогрессбар, все понятно.
    function _onProgressHandler(evt : ProgressEvent) : void{
        trace("Loaded" , evt.bytesLoaded," of ",  evt.bytesTotal);
    }
 
 
    function onCompleteHandler(evt : ProgressEvent) : void{
 
            //Вытаскиваем так.
            var mainMovie : MovieClip = bulkLoader.getMovieClip("main.swf");
            var mXML : XML = bulkLoader.getXML("my_xml_file.xml");                       
            var myBitmap : Bitmap = bulkLoader.getBitmap("background.jpg");
            var myBitmap : Bitmap = bulkLoader.getBitmap(backgroundURL);
    }
 
        //Самый кайф! В любом классе вашего проекта можем по уникальному имени обратиться
        //к нашей загрузке и тащить из нее то что нам нужно.
        //Прям как библиотека флешовая.
    var mainLoader : BulkLoader = BulkLoader.getLoader("main loading");
 
    var mXML : XML = mainLoader.getXML("my_xml_file.xml");
    var mXML : XML = BulkLoader.getLoader("main loading").getXML("my_xml_file.xml");

Правда последний прикол нужно проверить. Что-то прям даже не верится. Кто знает как такое сделать без передачи ссылок параметром? Как сделано подскажите? Через статические классы?

Все, сам посмотрел внутри. Через статику сделано. Классно и не сильно большая библиотека.

random13 Лоадеры в массив - понятно. Слушать когда закачаются - непонятно. Слушать как?

random13 22.12.2009 18:15

Цитата:

Сообщение от proxiServer (Сообщение 874332)
iflamberg
random13 Лоадеры в массив - понятно. Слушать когда закачаются - непонятно. Слушать как?


cоздаем лодер, кидаем ему ссыль, говорим загрузить, вешаем слушатель на лодер(по завершение загрузки выполнить то то), закидываем слушатель в массив.

как ток выполнился колбек удаляем лодер из массива, стопим все снимаем слушатель и уничтожаем лодер

proxiServer 22.12.2009 18:19

random13 Понял. Не умею вешать слушатели. Буду разбираться. Вопрос! Я сильно проиграю в производительности и размере флешки, если буду использовать эту библиотеку? По сути там реализовано как раз то что вы описали. Ведь удобная же, да?)

Zebestov 22.12.2009 18:34

У меня было удобно все COMPLETE отрабатывать в одном методе — он складывал полученные XML в массив, инкрементировал некую переменную и сравнивал ее с ожидаемым количеством загруженных данных. Если больше — шел дальше: перебирал массив и в зависимости от имени корневого элемента отсылал на тот или иной парсер.
Сделай так же. Даже если у тебя обработчики разные (ну например ты парсишь сразу или еще что-то) — вынеси инкремент с проверкой в отдельную функцию и вызывай ее в каждом своем обработчике.

proxiServer 23.12.2009 10:52

Zebestov, а можно код? Я даже понять не могу что не могу понять) Вроде все отдельные слова понимаю, а все вместе не складывается(

silin 23.12.2009 11:36

Код AS3:

package
{
        import flash.display.*;
        import flash.events.*;
        import flash.net.*;
        import flash.utils.*;
 
        public class Main extends Sprite
        {
                private var _map:Dictionary = new Dictionary();
                private var _counter:int;
 
                public function Main():void
                {
 
                        var urls:Array = ["xml1.xml", "xml2.xml"];
                        var parsers:Array = [parser1, parser2];
                        _counter = urls.length;
                        for (var i:int = 0; i < _counter; i++)
                        {
                                var loader:URLLoader = new URLLoader(new URLRequest(urls[i]));
                                loader.addEventListener(Event.COMPLETE, onLoadComplete);
                                loader.addEventListener(IOErrorEvent.IO_ERROR, onLoadError);
                                _map[loader] = parsers[i];
                        }
 
                }
 
                private function onLoadError(evnt:IOErrorEvent):void
                {
                        trace( "Main.onLoadError > evnt : " + evnt );
                        if (--_counter == 0) startApp();//или не старт, дело хозяйское
                }
 
                private function onLoadComplete(evnt:Event):void
                {
                        evnt.target.removeEventListener(Event.COMPLETE, onLoadComplete);
                        var data:XML = new XML(evnt.target.data);
                        var parser:Function = _map[evnt.target];
                        parser(data);
                        if (--_counter == 0) startApp();
 
                }
                private function startApp():void
                {
                        trace( "Main.startApp" );
 
                }
                private function parser1(data:XML):void
                {
                        trace( "Main.parser1 > data : " + data );
 
                }
                private function parser2(data:XML):void
                {
                        trace( "Main.parser2 > data : " + data );
 
                }
        }
 
}


random13 23.12.2009 12:57

Цитата:

Сообщение от proxiServer (Сообщение 874344)
random13 Понял. Не умею вешать слушатели. Буду разбираться. Вопрос! Я сильно проиграю в производительности и размере флешки, если буду использовать эту библиотеку? По сути там реализовано как раз то что вы описали. Ведь удобная же, да?)

значительно проираете, я по первости тоже пробовал использовать BulkLoader, лажа полная...

тоже самое пишешь самостоятельно ток без всякой кривоты

Zebestov 23.12.2009 13:43

Код AS3:

private function loadXML():void
{
        var ldr1:URLLoader = new URLLoader(new URLRequest("http://www.domain.com/data1.xml"));
        ldr1.addEventListener(Event.COMPLETE, onXMLComplete);
        var ldr2:URLLoader = new URLLoader(new URLRequest("http://www.domain.com/data2.xml"));
        ldr2.addEventListener(Event.COMPLETE, onXMLComplete);
        var ldr3:URLLoader = new URLLoader(new URLRequest("http://www.domain.com/data3.xml"));
        ldr3.addEventListener(Event.COMPLETE, onXMLComplete);
}
private function onXMLComplete(e:Event):void
{
        e.target.removeEventListener(Event.COMPLETE, onXMLComplete);
        this._XMLHolder.push(XML((e.target as URLLoader).data));
        if (this._XMLHolder.length == 3) this.parseXML();
}
private function parseXML():void
{
        var tree:XML;
        for each (tree in this._XMLHolder)
        {
                switch (tree[0].name().toString()) {
                        case "data1":
                                this.holdData1(tree);
                                break;
                        case "data2":
                                this.holdData2(tree);
                                break;
                        case "data3":
                                this.holdData3(tree);
                                break;
                }
        }
}

Ну как-то так. В моем случае я точно знаю, что гружу 3 XML-документа, и их надо парсить по-разному.

proxiServer 23.12.2009 16:26

silin Спасибо. Понял каких знаний не хватало.

Код AS3:

                        var parser:Function = _map[evnt.target];
                        parser(data);

Это же classFactory легко можно сделать, мне как раз нужно. Самое смешное, что читал про это даже. Но видимо пока в деле фичу не увидишь...

random13 А что конкретно было не так? Я вроде как обучаюсь флешу. Хочется выбрать один вариант и уже спокойно пользовать и не переучиваться. Но уж больно подкупает бульк простотой. Хотя и самому подгружать не большая проблема, как мне уже показали, но все-таки. По различным вариациям запроса "bulk-loader недостатки" ничего не нашел. В чем проигрываем? Память, скорость, функциональность?

Zebestov Угу, понял все, кроме старта загрузки. URLLoader в конструкторе начинает загрузку?

Zebestov 23.12.2009 18:43

Цитата:

Сообщение от proxiServer (Сообщение 874578)
URLLoader в конструкторе начинает загрузку?

ага

конечно задротней сначала вешать обработчик на процессы, прежде чем запускать их =) но не в данном случае. хотя с моим максимализмом я удивлен как это я не сделал все через load() 0o

random13 23.12.2009 22:19

Цитата:

Сообщение от proxiServer (Сообщение 874578)
silin Спасибо. Понял каких знаний не хватало.

Код AS3:

                        var parser:Function = _map[evnt.target];
                        parser(data);

Это же classFactory легко можно сделать, мне как раз нужно. Самое смешное, что читал про это даже. Но видимо пока в деле фичу не увидишь...

random13 А что конкретно было не так? Я вроде как обучаюсь флешу. Хочется выбрать один вариант и уже спокойно пользовать и не переучиваться. Но уж больно подкупает бульк простотой. Хотя и самому подгружать не большая проблема, как мне уже показали, но все-таки. По различным вариациям запроса "bulk-loader недостатки" ничего не нашел. В чем проигрываем? Память, скорость, функциональность?

Zebestov Угу, понял все, кроме старта загрузки. URLLoader в конструкторе начинает загрузку?


его простота как то невнятно работает, прибавляет уж не помню точно, помойму около 10k веса и ничего хорошего, то же самое выполняет пара методов описанных выше..

proxiServer 24.12.2009 10:36

random13 У меня приложение уже больше двух мегабайт. Для банера я конечно эту либу не буду использовать, но для флешек весом больше 100кб можно наверное)

Zebestov
from help.adobe
Цитата:

Операция загрузки может начаться сразу же, если таковое указано (дополнительные сведения см. в разделе о load).
Что-то я не нашел там про, как таковое указать.

Zebestov 24.12.2009 13:47

0o

ну вот если сделаешь так:
Код AS3:

var ldr1:URLLoader = new URLLoader();

никто никого не грузит, все ждут пока ты где-то напишешь:
Код AS3:

ldr1.load(new URLRequest("http://www.domain.com/data1.xml"));

а вот так:
Код AS3:

var ldr1:URLLoader = new URLLoader(new URLRequest("http://www.domain.com/data1.xml"));

создали и понеслась!

random13 24.12.2009 13:53

Цитата:

Сообщение от proxiServer (Сообщение 874815)
random13 У меня приложение уже больше двух мегабайт. Для банера я конечно эту либу не буду использовать, но для флешек весом больше 100кб можно наверное)

Zebestov
from help.adobe


Что-то я не нашел там про, как таковое указать.

то есть это только я борюсь за каждый килл))

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

proxiServer 24.12.2009 15:34

random13 А он последовательно грузит?

random13 24.12.2009 21:57

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


Часовой пояс GMT +4, время: 13:27.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.