![]() |
Многопоточность и асинхронный вызов методов во Flex
Всем привет!
Ктонибудь может подсказать по теме? Быть может интересная литература или ещё какието ресурсы. Столкнулся с тем, что во Flex зачастую не все работает так, как ты этого ожидаеш. Timer я так понял не запускается в отдельном потоке, и обработчики событий вызываются не всегда по цепочке. Очень интересно былобы узнать когда имеет место асинхронность и может быть есть пути делать какието вещи синхронно, если это нужно. |
Стандартных средств для синхронного вызова методов нет.
Приходиться делать самодельные очереди. Реализовать можно по-разному. Например: массив "операция" (или функции, или специальные объекты) и индекс, какая из операций текущая. Каждая операция должна сообщить о своём завершении. При этом индекс увеличится на единицу и будет выполнена запущена следующая операция. Вариант: вместо изменения индекса просто удалять "отстрелявшуюся" операцию из очереди. ---- А вообще, как я уже неоднократно говорил ранее, надо менять компилятор, чтобы всё это было прозрачно. |
LexeY4eg, ActionScript сам по себе работает в единственном потоке.
|
У меня tcnm ytcrjkmrj вопросов:
1. если я в цикле вызываю какойто метод у кучи обьектов, есть ли гарантия, что каждый последующий метод будет выполнен по завершению предыдущего? Код:
for (var i:Number = 0; i < 100; i ++) {2. Если ActionScript работает в одном потоке, то как реализован Timer? 3. Где можно посмотреть исходники EventDispatcher и других классов Flex SDK, хотябы Timer ещё. |
Цитата:
Это не мешает коду на ActionScript быть многопоточным. Аналогии: JVM (по крайней мере некоторые из её реализаций) работают в одном потоке. Это не мешает коду на Java быть многопоточным. Одноядерный процессор без Hyper Threading может исполнять только один поток одновременно. Это не мешает приложениям быть многопоточными. Поток в любой момент можно поставить "на паузу" и начать выполнять другой поток. Квантованием времени можно достигнуть эффекта, что несколько потоков выполняются одновременно. Кроме того, один поток может быть остановлен, ожидая какого-то события. В это время может выполняться другой поток. Разумеется, есть некоторые ограничения, накладываемые всё той же однопоточностью AVM2, например, многопоточность будет невытесняющая: каждый поток сам должен время от времени останавливать себя, давая возможность выполниться другим потокам. То есть как в старом добром Windows 3.1 Цитата:
Следующий будет вызван только после того, как завершиться предыдущий. Но если эти методы запускают какие-то "долгоиграющие" действия, например: запуск анимации, проигрывание звука, запрос к серверу и т.д., то методы будут исполнятся не дожидаясь, пока эти длительные действия завершаться. |
WindWalker, тогда напишите компилятор, который создаст AVM2-совместимый код и реализующий эту самую многопоточность. А пока этого нет, никакой многопоточности в плеере и AS нет.
|
Цитата:
|
Вложений: 1
Да есть там всё.
Вот примерчик когда-то делал, именно как демонстрацию многопоточности. Одновременно происходят вычисления, которым требуется очень много времени и которые в обычном случае подвесили бы флеш-плеер, и появилась бы ошибка "скрипт выполняется слишком долго". Здесь же этого не происходит, вычисления выполняются постепенно и на экран выдаётся текущий прогрес. По сути - два отдельных потока: один вычисляет, другой отображает. Есть в этом что-то чудесное и удивительное? Нет. Все прекрасно знают, как это сделать, и сами делали не раз. Но это требует написание дополнительного кода, а также рестуктуризацию самого кода вычислений (простой цикл заменяется на несколько функций). Новый компилятор нужен только для того, чтобы освободить от этой рутины, чтобы каждый раз не изобретать этот велосипед. Вобщем, скажем так: AVM2 выполняется в одном потоке. Код на abc-байткоде может быть многопоточным. ActionScript3 не имеет встроенных средств для создания и работы с потоками, поэтому приходиться использовать обходные пути. |
Цитата:
Код:
public class Teststart 0 finish 0 start 1 finish 1 start 2 finish 2 как вы это обьясните? |
Цитата:
Нпример, загрузка внешнего файла или HTTP-запрос. Пока цикл не закончится, функция разумеется не завершится. |
WindWalker, swf без сорсов ничего такого своим внешним видом не рассказывает. Если вы реализовали несколько конвееров (которые имеют псевдо одно и то же время старта), то это не многопоточность.
|
Цитата:
Цитата:
|
Цитата:
А выглядит это просто - достаточно объёмные вычисления (9! = 362880 итераций - для AS2 это достаточно много) не подвешивают плеер, а выполняются постепенно с отображением текущего прогресса. Принцип работы простой: есть метод, который выполняет одну-единственную итерацию. В onEnterFrame засекается время через getTimer(), затем начинает в цикле вызываться метод и после каждого заверешения проверяется, сколько времени прошло. Метод вызывается до тех пор, пока время не превысит 20 миллисекунд. На этом обработка onEnterFrame заканчивается. Продолжение - в следующем кадре. То есть в каждом кадре выполняется столько итераций, сколько успеет выполниться за 20 мс. Основная проблема такого подхода - необходимо вычленить эту самую "одну итерацию". Цитата:
1. А что тогда такое многопоточность? Критерии, пожалуста. 2. Зачем нужна полная и настоящая многопоточность для синхронных вызовов? |
1. Независимость потоков друг от друга. Цикл на миллион итераций, выполняющийся 100 миллисекунд, никак не влияет на тот же таймер, «тикающий» каждые 10 мс;
2. А как вы сделаете два вызова в один момент времени без многопоточности? |
Цитата:
Но это условие и не обязательно. В Windows 3.1 форматирование дискетки останавливало все остальные процессы - тут уж ничего не поделаешь, недостатки невытесняющей многозадачности. Но задача-то состоит не в том, чтобы потоки выполнялись плавно. Основная задача - синхронные вызовы. Цитата:
Гарантии, что таймер будет тикать раз в 10мс, а fps будет всегда ровно 30, нам тут совершенно не требуются. |
2WindWalker
Суть потока в том, что когда мы пишем код исполняемых им функций мы абстрагируемся от распределения процессорного времени. А здесь вы предлагаете в каждом вызове функции, проверять таймер и писать ещё дофига кода для обрывания "потока" исполнения и запоминания состояния, получается код во время своего исполнения занимается постоянным мониторингом псевдопотока. бууууэээээ.... |
Нет, я вовсе не предлагаю проверять таймер.
Это просто одна из реализаций - эксперимент на тему "хочу квантование". Но вы правы - действительно для того, чтобы сделать что-то потокообразное - либо для синхронных вызовов, либо (уже другая, но смежная задача) для более плавного выполнения больших вычислений/парсинга xml/обработки битмапов/прочего - необходимо написать оочень много лишнего кода. Более того - код должен иметь особую структуру. Каждая возможная пауза означает создание как минимум одной новой функции. И иногда это может повернуться боком. Вот как раз таки чтобы полностью абстрагироваться, необходимо, чтобы всю рутину взял на себя компилятор. Тогда мы сможем писать чистый и понятный код без всякой мишуры, которую приходиться добавлять сейчас. ------------------- А вообще разговоры про многопоточность меня уже достали. Да, её как таковой нет. Да, её можно эмулировать. Да, это потребует дополнительного кода. Я наконец-то хочу обсудить с кем-нибудь шарящим, какие реальные проблемы могут возникуть при автоматической генерации псевдопотокового кода. Но все почему-то упорно зацикливаются на всякой маловажной ерунде. |
Куда-нибудь, в светлом будущем, она может быть будет…
|
Вложений: 1
Итак, постановка задачи...
Очень часто требуется выполнить несколько действий последовательно. Каждое последущее должно начинать выполняться только после завершения предыдущего. Примеры: 1. Установить сокетное соединение с сервером. Только после того, как соединение установленно, отправить hand-shake запрос. Только после того, как hand-shake подтверждён, начинать дальнейший сетевой обмен. (Вариация: сперва соединиться с login-сервером, отправить имя/пароль, получить id сессии, соединиться с game-сервером, отправить id сессии, получить список комнат, войти в комнату по умолчанию). 2. Загрузить текстуру. Только после того, как текстура загружена, наложить её на объект. 3. Показать пользователю диалоговое окно с кнопкой OK. Только после того, как пользователь нажмёт ОК, выполнять дальнейшие действия (Вариация: окно с Yes/No). Можно привести ещё добрую сотню подобных примеров. В случае, если бы были синхронные вызовы, никаких особых проблем бы не было. Действия выполняются одно за другим, никакой особой параллельности вычислений здесь не требуется. Однако все вызовы в AS только асинхронные. Вызов функции возвращается немедленно, а вот действие можно быть ещё не выполнено. Чтобы узнать, что действие завершено, необходимо подписаться на соответствующее событие. Для каждого события необходимо создать обработчик. Таким образом, вместо одной функции, мы создаём несколько функций, каждая из которых вызывается, когда завершенно предыдущее действие, и инициирует следующее действие. Возникают проблемы: 1. Код разрастается и становится не таким очевидным. Например, другой разработчик, посмотрев на такой код, может не сразу понять, в каком порядке вызываются действия. 2. Вместо локальных переменных приходиться использовать приватные поля для тех данных, которые должны быть общими для разных функций. 3. Некоторые обработчики одноразовые. После срабатывания они должны быть отключены (например, обработчик hand-shake должен сработать один раз. Дальнейший сетевой обмен никак не должен его задействовать). 4. Необходимо заранее задумываться о том, какие действия у нас "мгновенные", а какие "долгоиграющие", чтобы правильно разбивать функции на части. Попробуем всё-таки скомпоновать всё в одну функцию, чтобы частично решить проблемы 1, 2 и 3. Вместо отдельных обработчиков будем использовать вложенные анонимные функции. Для простоты возьмём такой пример: в начальном состоянии приложение ожидает, пока пользователь нажмёт первую кнопку. После нажатия первой кнопки, приложение ожидает, пока пользователь нажмёт вторую кнопку. Очень утрированный пример, но аналогия с предыдущими, думаю, вполне очевидна, зато он более нагляден в визуальном плане. Полный пример кода находиться в аттаче, приведу только самое основное: Код:
public function Main()Достоинства: 1. Действия выполняются строго по порядку. 2. В целом, имеем одну функцию, в которой чётко виден порядок действий. 3. Вложенные функции имеют доступ к локальным переменном основной функции. Недостатки: 1. Очень много "мусорного" кода, который приходиться набирать и который затрудняет чтение. Решение: изменить компилятор таким образом, чтобы весь допольнительный код, необходимый для "прерывания" функции автоматически генерировался компилятором и не присутствовал явно в исходном коде. Чтобы получилось что-то вроде такого: Код:
tf.text = "Step 0";Код:
nodes = xml.items(@data=="100");Точно так же (теоретически) компилятор может создавать за нас всё необходимое для синхронных вызовов. Но это чисто в теории и на первый взгляд. Интуитивно я чувствую, что здесь скрыто не мало подводных камней. Вот что я вижу на первый взляд: 1. Есть риск, что неособо-локальные переменные (существующие даже после завершения функции, в которой они описаны) могут вызвать утечки памяти. Или наоборот - удаление нужного объекта. 2. Этот подход хорош, когда ожидается только одно событие. Но многие действия могут завершаться с разными событиями (например - если возникает ошибка: не получилось установить соединение, файл не найден, закончился таймаут и т.д.) Поэтому, видимо, придётся сделать более сложное расширение языка. 3. Пока не проверил, как будет вести себя такая система с исключениями. 4. Потребуется разширить существующие классы, чтобы добавить синхронные методы (разумеется, никто не запрещает пользоваться асинхронными). 5. Возможно возникновение проблем, свойственных многопоточным системам. 6. Возможны проблемы с производительностью. И пока не совсем ясно, как осуществлять оптимизацию (например, как определять, когда не следует удалять обработчик, так как он ещё может пригодиться). Вот именно эти проблемы я и хотел бы обсудить. А так же - как покрасивее сделать синтаксис языка. Ну и наконец - что лучше брать за основу: AS3 или HaXe. |
Сорри, весь пост не читал, вопрос возник сразу: почему сервер шлет какие-то команды клиенту, не дожидаясь реакции пользователя? Результат выполнения чего-либо на клиенте должен быть отправлен на сервер, а тот уже решает, что делать с результатом дальше. Т.е. вот этих вот waitForClick не должно быть в клиенте, клиент логической частью не должен обладать, все решения принимает сервер. Сервер не должен быть тупым и присылать сразу очередью тучу команд логики, он должен их присылать по мере получения результатов выполнения предыдущих.
Команды, приходящие от сервера, должны отправляться в тот контроллер, который их обрабатывает. Контроллер диалогового окна может спокойно ждать реакции пользователя, а контроллер передвижения персонажа, по командам, приходящим от сервера, передвигает этого самого персонажа, совершенно не обращая внимания на то, что открыто диалоговое окно каким-то другим контроллером. На моей практике никаких проблем в реализации подобного плана клиентов на AS3 не было, не говоря уже об отсутствии необходимости реализовывать какой-то движок мультипоточности. Ну вот не вижу я ни одной причины, по которой он должен быть. |
waitForClick - всего лишь тривиальный пример.
А как тебе такое: Код:
var connected:bool = false;sock.connect() и sleep() в данном случае - синхронные методы. Попробуй написать вышеприведённый код на классическом AS3, затем сравним. ------------------------- Другой пример. В одном проекте мне необходимо было рисовать различные псевдо-3D объекты в аксонометрической проекции. Для отрисовки каждого объекта требуется одна или несколько текстур. Текстуры хранятся во внещних файлах. Разумеется, загружать текстуру каждый раз, когда он потребовалась - слишком дорогое удовольствие, поэтому я сделал кеш текстур, основной метод которого выглядел так: Код:
public static function getTexture(sPath:String):BitmapDataНо после уточнения ТЗ оказалось, что в реальной работе текстур может быть тысячи, а то и десятки тысяч. Все их загружать в память просто не реально. Поэтому надо использовать ленивую загрузку - текстура загружается только при первом обращении к ней. Но в таком случае я не могу сразу вернуть BitmapData! Ведь возможно такой текстуры в кеше ещё нет, следовательно она будет загружаться, следовательно потребуется какое-то время. Пришлось добавлять callback'и. Но мало того - пришлось полностью переделывать отрисовку объектов. Если раньше это был один метод (у разных типов объектов - свой), то теперь мне пришлось его разбивать на части, чтобы гарантировать, что текстура точно загружена. Если бы я мог сделать getTexture синхронным, то таких значительных переделок не потребовалось бы. |
Ну connect в AS3 не синхронный, начнем с этого.
Подход к текстурам неверный, поверхность должна получить адрес текстуры и все, она начнет грузить текстуру или не начнет, пусть сама решает. Если поверхность скрылась, то она может положить в общий кеш текстуру (если текстура успела загрузиться). Если поверхность скрылась, а текстура загрузилась позже, то положить сразу кеш. Кеш сам по себе очищает себя, скажем, раз в пять минут, убивая все битмапы. Вы сваливаете свою ошибку проектирования на язык, который ничем вас на самом деле не обидел. |
Из много букв, отбросив лишнее, выделил такую суть:
Цитата:
Цитата:
|
Именно!
Приведённый код - пример того, как выглядел бы код, если бы connect был синхронным. Напиши эквивалент этого кода с помощью асинхронного connect. И мы вместе почувствуем разницу. |
Цитата:
|
Цитата:
Код:
… |
Итак, во-первых - длиннее.
Во-вторых, цикл уже не так очевиден. В-третьих - порядок действий уже не так очевиден, появляется псевдорекурсия: connect может вызвать attempt, attempt косвенно вызывает connect. B это всего для двух "долгоиграющих" действий: connect и таймаут. Теперь маленькое добавление: если соединение не удалось, то показать диалоговое окно с надписью: "Connection failed" и кнопкой OK. Делать следующую попытку только после того, как пользователь нажмёт OK. Как меняется код на выдуманном языке: Код:
var connected:bool = false;------------------- Цитата:
А если другая поверхность начала загружать эту текстуру, но ещё пока не загрузила? |
Код:
… |
Итого: +1 функция (новый обработчик).
addListener в одном месте, действие, которое может инициировать событие - в другом, обработчик события - в третьем, и после этого ещё и повторный вызов connect. А теперь дальше. QA посмотрели наше приложение и сказали: что-то слишком часто сообщение появляется. Надо сделать так, чтобы сперва делалось три попытки (молча), а если они не удались, то тогда уже показывать сообщение. Между попытками пауза 500 мс. Сообщение должно теперь содержать YES и NO. Если отвечает YES, то снова делать три попытки. Код:
var connected:bool = false;Ваш ход? |
Я не играю с вами в шахматы, потому как мой ход очевиден и смысла в продолжении нет. Если вы ради сомнительного удобства собираетесь ваять конвееры и псевдомногопоточность — вперед. Но это AS way, и это не Java, в очередной раз говорю.
Вам всего навсего нужен sleep, а многопоточность тут особо и не нужна. Чего вы хотите примерами кода доказать — я не знаю. Я вам докажу, что можно без многопоточности, пусть и длиннее, но никаких проблем в понимании логики лично я не вижу. Если вы видите, то AS — не ваше. |
Я нигде не утверждал, что вообще нельзя обойтись средствами AS.
Как так раз таки наоборот - можно. Просто получается: 1. Гораздо длиннее 2. Сложнее вносить изменения 3. Порядок действий теряется, так как размазан по всему коду. 4. Нужно следовать строго определённой структуре кода. Некое единое по своей сути действие необходимо разбивать на несколько кусочков. Каждая минифункция ссылается не следующую. Иногда на одну функцию может быть несколько ссылок. Иногда одна функция может вызывать одну из нескольких других в зависимости от условий. В результате получается сложный граф вызовов. Вставить туда что-то новое или наоборот убрать требует значительных изменений в разных частях кода. Вот вы уже быстро сдались даже на таком простом примере. На практике это означало бы "won't fix, потому что всю систему ломать надо". Я ведь не зря привёл пример с E4X. Жаль, что вы не прочитали тот пост целиком. Ведь работать с XML можно и без E4X. Почему же все так фанатеют от него? Потому что компилятор берёт на себя заботу о всякой рутине. Мы пишем: Код:
nodes = xml.item.(@data="100");Мы можем легко изменять единственную строчку, а реализацию целиком возьмёт на себя компилятор. В AS3 массивы нетипизированные. Разумеется, эту проблему можно обойти: каждый раз при обращении к элементу массива явно делать преобразование типа. Но это, во-первых, добавляет множество лишнего по сути кода, во-вторых, увеличивает шанс допустить ошибку (которую компилятор обнаружить не сможет). Тем не менее в haXe массивы вполне даже типизированные. И не только массивы. И даже используются допольнительные трюки, чтобы оставить строгую типизацию даже в run-time (чтобы не тратить время на приведение типов). В AS3 нет типа enumaration, и без него вполне можно обойтись. Но в haXe он есть и позволяет многие вещи сделать короче, элегантнее и более защищённым от ошибок. Вот я предлагаю дополнительное средство языка, которое просто упрощает работу с последовательными действиями. Точно так же, как E4X упрощает работу с XML. Чисто теоретически это сделать можно - ведь, как все мы прекрасно знаем (и в данной теме ещё раз продемонстрировали), сделать на AS3 код, аналогичный коду с синхронными вызовами, возможно. Но поддерживать его гораздо сложнее. |
Я не вижу в споре (?) и в сравнении двух разных языков никакого смысла и в такие шахматы с разными фигурами и правилами с каждой стороны не играю.
В многопоточности тоже есть свои недостатки, потоки нужно контроллировать, вовремя останавливать, жрут больше памяти и т.п. Все это приводит к неменьшему количеству кода, только в других местах. И проблемы с поддержкой реализации «многопоточности» на AS3 сводят на нет преимущество в длине кода и мнимой простоте. Есть два инструмента, надо использовать каждый в своей сфере, а не пытаться сделать из одного инструмента кривую обрезанную реализацию другого ради кривой и чуждой изначальному инструменту логике. Из рубанка плохой молоток выйдет, равно как и наоборот. |
Цитата:
- Зачем нужны синхронные методы, если тоже самое можно сделать с помощью асинхронных, это же не Java? - Зачем нужен Flex, если всё то же самое можно сделать на Flash? - Зачем нужен E4X, если есть XMLDocument и можно тоже самое сделать с помощью firstChild, nextSibling? - Зачем в свою очередь нужен XMLDocument, если можно взять обычный String и самому распарсить? - Зачем нужны пекеджи и классы, у нас ведь не Java? - Зачем нужен JIT-компилятор, у нас ведь не Java? - Зачем нужны типы int и uint, если есть Number? - Зачем вообще нужно использовать разные типы, если есть *? - Зачем был нужен AS2, если тоже самое можно сделать на AS1? - Зачем нужны внешние .as файлы, если можно писать код в кадрах? - Зачем нужны классы, если объекты можно создавать и без них? А всё просто: как вы сами сказали, всему своё место. Иметь два инструмента лучше чем один - всегда можно выбрать, какой из них больше подходит для решения конкретной задачи. Вы же говорите: "У меня уже есть рубанок, зачем мне какие-то молотки?" Использовать события хорошо в тех случаях, когда порядок действий (и соответственно порядок возникновения событий) заранее неопределён и непредсказуем. Но если нужно выполнить действия строго по порядку, то события и колбеки выглядят как подпорки. Но мы может сделать более высокоуровневую конструкцию, которая спрячет от нас все эти подпорки и костыли и позволит нам абстрагироваться от них. Как E4X по сравнению с XMLDocument, как class по сравнению с prototype. Смыслом нашей "игры без правил" было: 1. Показать, что для кода с синхронными методами можно создать аналогичный код с помощью событий и колбеков (а значит, в теории, можно автоматизировать этот процес). 2. Показать преимущества синхронных методов в при решении определённого класса задач (это совсем не означает, что синхронные методы рулят всегда и везде). Правда, я проиграл. Я надеялся, что у меня всё-таки получится убедить, что синхронные методы действительно были бы полезны. Но вместо этого получил ответ в стиле: "Да зачем нам ваши классы, когда всё прекрасно делается через прототипы. Если у вас проблемы с пониманием логики, значит AS не для вас. Классы пусть останутся в Java, а здесь им не место". -------------------- Опять вместо конструктивной беседы получился спор "да зачем это надо". Где бы найти собеседников, а не оппонентов... |
Господа, давайте делать разницу между потоками и процессами.
Ява работает в одном потоке но может создать тучу процессов. Флеш же явно трудится в одном потоке. При этом псевдо многопоточность реализована просто убого - без приоритетов и пр. И закралось у меня сомнение, что запуск нескольких псевдо потоков просто убипает плеер... Соответственно флексовые ивенты и таймеры масдай! |
Цитата:
|
Этот вопрос вам лучше адресовать стоматологам где-нибудь на стоматолог.ру или ещё где-нибудь. Хотя сомневаюсь, что перед ними часто встают задачи, требующие отбойного молотка.
А здесь форум для флешеров. И я привёл примеры задач, которые часто встают перед флешерами. В том числе и у меня, но не только. Обратите внимание, что тему создал не я. Есть другая, ныне закрытая, тема, тоже созданная не мной. Есть масса попыток создания библиотек, для решения подобных задач (далеко не единственный пример: http://potapenko.com/rus/articles/conveyor.htm). Это говорит о том, что задача крайне распространённая. И синхронный вызов методов - самый простой, самый интуитивно понятный метод её решения. Это не отбойный молоток, это как раз таки современная немецкая ультрозвуковая безконтактная бормашина. Но у нас такой, увы, нет, поэтому приходится по старинке пользоваться обычной бормашиной со сверлом (ивенты, таймеры) и вздыхать, что чудеса техники есть только в Германии (в Java), а мы живём в России (в Flash) и не надо путать. |
WindWalker, ну пишите тогда на Java, а то вы как ВовкаМорковка, ходите и ноете.
Вещи, которые вам хочется, должны быть реализованы на уровне языка, а не в виде поделки. Иначе это бесполезный треп. Работать надо, а не вздыхать на тему «Вот как было бы круто, если бы была такая вещь…». Нет ничего идеального, машина не может делать вообще все за вас. |
Цитата:
Зачем вам все эти классы, типы, массивы, E4X, метаданные и прочее? gotoAndPlay, gotoAndStop - вот он настоящий флеш, всё остальное от лукавого. Так? Цитата:
Ещё раз намекаю: AS2 и AS1 - разные языки, но работают на одной и той же виртуальной машине. Код из AS2 прекрасно преобразуется в AS1. Означает ли это, что AS2 - ненужная поделка? С вашей точки зрения - получается, что так. |
Цитата:
Причем тут AS1 и кадры? Не было бы всего того, что было перечислено вам выше, я бы и писал в кадрах. Каким боком здесь многопоточность, которой нет в языке и которую вы пытаетесь криво реализовать? Я не могу применять то, чего нет, но я не утверждаю того, что не буду применять то, что уже есть. Цитата:
|
Цитата:
2. Мы уже убедились, что код с синхронными методами прекрасно переводиться в код на AS3 (в чём я в принципе и не сомневался). Вы лично выступали в роли транслятора. Осталось это лишь автоматизировать, поскольку обычно в роли транслятора приходиться выступать мне самому, а хочется свалить это на компилятор. И вот как раз таки проблемы автоматизации я и хотел бы обсудить. Но, видимо, выбрал не то место для серьёзных бесед. :( |
| Часовой пояс GMT +4, время: 16:24. |
Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.