2008年3月27日木曜日

flex3のEffectをMXMLでSequence

as3でもflex3のeffectが使える。

import mx.effects.Move;

とすれば as3で

var move:Move = new Move();
move.play([this]);

とflexのEffectを利用できる。

しかし よく使うEffectはMXMLで

<mx:Move yBy="-1" duration="50"/>

と書いた方が楽だしきれいに思う。 ただし Effectの記述は純粋にViewの記述とは言いがたいので Effect用途毎に 別ファイルとして記述したい。

そこで

<mx:Move xmlns:mx="http://www.adobe.com/2006/mxml"
         suspendBackgroundProcessing="true"
         yBy="-1" duration="50"/>

という内容でHogeEffect.mxmlとして保存すれば as3では

var hoge:HogeEffect = new HogeEffect();
hoge.play([this]);

newできる。

しかし Sequenceだとうまくいかなかった。

<mx:Sequence xmlns:mx="http://www.adobe.com/2006/mxml"
             suspendBackgroundProcessing="true">
  <mx:Move yBy="-1" duration="50"/>
  <mx:Move yBy="+2" duration="100"/>
  <mx:Move yBy="-1" duration="50"/>
</mx:Sequence>

とMXMLを記述しても (正しいはずだが) 子Effectが再生されない。 as3上でchilrenをみても空になっていた。

試行錯誤した結果

<mx:Sequence xmlns:mx="http://www.adobe.com/2006/mxml"
             suspendBackgroundProcessing="true">
  <mx:children>
    <mx:Move yBy="-1" duration="50"/>
    <mx:Move yBy="+2" duration="100"/>
    <mx:Move yBy="-1" duration="50"/>
  </mx:children>
</mx:Sequence>

と きちんとmx:chilrenで囲むと 動いた。

2008年3月26日水曜日

as3の安易なカスタムイベント

as3でイベントを起動するには、通常

this.dispatchEvent(new Event(Event.COMPLETE));

のようにイベントタイプをクラス定数で渡すという お行儀の良い方法をとる。

でもas2のようにおきらくにカスタムイベントを使いたい。 で、

this.addEventListener('hoge', this.onHoge);

として

this.dispatchEvent(new Event('hoge'));

と任意の文字列でイベントタイプを渡すこともできるが イベントタイプの識別は文字列であって どのイベントクラスの定数かまでは考慮されないので

this.addEventListener('complete', this.onComplete);

とカスタムイベントをセットしているつもりでも イベントタイプがthisの組み込みのものと一致すると 予期しないタイミングで組み込みイベントEvent.COMPLETEが発生してしまい 危険。

とにかく 安全にカスタムイベントをセットするには 組み込みイベントタイプと一致しない文字列を指定しなければならない。

そこで

public class E extends Event {
  private static const PREFIX:String = 'easy_event_prefix_';

  public function E(type:String,
                      bubbles:Boolean=false,
                      cancelable:Boolean=false) {
    super(E.t(type), bubbles, cancelable);
  }

  public override function clone():Event {
    return new E(type, bubbles, cancelable);
  }

  public static function t(type:String):String {
    return E.PREFIX + type;
  }
}

のようにEventクラスを継承したEクラスなどを1つつくっておき

イベントの登録には

this.addEventListener(E.t('complete'), this.onComplete);

イベントの起動には

this.dispatchEvent(new E('complete'));

としておけば easy_event_prefix_という接頭辞がついたイベントタイプで 受け渡しが行われるので 組み込みイベントに反応することはない。

2008年3月22日土曜日

javascript.elと[:punct:]

javascript-modeで 行の先頭が$なんかのとき インデント1つ分ずれる。

function hoge() {
  fuga();
    $('hoge').empty();
}

これは、modify-syntax-entryかなと思ったら 効かず。 javascript-mode-hookで (setq c-echo-syntactic-information-p t) するもエコーされない。

javascript.elを読むと この人はindent-line-functionを cc-modeのをつかわず 自分で実装していた。

ずれる原因は

(let ((p (parse-partial-sexp (point-min) (point)))
      (brace-p (looking-at "[{}]"))
      (continued-expr-p (looking-at "[[:punct:]]")))

(looking-at "[[:punct:]]") の部分で 表示可能な記号文字が先頭のとき 余分にインデントされるようになっていた。

(let ((p (parse-partial-sexp (point-min) (point)))
      (brace-p (looking-at "[{}]"))
      (continued-expr-p (and (not (looking-at "['$_]"))
                             (looking-at "[[:punct:]]"))))

と['$_]のときはcontinued-expr-pと解釈されないようにして 修正。

2008年3月19日水曜日

emacsでphpのインデントがずれる

ずれる。

<?php
function hoge () {

  }
?>

となる。

php-mode.el cc-*.el を読んだり debugでトレースしたりして わかったのは <?php の部分が原因のようであること。

<?php<? にすれば ずれない。

前へさかのぼってサーチしていって phpがワードで その前の?がデリミタになって バッファの先頭までいってサーチが終了し サーチが終了したひとつ前にポイントがどこだったか でインデントが決まり <?php の3文字目がそれにあたるので それまでの2文字分インデントされてしまう ということらしい。

つまり、 関数宣言部分が 本来はfunctionの頭から始まるわけだが php function となっていっていて phpとfunctionの間が改行されている と解釈されているよう。

cc-mode.el はC系の言語のことしか考えてくれてないみたいで php-mode-hook で外から変数いじっても <?php を無視するようにできそうになかった。

しかたがないので php-mode-hookで (setq indent-line-function 'my-php-indent-line) と indent-line-function を上書きして my-php-indent-lineでは

(defun my-php-indent-line ()
  (save-restriction
   (let ((here (point)))
     (if (not (search-backward "<?php" nil t))
         (funcall 'php-cautious-indent-line)
       (goto-char here)
       (narrow-to-region (match-end 0) (point-max))
       (funcall 'php-cautious-indent-line)
       ))))

と php-cautious-indent-lineする前に narrow-to-regionで <?php を 隠したら うまくインデントされるようになった。

php-cautious-indent-lineを2回書いているのが汚い。