IronScheme を使ってみた

C# から手軽に Scheme のコードを呼び出したくて。


IronScheme をインストールした後、.NET なプロジェクトに IronScheme.dll と IronScheme.Closures.dll を参照設定に追加すれば一通り使えました。

using System;
using IronScheme;
using IronScheme.Runtime;

static void Main(string[] args) {
    Console.WriteLine("(+ 1 2)".Eval()); // => 3
    Console.ReadKey();
}

あっけなく。


次に Scheme 側の手続きを C# で呼び出してみます。

"(define (add-one-func i) (+ i 1))".Eval();
var addOneFunc = "add-one-func".Eval<Callable>();
Console.WriteLine(addOneFunc.Call(0)); // => 1
Console.WriteLine(addOneFunc.Call(5)); // => 6
Console.WriteLine(addOneFunc.Call(10)); // => 11

あっけなく。


最後に C# 側の関数 (Func) を Scheme で呼び出してみます。

int i = 0;
Func<int> incrementFunc = () => i++;

"(define increment-func {0})".Eval(incrementFunc.ToSchemeProcedure());

が、no expression in body と怒られてしまいます。
IronScheme の Eval() が悪さをしているっぽいのですが (引数で渡したオブジェクトがいったんシンボルになってる)、Scheme レベル 0 なのであんまり深く追っていません。

"(define increment-func '())".Eval();
"(set! increment-func {0})".Eval(incrementFunc.ToSchemeProcedure());
Console.WriteLine("(increment-func)".Eval()); // => 0
Console.WriteLine("(increment-func)".Eval()); // => 1
Console.WriteLine("(increment-func)".Eval()); // => 2
Console.WriteLine("(increment-func)".Eval()); // => 3

とすると、とりあえず動きました。


他にも、

foreach (var val in "'(1 2 3 4 5)".Eval<Cons>()) {
    Console.WriteLine(val);
}

のように、Cons が IEnumerable だったりして面白いです。


IronScheme 自体の初期化が重いのが難点ですが、常駐系のアプリであれば結構使えそうです。

Vista, 7 以降の環境で LR2 をリフレッシュレート 120Hz で動かす方法 (GeForce, RADEON 共通)

LR2 に限らず、リフレッシュレート 60Hz で固定されてしまうのをなんとかする方法です。
XP 時代はグラフィックカードのドライバからリフレッシュレートの固定ができたのですが、Vista 以降のドライバからは軒並み削除されているようです (DX10以降のアプリケーションが、外部からのリフレッシュレート強制変更にそもそも対応しないようです。MS方針?)。
そのような事情もあり、DirectX9 世代のアプリケーションにしか効果はありません。


昔は dxdiag でリフレッシュレートの固定ができていましたが、今はありません。
というわけで、レジストリを弄ってしまいましょう。


32bit の場合 (と、64bit の場合のネイティブ 64bit アプリ向け)
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\DirectDraw に ForceRefreshRate (DWORD) を作成。値は固定したいリフレッシュレート。


64bit の場合の 32bit アプリ向け (LR2 の場合はこちら)
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\DirectDraw に ForceRefreshRate (DWORD) を作成。同上。


レッツぬるぬる!

Pure Javascript な jQuery Templates

Web プログラミングを行う場合、さまざまなテンプレートエンジンを使うことになると思います。
ただ、サーバサイドなテンプレートエンジンだと、ajax バリバリなページを作る場合に DOM との相性が悪く、冗長なコードになりがちです。(なりますよね?)


というわけで、Javascript なテンプレートエンジン、jQuery Templates を使ってみましょう。
jQuery Templates は現在β版で、 jQuery 1.5 にマージされるはずだったのですが、結局 1.5 には入っていないようです。
ダウンロード・ドキュメントはこのページから。
http://api.jquery.com/category/plugins/templates/


百聞は一見にしかずということで、簡単に書いてみます。

<script id="tmplUser" type="text/x-jquery-tmpl">
<li>${name} (${age})</li>
</script>

<ul id="users">
</ul>
$(function() {
    var users = [
        { name: 'foo bar', age: 20 },
        { name: 'hoge fuga', age: 30 }
    ];
    $('#tmplUser').tmpl(users).appendTo('#users');
});


ね、簡単でしょ?
.tmpl に配列を渡すと、自動的に複数のテンプレートに展開してくれます。


さて、ここまでは序の口。
次はテンプレートからテンプレートを呼び出します。

<script id="tmplUser" type="text/x-jquery-tmpl">
<li>
    ${name}
    <ul>
        {{tmpl(items) "#tmplUserItem"}}
    </ul>
</li>
</script>
<script id="tmplUserItem" type="text/x-jquery-tmpl">
<li class="item">${name}</li>
</script>

<ul id="users">
</ul>
$(function() {
    var users = [
        {
            name: 'foo',
            items: [
                { name: 'ひのきのぼう', power: 2 },
                { name: 'ラグナロク', power: 10000 }
            ]
        },
        {
            name: 'bar',
            items: [
                { name: 'エクスカリパー', power: 1 },
                { name: 'エクスカリバー', power: 10000 }
            ]
        }
    ];
    $('#tmplUser').tmpl(users).appendTo('#users');
});


ね、簡単でしょ?
さて、この謎のアイテムをクリックすると、power を alert するようにしてみましょう。
変更箇所は Javascript の最後の行だけです。

$('#users')
.delegate('.item', 'click', function() {
    var item = $(this).tmplItem();
    alert(item.data.power);
})
.append(tmpl)
;


ね、簡単…ですよね?
テンプレートごとに割り振られた値を $(this).tmplItem().data で取得できます。
ここでは {{tmpl(items) "#tmplUserItem"}} により、items が(勝手に)展開され、1つ1つのアイテムが取得できているかんじです。


また、tmpl() を実行した結果は jQuery object ですので、append する前にごちゃごちゃと操作することもできます。

var tmpl = $('#tmplUser').tmpl(users);
$('.item', tmpl).click(function() {
    var item = $(this).tmplItem();
    alert(item.data.power);
});
tmpl.appendTo($('#users'));


(続きはそのうち書く)

jQuery slideUp() で IE8 だけ margin がぶっ壊れる問題が釈然としないけど治った

IE6でさえも正常に動作するのに、IE8でだけ発生する問題。
アニメーション完了の callback で、margin がぶっ壊れる要素を編集しなおすと margin が帰ってきた。なんだそれ!


さんぷるこーど。

var dt = $('#hoge dt'); // margin がぶっ壊れる要素
var dd = $('#hoge dd'); // slideする要素

dd.slideUp(500, function() { dt.html(dt.html()); });

SC-02B カスタムカーネル + z4control 導入記

カスタムカーネルは某所に上がってる initramfs に手が加わっていないほう (1.2GHz OC + 330MB RAM + BLN + その他)。
ファームウェアはオリジナル版 (JJ1) です。
最初何も考えずに Odin3 でやきやきしたら、z4mod で /data を ext2 化したことをすっかり忘れてて起動しなくなったのでちょっと焦ったり。


z4mod (apk版) からカーネルパッチを当てようと思い、パッチを当てて再起動すると、カーネルが元に戻ってまたもや焦る。
z4mod でパッチされたカーネルが z4mod 内に残ったままで、既にパッチ済みカーネルをダウンロードしたものと思い込まれており、オリジナルカーネルにパッチ当たったものが適用されていただけでした・・・
Patch Kernel と Flash Kernel は違うゾ!(あたりまえ)
ちなみにリカバリイメージからまるごと初期化した後でも、Titanium で復元したら同じことが言えるので注意してください。
z4mod をアンインストール→インストールするか、(たぶん)アプリケーション管理から設定を削除することで消えると思います。


z4control は /data, /dbdata, /cache を ext2 化してみました。
この状態で Quadrant が2000程度です。ベンチスコアでは OCLF にはかないませんね。
BLN も正常に動作していました。


カスタムカーネルで z4mod を使う場合、やきやきする前に z4mod Kernel Patcher でパッチを当てて、それをやきやきしたほうが手間が省けて良いと思います。

Galaxy S で /system の容量が足りないとお嘆きのあなたへ

こんにちは、フォントやら framework やらを弄りまくると /system の容量が少なくて泣ける cryks です。
以前の記事では /system 以下にリネームバックアップしてましたが、そんなことをすると /system の空き容量がマッハです。


そんなわけで /data に移し替えましょう。


取り立てて説明するようなものでもないですけど、framework-res.apk を例に。
あ、書いてある内容に責任は持てませんのでうんぬんかんぬん


以下起動中
> adb push framework-res.apk.customized /sdcard/
> adb shell
$ su
# cd /data
# mkdir framework
# chmod 775 framework
# cd framework
# cp /sdcard/framework-res.apk.customized .


以下リカバリモード、rageagainstthecage で rooted 前提
z4mod でカーネルパッチを当てている場合は、/system が ro でマウントされますので、rw で remount してください。
> adb shell
# cd /system/framework
# mv framework-res.apk framework-res.apk.original
# ln -s /data/framework/framework-res.apk.customized framework-res.apk


/data はリカバリモードでは見えないので、/data に突っ込むのは通常起動中である必要があります。
また、リカバリモードの wipe を選ぶとえらいことになるので、そのときはバックアップを復活させてください。


(2010/12/31 追記)
/data がリカバリモードで見えないのは、z4mod で mmcblk0p1 が ext2 になっている場合です (リカバリモード時に ext2 モジュールが読み込まれないため)。
rfs のままの場合は見えているかもしれません。もしくは、適切な mount コマンドを叩けばマウントできるかもしれません。未確認。
OCLF で lagfix している場合は諦めてください。

ドコモ版 Galaxy S (SC-02B) でバッテリーアイコンを変更する

バッテリーに限らず、要は framework-res.apk を弄る方法です。
私はこれで動いていますが(動いているように見えるだけかも)、必ずバックアップは取ってください。


必要なのは、オリジナルの framework-res.apk と、Apk Manager と、バッテリーアイコンの xml/png ファイルです。
Apk Manager は各種ツールを持っていれば必要ありませんが、これ1つで apk の逆コンパイル・コンパイルなどが出来るので、持っていて損はないと思います。
バッテリーアイコンは
http://forum.xda-developers.com/showthread.php?t=724778
ここからダウンロードしました。私は Version I を使用しました。
Post #2 にある Source Zip Files からダウンロードしてください。


Apk Manager の place-apk-here-for-modding ディレクトリに、オリジナルの framework-res.apk を突っ込みます。
Script.bat を起動し、プロジェクトを選択、Decompile を選択します。
projects ディレクトリに展開されますので、ダウンロードした zip の中にある drawable ディレクトリと drawable-hdpi ディレクトリの中身を projects の中のしかるべき場所にコピーします。
zip には drawable-hdpi-v4 というディレクトリで保管されていますが、中身は drawable-hdpi に入れて大丈夫です。


次に Compile です。
2回質問が出てきますが、両方とも y を選んでください (ちゃんと質問の中身も読んでおいてね)。
2回目の質問の後にキー入力待ち状態となり、Apk Manager のディレクトリに keep ディレクトリが現れます。
要はこの keep ディレクトリに残っている物はそのまま使い、入っていないものを projects から上書き圧縮するような感じになります (ちょっと違う気がする)。
というわけで、上書きしたファイルを keep ディレクトリから消していくのですが、ファイルをちまちま消すのはめんどくさいですね。
projects で上書きコピーしたように、keep でもいったん上書きコピーし、更新日時でソートかけてまとめて削除するほうが漏れが無くて良いと思います。
あと、Apk Manager の注意書きの通り、xml を変更しているので resources.arsc も削除します。
適当にキーを叩けばコンパイルされます。


Sign は必要ありません。完成です。
place-apk-here-for-modding ディレクトリにコンパイルされた apk ができあがっていますので、適当にファイル名を変えて導入して終わりです。


(2010/12/31 追記)
この手法はもちろん Mobile なんちゃらの謎文字列にも適用できます。
デコンパイル→謎文字列の作業→コンパイル→keep は resources.arsc を削除するのみ、でOKです。