2007/02/23

LSL 書けないのに lsl-mode

正月頃にマイミクが一名いきなり消えた。ちょとショックで他のことやろうと Second Life に参加してみた。
Second Life は仮想世界で生活し、その中で自ら 3D オブジェクトを作りそれをスクリプト(LSL)で拡張でき更にそれを売買できるというクリエーターにとって非常に面白いシステムだ。もちろん俺も興味たっぷり。

LSL は Second Life 上のエディタで編集、コンパイル、実行されるのだがコーディングは外部のエディタ+lslint という構文チェッカで行う人も多いらしく、各種エディタでそのスクリプト編集モードが用意されている。Emacs も例に漏れずあることはあるのだが色づけとインデント機能程度(しかも完璧ではない)しかない。それでは LSL の学習がはかどらないと思われるのでカスタマイズしてみた。
http://forums.secondlife.com/showthread.php?p=886077#post886077

ちなみに LSL の情報は、
http://rpgstats.com/wiki/index.php?title=Ja:Main_Page

Second Life Wiki は、
http://secondlife-wiki.main.jp/modules/pukiwiki/

ところで Real Life(RL) で人見知りが激しい自分は Second Life(SL) でも日本人、外国人にかかわらず人見知りする orz

2007/02/11

Mew の拡張ツールを作る(2)

Mew の拡張ツールを作る(1)で紹介したツール ptkbiff.pl は単なるシグナルで切り替えの出来るアニメーションツールだ(ツールというのもおこがましい程単純だが)。

ここで Mew を拡張するためには elisp 及び Mew のソースに手を染める必要がある。

ちょっと古いのだが会社都合で Mew 4.2 を元に改造を行った。Mew 5.X 系でもこの部分が同様ならそのまま適応できるかも。

さて改造の要旨だが、Mew の biff 機能で新着メールを見つける箇所と新着メールを取り込こむ箇所を見つけ、その部分に前回作ったptkbiff.pl をキックするコードを挿入しれやればよいことになる。

Mew の biff についてコードを探ると mew-biff-bark という新着メールがあるとモードラインにメール数を表示し、ビープを鳴らすファンクションがある。また、ここでは新着メールを取り込めばモードラインのメール数をクリアする機能があるようだ。

この部分にちょうど良い hook が設定されていればそれを利用してもいいのだが無い。仕方ないので elisp の「利点」を生かして、男らしくオーバーライドした。

ところで mew-biff-bark でモードラインのメール数をクリアする機能と一緒に ptkbiff.pl をキックする機能を入れると反応が鈍い。どうやらメールを取り込んだ直後に働くわけではなく、メールを確認するサイクルで取り残しメールが無ければクリアするようだ。

仕方ないのでもう少しコードを探ると直接クリアだけする関数 mew-biff-clear という関数があるではないか!これをまたまたオーバーライドすることによってことなきをえた。

ptkbiff.pl をバックグラウンドモードで走らせたうえで、以下のコードを .mew.el または .emacs に加えた Emacs を起動して Mew を走らせて初めて biff ツールとして完成する。


(setq mew-use-biff t)
;;(setq mew-use-biff-bell t)
;;(setq mew-pop-biff-interval 5)

;; mew-biff-bark OVER WRITE
(defun mew-biff-bark (n)
"Over writed mew-biff-bark"
(if (= n 0)
(progn
(setq mew-biff-string nil)
(call-process "kill" nil nil nil "-HUP" (ptkbiff-pid-read)))
(if (eq mew-biff-string nil)
(progn
(call-process "kill" nil nil nil "-INT" (ptkbiff-pid-read))
(if (not (eq mew-use-biff-bell nil)) (beep))))
(setq mew-biff-string (format "Mail(%d)" n))))

;; mew-biff-clear OVER WRITE
(defun mew-biff-clear ()
(setq mew-biff-string nil)
(call-process "kill" nil nil nil "-HUP" (ptkbiff-pid-read)))

(defun ptkbiff-pid-read ()
"ptkbiff pid read from /var/tmp"
(save-excursion
(setq ptkbiff-pid-file (concat "/var/tmp/ptkbiff." user-login-name))
(find-file ptkbiff-pid-file)
(forward-word 1)
(setq ptkbiff-pid (buffer-substring (point-min) (point)))
(kill-buffer (concat "ptkbiff." user-login-name))
ptkbiff-pid))

Mew の拡張ツールを作る(1)

Mew の拡張ツールを Perl/Tk で作ってみた。

会社のワークステーションでは随分前から Mew を使ってメールを読んでいる。Mew を使ってメールを読む上で困るのはメールが来ているか来ていないかが視覚的にわかりづらいこと。Mew にも biff の機能はあるのだけどステータスバーにそれがちょいと表示されていても気づかないことがある。

以前、この不満の解消のために biff ツールを GTK ベースで自分でつくってみたことがある。普段は適当なアニメーションをしていて、POP サーバーに新たなメールが来るとアラートのアニメーション表示をするツールだった。随分と活躍していたのだけれど社内で SSL が導入されてから役にたたなくなってしまった。SSL の実装を調べるのも面倒でずっとなにもしていなかったのだけれど、ワークステーションでメールは SSL に対応している Mew を使って読んでいるのだから Mew の機能を使わせてもらえばいいじゃないかと発想の転換をしてみた。

つまり Mew の biff 機能を横取りして新着メールがある時と新着メールが取り込まれたことをイベントのトリガーとしてアニメーションできるツールがあればよい。

アニメーション、及びイベント処理が簡単に出来そうなプログラミング言語として Perl/Tk を選択。イベントの受け渡しは単純に UNIX のシグナルを使うことにした(INT と HUP)。

そのソース ptkbiff.pl とコンフィギュレーションファイル ptkbiff.conf を以下に貼付けておく。アニメーション用の画像ファイルは適宜用意して欲しい。
実行には Perl/Tk が必要なのは言うまでもない。逆に Perl/Tk が動く環境ならほぼこのソースコードは実行できる。ま、需要は殆どないと思われるが。

あとで気づいたのだけど GIF 対応なら GIF アニメーションを使えばツール側でアニメーション機能はいらないなぁと w


--- ptkbiff.pl ----------------------------------------------

#!/bin/perl
#-----------------------------------------------------------------------------
# Title : ptkbiff
# Project : Biff
#-----------------------------------------------------------------------------
# File : ptkbiff.pl
# Author : Tatsuro Satoh
# Created : 10.02.2007
# Last modified : 10.02.2007
#-----------------------------------------------------------------------------
# Description :
#
# Animation activated by signal
#
# HUP(kill -1) activates normal animation(default)
# INT(kill -2) activates alart animation
#
# You have to put configuration file ptkbiff.conf into the same
# directory of this script.
#
# This scripts PID is saved at /var/tmp/ptkbiff.${USER}
#
#-----------------------------------------------------------------------------
# License :
# This script file is distributed under BSD licese.
# http://www.opensource.org/licenses/bsd-license.php
#-----------------------------------------------------------------------------
# Copyright (c) 2007 by Tatsuro Satoh
#-----------------------------------------------------------------------------
# Modification history :
# 10.02.2007 : add clear
#-----------------------------------------------------------------------------

use Tk;

# Check Script Path
@ptkbiff_path = split('/', $0);
pop @ptkbiff_path;
$ptkbiff_path = ($#ptkbiff_path == -1) ? '.' : join('/', @ptkbiff_path);

# Grobal Values
$iniflg = 0;
$state = 0;
%imgs = ();
@nanim = ();
@aanim = ();
$mw = MainWindow->new;
@seq = (); # sequence
$seqp = 0; # sequence pointer
$timer = 0;

&loadConfig();

# Bind Interrupt Signals
$SIG{HUP} = \&catch_hup;
$SIG{INT} = \&catch_int;

# Check PID
$pid_file = "/var/tmp/ptkbiff.$ENV{USER}";
open PFILE, ">$pid_file" or die "Cannot open $pid_file\n";
print PFILE "$$\n";
close PFILE;

# Init and Start
&InitDisp;
MainLoop;


# SUB routines
sub InitDisp {
$mw->title ("");
$l0 = $mw->Label(-image => $img)->pack;
@seq = @nanim;
$seqp = -1;
&tick;
}

sub catch_hup {
@seq = @nanim;
$seqp = -1;
&tick;
}

sub catch_int {
@seq = @aanim;
$seqp = -1;
&tick;
}

sub tick {
if ($iniflg) {
$timer->cancel();
} else {
$iniflg = 1;
}
$seqp = ($#seq == $seqp) ? 0 : $seqp + 1;

sub tick {
if ($iniflg) {
$timer->cancel();
} else {
$iniflg = 1;
}
$seqp = ($#seq == $seqp) ? 0 : $seqp + 1;
# print "$seqp\n";
$l0->configure(-image => $imgs{$seq[$seqp]->{img}});
if ($seq[$seqp]->{time}) {
$timer = $mw->after($seq[$seqp]->{time}, \&tick);
}
}

sub loadConfig {
my $cfile = "$ptkbiff_path/ptkbiff.conf";
open CFILE, "<$cfile" or die "Cannot open config file($cfile).\n";

my $section = ""; # current section

while () {
chomp;
my @s = split('#', $_);
$s = shift @s;
if ($s !~ /^\s*$/) {
if ($s =~ /\s*EndSection/) {
$section = ""; # clear section
} elsif ($s =~ /\s*Section\s+(\S+)/) {
$section = $1; # set section
} else {
@s = split(/\s+/, $s);
if ($section eq "ImageFiles") {
$imgs{$s[0]} = $mw->Photo(-file => "${ptkbiff_path}/img/$s[1]");
} elsif ($section eq "NormAnimation") {
my %animitem = (img => @s[0],
time => @s[1]);
push(@nanim, \%animitem);
} elsif ($section eq "AlertAnimation") {
my %animitem = (img => @s[0],
time => @s[1]);
push(@aanim, \%animitem);
}
}
}
}
close CFILE;
}


--- ptkbiff.conf ----------------------------------------------

# Confiuration file of ptkbiff (C) 2007 by Tatsuro Satoh

# pktbiff.pl 用のコンフィギュレーションファイルです。
# このファイルは ptkbiff.pl と同じディレクトリに置いて下さい.
#
# コメントは '#' でこの記号以降は無視されます。
#
# このファイルは ptkbiff.pl でアニメーションに使うファイルの登録と
# アニメーションの設定を行ないます。
#
# Section

# Endsection
#
# で囲まれた部分に Section TAG で示す Section の設定を書きます。


# Section TAG: ImageFiles
# 使用するイメージファイルの登録をします。
# GIF と JPEG(多分) が使えます。サイズや色に制限はありませんが、
# アニメーションの都合上それぞれの画像のサイズは合わせておいた
# 方がよいです。また表示環境が貧弱な場合も考えて色数は極力少なく
# しておいた方が無難です。
#
# 記述の仕方は
# のようにエイリアスとそれが指すイメージファイルをスペースで区切った
# ものを一行に一組合せを書き、それを列挙します。登録数に制限はありません。
# Image File は ptkbiff.pl と同じディレクトリにある img ディレクトリ
# にあるファイルを指定します。
# Alias の文字に特に制限はありませんが、正規表現のコントロール記号は
# 避けましょう。

Section ImageFiles
img0 img0.gif # normal
img1 img1.gif # close eyes
img2 img2.gif # drinking
img3 img3.gif # interesting..
img4 img4.gif # receive
EndSection


# Section TAG: NormAnimation
# 通常のアニメーション表示の設定です。
# の組合せを列挙します。
# Alias は ImageFiles で登録したイメージファイルの Alias です。
# Time は Alias のイメージを表示する時間(単位 [ms])の指定です。
# 表示は上から下の順に行なわれ、最後のイメージが表示された次には
# 再び最初のイメージを表示する自動ループ制御が行なわれます。
# Time を 0 に指定したらアニメーションを止める。。ようにしたかった
# のですがデバッグしてる Mac OS X で思い通りにならなかったので
# ほっといてます。
# また Time はあまり短すぎても無駄に CPU を使うだけなので節度ある
# 設定にしましょう。
# 根性次第で複雑なアニメーションも可能です。
# ちなみにアニメーションの時間待ち中の割り込み受付は OS に依存する
# ような感じがします。OS によっては Time 設定を長くしすぎるとその
# 期間割り込みの処理が待たされて反応が鈍くなる場合があります。

Section NormAnimation
img0 7000
img1 300
img0 7200
img1 500
img0 7000
img1 300
img0 6600
img2 1000
EndSection


# Section TAG: AlertAnimation
# アラート状態のアニメーション表示の設定です。
# 設定は NormalAnimation と同じです。

Section AlertAnimation
img3 1500
img4 1500
EndSection

2007/02/08

Mac OS X で Perl/Tk

会社用のちょっとしたツールを作ろうと思ってうちでもデバックできるように環境を整えた。
参考にした Web http://homepage1.nifty.com/alchemy/tips/perl_tcl_tk.html

インストールした時の環境
Mac OS X 10.4.8 (Intel Mac)
Perl 5.8.6
gcc 4.0.1
Tk module Tk804.027

Tk module は CPAN から、
http://www.perl.com/CPAN/modules/by-module/Tk/
以下の
Tk-804.027.tar.gz
を持ってきてコンパイルした。

% perl Makefile.PL;make;sudo make install
でインストールはあっさり完了。

ちなみに参考にした Web に書いてあるとおり Mac OS X 10.4(Tiger) には Tcl/Tk Aqua が既にインストールされていた。

インストールの確認で以下のコードを実行。Terminal からでは実行できないが、X11 の xterm からは実行できる。

#!/usr/bin/perl

use Tk;

my $mw = MainWindow->new;
$mw->title ("Hello World");
$mw->Button(-text => "Done",
-command => sub {exit})->pack;
MainLoop;


UNIX 系のツールを使おうとするときは Mac OS X のありがたみを感じる。
まぁ、コンパイルがすんなり通らずに苦労することもあるけどね。