AS2 магия

Сегодня ко мне в аську обратился Алексей «Vooparker» Аникутин с проблемой подгрузки swf-роликов, скомпиленных через mtasc. Дело в том, что mtasc вызывает статический метод main() основого класса приложения, не передавая никаких параметров, содержащих ссылку на таймлайн клипа, в котором, собственно, и содержатся сами классы. Т.е. единственный вариант аттача клипа — в _root. Тут же возникает проблема подгрузки таких роликов: _root ссылается на таймлайн родительского клипа, а не загруженного. В итоге работоспособность флешки нарушается.

А как же _lockroot, скажете вы? Да, его можно использовать, но только непосредственно в клипе-загрузчике, что не подходит под условия задачи. Необходимо включить _lockroot изнутри загруженного клипа. Как это сделать? Читайте далее.

Решение оказалось неочевидным, нетривиальным и совершенно не поддающиеся никакой логике:

This content requires Adobe Flash Player.


Типичный входной класс для mtasc. Будучи загруженным, такой ролик верно определяет свой _root.

Как работает?
Точного ответа я дать не могу. Начнем с того, что eval(eval('_target')); не заработает, будет ошибка there is no property with the name '_target'.

eval(targetString) возвращает строку (!) "/". Но при этом, если мы захотим использовать что-то вроде:


var root:String = '/';
var target:MovieClip = eval(root);

То это не будет работать, вернется ссылка на _root родительского клипа, он же _level0. Именно здесь проявляется магия eval(targetString), который возвращает магический String, eval которого дает нам ссылку на таймлайн загруженного клипа, а не _root родительского.
Далее просто включаем _lockroot, либо используем полученный target в своих целях.

Каким образом было получено данное решение?
Методом тыка. В основе сего действа лежит знание того, что инициализация классов происходит в клипах. В результате экспериментов получился сей работающий код. Да, это грязный хак, но работать оно не перестанет.

Буду рад, если кто-нибудь расскажет с научной точки зрения, почему это работает.

11 Responses to AS2 магия

  1. ээээ
    эм.. я не совсем понял смысл этих приседаний

    /**
    * @param container reference to _root
    */
    public static function main ( container: MovieClip ): Void {

    }

  2. magius, откуда у тебя эти данные? =)

  3. Упоминания об этой тонкости нет в русскоязычном MTASC FAQ, но оно просто обязано быть там! magius, спасибо за наводку.

  4. Спасибо. Вчера весь вечер потратил на поиск решения с вызовом main с переданной ссылкой на клип. Официальная дока партизански промолчала про эту возможность.

  5. Тем не менее, магия имеет место быть :)
    Я, честно говоря, mtasc не пользовал и документацию к нему не читал :D

  6. мда… век живи век учись :)

  7. Шаманы…

  8. >>Буду рад, если кто-нибудь расскажет с научной точки >>зрения, почему это работает.
    Вы ведь сами сказали, в чем она :)

    “статический метод main() основого класса приложения, не передавая никаких параметров”
    Почему не написать разработчику, и показать свой код… интересно, что он скажет…
    http://tech.motion-twin.com/contact.html

  9. Да нет, разработчик mtasc тут непричем. Я сам mtasc-ом не пользовался и документацию к нему не читал. Просто поверил на слово, но оказалось, что он все таки передает в параметрах ссылку на нужный таймлайн, просто это явно не было указано в FAQ или хелпе.

    А вот мой хак работает независимо от компилятора. Вопрос касался именно данного момента, почему эта конструкция вообще заработала и работает.
    В этой конструкции много неясностей, она работает ровно в таком виде, в котором написана и никак иначе.

  10. Pingback: Garbage Collector » Архив » MTASC FAQ

  11. [голосом доктора зойдберга] ура! я пригодился! :)

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>