2009年4月28日火曜日

mozilla firefox plugin sdk まだ続く

 前回のサンプルコードを眺めていて、これじゃ、HTML上に複数インスタンスを置けないよなぁ?と、いう事で、複数インスタンスに対応してみる事に…。すると、描画がおかしい。いろいろと突っ込んでみて、わかった事。
  • 基本的な事ですが、wglMakeCurrent( hDC, hGLRC ) から wglMakeCurrent( NULL, NULL ) までがインスタンス毎に排他的に行われる必要がある。
  • Google Chrome が WM_PAINT メッセージをまともによこさない。WM_ERASEBKGND メッセージで代用しているのか?
  • Google Chrome は、WM_NULL メッセージをタイマーのように送信している。
  • Firefox のスクロールバーで移動後の再描画メカニズムがおかしい。WM_PAINT が呼ばれているようなのだが、その後にウィンドウ領域をクリアしているのか?領域計算がおかしくて WM_PAINT をよこさないケースがあるのか?原因が特定できないけど、描画されない場合がある。
 最初は、Google Chrome 行儀悪りーと思っていたが、WM_ERASEBKGND メッセージ時にも描画処理を行えば対処が可能な Google Chrome の方が御し易い。アニメーションしない Flash は、スクロール・バーでスクロールさせると白く抜ける現象を起こしたりしないのかなぁ?という疑問が…。

2009年4月27日月曜日

来たー!!!

 もうじきゴールデン・ウィークですね。私の方は、暦どおりの休みの予定です。まぁ、そろそろゴールデン・ウィークに備えて本を買いだめする時期ですよ…と、今日は物色していて、軽めのこんな本を買いました(ゴールデン・ウィーク前に読んでしまいそうで怖い)。

 こちらは、茂木先生の本ですが、脳の活用法マニュアルは無いけれども、脳の活用法マニュアルたらんという自分の仕事に対するアイデアを際立たせるためには?というミクロな視点にたった書です。って、まだ読んでねぇけどさ…
 こちらは、勝間先生の本です。脳活用法と違って、今度はマクロな視点にたって、自分の今の立場を見つめ直してみようと思います。
 今度は、ブルーバックスの本で、著者は複数みたいです。アルゴリズム・ブームみたいですが、ストーリがわかると、理解度も深まるのではないか?と思いチョイスしてみました。

 本屋は大きい方が品揃えが良いので紀伊国屋とかに行ってしまうのですが、札幌駅中の弘栄堂書店には多分、本好きの店員さんが居て、おまえはこれを読めと言わんばかりに本が並べてあります。こういう本屋さんには、ついつい足が向いてしまいます。そこで、ダン・ブラウンのフェアをやっていて、思わず買ってしまいました。
 と、家に帰ってしばらくすると、嫁さんが「そういえばAmazonから何か来てたよ」と渡された・・・

うひょーーーー来たーーーーー来たでーーーーーー!

mozilla firefox plugin sdk 続き

 とりあえず、CodeProject のサンプルを作成してみたら、アッサリと動いて拍子抜けした。WM_LBUTTONDOWN をハンドリングして、theta の値を反転させると、三角形が逆周りになった。ウィンドウ有りのプラグインは、JavaScript のイベント等とは全く関係なしに動作できるようだ。
 で、サンプルを動かしていて気が付いたのだが、おめぇー、よく見たらFirefoxじゃなくて、Chromeやんけーーーーー!どうやら、Google Chrome はFirefoxのプラグインもそのままパクっているようです。
 調子に乗って、JavaScriptable なサンプルを動かしてみたが、今度は Firefox では動作するものの Chrome では動作しない…。V8エンジンっすか…。という事で、両方をインプリメントしようと思ったら Nixysa を使わないといけないようだ。しかし、このnixysaって、はっきり言うと、ドキュメント無ぇし、使いにくいんだよ。

2009年4月26日日曜日

ubuntu 9.04 インスコ

 家の環境の Ubuntu 8.10 は、無線Lan が使えないままだった(4965agnドライバをコンパイルしてインストールしても、全く認識せずにお手上げ)ので、喜び勇んでアップグレードしました。
 まぁ、8.04 の状況に戻っただけ…。無線Lanは認識するようになったけども、相変わらず DHCP で失敗する。いじりすぎたので、今度クリーン・インストールでもしてみようかと思う。その前に WICD を試すと思うけど・・・。
 ちなみに、世界中からワッとアップグレードしているためか、アップグレードのダウンロード作業には6時間ほどかかりました。

追記:アップグレードしたUbuntu 9.04 に WICD を入れてみましたが、無線LANの4965agn は繋がりません。しょうがいないので、Ubuntu 9.04 をクリーン・インストールしてみましたが、繋がりません。
# iwpriv wlan0
とコマンドを打ってみましたが、priv コントロールが無ぇーと怒られます。え~っ?8.04 の初期状態に逆戻り?今度は、wifi-radar でも入れてみるか?

mozilla firefox plugin sdk 備忘録

 選択肢は、JavaScript, Flash, Silverlight と、いろいろあるのだが、結局O3Dのような事をやろうと思ったら Native しか選択肢が無さそうなので、ぐるりと一周して plugin という話に落ち着いた。ブラウザの選択肢としての IE は既に重要視していない。ActiveX コントロールの開発はバリバリ可能ではあるが、後でどうにでもなるや・・・という事で、plugin を突っ込むことに・・・。つか、今時、独自仕様での開発(=ActiveX, Direct3D)はパスしたいところだ。

 材料
  インストール
  まぁ、展開するぐらいで、特に何もない。Gecko SDK は、c:\libs\xulrunner-sdk というフォルダに展開するものとする。

 プラグインのサンプルのコンパイル
     mozilla/modules/plugin/tools/sdk/samples/simple 
 にあるサンプルをコンパイルする。

  1. npsimple.dsp ファイルをサクラ・エディタで開く
  2. 編集・全て選択
  3. 編集・CRLF改行でコピー
  4. 編集・貼り付け
  5. ファイル・上書き保存

  1. Visual Studio で開く
  2. ツール・オプション・一番上のプロジェクトおよびソリューションにて、以下を設定
  include = C:\Libs\xulrunner-sdk\include
  include = C:\Libs\xulrunner-sdk\sdk\include
  lib = C:\Libs\xulrunner-sdk\lib
  lib = C:\Libs\xulrunner-sdk\sdk\lib

  1. plugin.h から、pluginbase.h を開く
  2. pluginbase.h から、npplat.h を開く
  3. include の順番がおかしいので下記のように修正する。


/**************************************************/
/* */
/* Windows */
/* */
/**************************************************/
#ifdef XP_WIN
#include "windows.h"
#endif //XP_WIN

#include "npapi.h"
#include "npupp.h"

  1. ソリューション・エクスプローラのnpsimple からプロパティを開く
  2. ビルド・イベントのビルド前イベントに下記のコマンドを追加する


xpidl -m header -Ic:\Libs\xulrunner-sdk\sdk\idl nsISimplePlugin.idl
xpidl -m typelib -Ic:\Libs\xulrunner-sdk\sdk\idl nsISimplePlugin.idl

以上

ダメージ

 自転車通勤のダメージが抜けません・・・。腰と背筋と肩周りの筋肉がほぐれなくて、ぐったりしてます。中途半端に休むと筋肉がほぐれないです。まだ、肩が重たい・・・。

2009年4月24日金曜日

いろいろ

 困ったときには、このタイトルで(^_^;

 巡回セールスマン問題の新しい実装、終了した。でも、まだウェブの方は調整中です。

 新人プログラマーがプロのプログラマーとして独り立ちするための7つの条件・・・すみません・・・謝っときます。ここんところ、リソースが足りないが口癖です。実際、足りません。ほんと足りません。どうにもなりません。身の回りの整理整頓ができません。orz...。1.は表現が違うような気もしますが、真実をついてます。今の技術がどこまで通用するか、いつ廃れるか?は、絶えず考えてます。

 自転車通勤、良いです!健康的です。しかし、帰ってきたら脱力してぐったりです。運動した方が頭の回転も集中力も高まる気がします。

 C|C++のライブラリが貧弱なのは認めます。しかし、一昔前に比べたら、今は天国です。

 「新日本紀行ふたたび」と「WALL-E」買いました。うちの坊ちゃん大興奮です!

2009年4月23日木曜日

巡回セールスマン問題を解く(6)

 ウェブ・サーバのマシン(6万円)を投資してもらいました。Quad Core でメモリ4G、ただしディスクはHDDでSDDではありません。おかげで一台で処理してもマシンが悲鳴をあげる事は無くなりました。
 あと、ノード間の経路を一度に計算して巡回セールスマン問題用に流用するように改造を加えましたが、肝心のPHP側のプログラムがそちらに対応していないので、今はまだ、ばか正直に40点あれば40回経路を計算してます。それと同時に、一方通行もまじめに考慮するように修正しました。
 新しい方式のルーチンをPostgreSQL用に実装中です。Windowsのアプリケーションでは安定して動作するのですが、plpgsql として実装したものは、divided by zero の Floating Point Error でお亡くなりになるため、まだまだデバッグが必要な段階です。このルーチンを実装し終わったら、札幌市内にランダムで100箇所を生成し、実際の道路データを使用して数秒で巡回セールスマン問題を解くデモサイトを構築しようと思います。
 また、北海道には市場が無く、何を作っても無駄でプロダクト・アウト(マーケット・プルではないという意味)と、痛烈な批判を浴びるので、PHPでサービスAPIを作成して公開する予定です。しかし、サービスAPIを作成しても、データは東北と北海道しか無いので、地域は限定されると思います。プロダクト・アウトもできないで、マーケット・プルもくそも無いと思うのですが、地方はそれだけ厳しいです。

2009年4月22日水曜日

subversion Cannot accept non-LF アホかい

 今日 svnsync のコマンドを実行してたら、

svnsync: Cannot accept non-LF line endings in 'svn:log' property 

つうエラーが出る。調べてみたら、こんなのが・・・。アホか?
svnsync のバージョン 1.6.1 を使ってはいけない。1.5.6 ぐらいに留めとけ。
どっかで、git に乗り換えろというお告げか?

2009年4月21日火曜日

OracleのSun買収

 まあ、度肝を抜かれたのは間違いない。IBMじゃなかったのかよっ!と突っ込みを入れてしまったぐらいだ。Oracle の目当ては、MySQL だったのか・・・にしては、高い買い物のような気がしないでもない。オープン・ソースの中では、多分、一番人気の MySQL だが、私は毛嫌いしている。GPLというライセンスもさることながら、Windows で利用しようとしてみて、あまりの品質の低さに手の施しようもなく呆れたからだ(その時の結論は、タダより高いものは無い、業務としては使えません)。その数年後にオープンソースはバグだらけという指摘を受けて、あっという間にバグが修正されてからの MySQLは知らない。モジュールの分離性により、それぞれの専門分野を生かしやすい設計(と、私は思っている)の PostgreSQL がOracleに買収されませんように…と祈りたくなった。でも大口スポンサーって、SUN じゃなかったっけか?嫌な予感がするぞ・・・。Winner takes all. なんですかねぇ?
 Java も OpenOffice に変化は無いような気もするが、StarSuite の行方は何処へ?

 
 

2009年4月20日月曜日

御立 尚資 先生の本

 ワールド・ビジネス・サテライトのコメンテイタである御立先生ですが、私の専門分野であるITに対して的確な意見を持っているだけでなく、自分が考えもしなかったような事までコメントされていて、凄いな!と感じました。そんな御立先生の書いた本なら読んでみたい!という動機で読んだのが、この2冊です。
 (戦略「脳」を鍛える)と(使う力)です。
 戦略「脳」を鍛えるの方は、御立先生のコンサルタントとしての思考方法を説いた本で、ノウハウを公開してもコンサルタントとしての自分の地位はゆるがない!という自信を持って書かれたもので、読めば世界が広がると思います。
 使う力の方は、得た知識をどのように生かすか?について書かれたもので、人の動かし方など内容もユニークです。戦略「脳」を鍛えるの続編という感じですが、こちらも面白いです。

自転車通勤

 今までの通勤時間と自転車での通勤時間は、変わらなかった…。
  1. 家から駅まで徒歩12分
  2. JRで17分
  3. 駅から会社まで15分
  4. 待ち時間ロス10分(帰りは20分)
     合計 44分

 に対して、行き45分、帰り50分でした。走行距離は、およそ12km。
さすがに、今日は、腕にきました・・・。全身もだるい。明日は幸い雨みたいなので、休養と読書も兼ねてJR通勤にしたいと思います。うぉーーーー、メタボも解消するZe!

2009年4月19日日曜日

そして筋肉痛

調子こいて自転車を漕いだら、全身がだるく、特に背筋にきた…。Twitterっぽいけど、ま、いいか…

2009年4月18日土曜日

自転車を買った

 雪も融けた事だし、時期的にもちょうどいい。という事で、昨年の12月に廃車した車の車検代は自転車代へと変身しますた。ビアンキ・パッソ!かっこいいー。月曜日からは、こいつで通勤するのだ!

手前に写っているのは、うちの4歳の坊ちゃんの自転車。同時ゲットです。


追記:Haloscan で Trackback に失敗するから諦めてたら、2重トラバをうっちゃってるよorz...。えー、40x のステータスコード返ってたのに、そんなのありかよ?

にんじん


 レンタカーを借りて、遊びの師匠のところへ「にんじん」を掘りに行ってきました。お昼は、いし豆さんの「そば」。うまかった。

レンタカー

 本日は、車無し生活に突入してから、始めてのレンタカーです。実際に借りてみると、いろいろと考えるものがありました。
 自転車があれば、自転車に乗ってレンタカー屋さんまで駆けつけて、自転車を置いたまま自動車に交換して…というスタイルを取れるなーと考えていたら、放置自転車を貰い受けてレンタル会員に入会する時に希望者には自転車を配るという手もあるかな?とか、
 これだけ格安のレンタカーが可能なのは、中古車をうまく活用しているからで、実際には次の考えが直ぐに売り上げに繋がるとは思えないけれども、所有しない車の使い方としては、TPOに応じて車を選ぶという傾向が強くなるので、自動車会社は、こういう市場を睨んで、もっと尖がった車を作っても良いのではないかな?というもの。

2009年4月17日金曜日

FTGL de Orientation

 FTGLがオリエンテーションとフォント・アライメントに対応していなかったので、XY平面上ながら書いてみました。



#define FT_V_MASK 0xFF00
#define FT_V_TOP 0x0100
#define FT_V_CENTER 0x0200
#define FT_V_BOTTOM 0x0300

#define FT_H_MASK 0x00FF
#define FT_H_LEFT 0x0001
#define FT_H_CENTER 0x0002
#define FT_H_RIGHT 0x0003

#define PI 3.14159265

template <typename STR, typename FONT>
void AlignedRender(
FONT& font,
STR* text, int text_len,
FTPoint pos, //!< position
FTPoint spc, //!< Spacing
double ang, //!< Orientation angle
int alignment //!< Font alignment
) {
FTBBox box = font.BBox( text, text_len );
FTPoint sp = box.Upper() - box.Lower();
double offset_x = double();
double offset_y = double();
switch( (alignment & FT_V_MASK) ) {
case FT_V_TOP: offset_y = sp.Y(); break;
case FT_V_CENTER: offset_y = sp.Y() / 2.0; break;
case FT_V_BOTTOM:
default: {}
}
switch( (alignment & FT_H_MASK) ) {
case FT_H_RIGHT: offset_x = sp.X(); break;
case FT_H_CENTER: offset_x = sp.X() / 2.0; break;
case FT_H_LEFT:
default: {}
}
double cpar = std::cos( ang / 180.0 * PI );
double spar = std::sin( ang / 180.0 * PI );
double xx = cpar * offset_x - spar * offset_y;
double yy = spar * offset_x + cpar * offset_y;
offset_x = pos.X() - xx;
offset_y = pos.Y() - yy;
glTranslatef( offset_x, offset_y, 0.0 );
glRotatef( ang, 0.0, 0.0, 1.0 );
font.Render( text, text_len );
glRotatef( - ang, 0.0, 0.0, 1.0 );
glTranslatef( - offset_x, - offset_y, 0.0 );
}

2009年4月16日木曜日

クラスの設計について

 隊長のブログで過猶不及也と出ていたので、設計について書いてみます。
 自分は、保守的です。C++ が出た時も、class なんているのかいな?と懐疑的でした。template が出た頃には、なんじゃこれ?どこの世界の言語やねん…と思ってました。自分の中の設計に対する考え方にも変遷があります。
 一時期は、オブジェクト至上主義的な考えに染まっていました。その時は純粋仮想継承と多重継承を使いまくりで、いかにオブジェクト中に共通部分があり抽象化できるか?に命題を見出していたように思います。その頃のブームは、「プログラムデザインのためのパターン言語」だったでしょうか?この頃は型による条件分岐にも入れ込んでいました。多重継承を駆使し、is-a の関係から処理を行うのです。擬似コードは、こんな感じです。

foo* pFoo = dynamic_cast<foo*>(pBar);
if( pFoo ) {
hoge( pFoo );
}

しかし、これは良い設計ではありません。それに、多重継承で、いろいろと武装していくと、後の設計変更に弱いのです。まぁ、パターンに溺れていたように思います。パターンなんて、たいして重要ではないのです。
 今は、オブジェクトよりも関数単位のメタな指向がいいなぁと感じています。一番好きなパートは、「Exceptional C++ Style」の37. 一枚岩 string の崩壊「過度にモノリシックな設計を避けよう」の節です。何でもクラスの中に隠蔽してしまうのは設計変更に弱く、メンテナンス性も低いし、再利用しずらいです。
 では、どうすれば良いか?実は、私も未だ旅の途中…。今は、クラス間の疎結合を目指す感じで書く事が多いです。そのためなら、ダック・タイピングも厭わない。コール・バック関数を使う局面も、昔よりは増えてきたような気がします。

OpenGLで日本語フォント

 できれば車輪の開発は避けたいところである。で、プラットフォームに依存しない形のものがないか探してみたら、あった。
  FTGL

 とりあえず、Windows で構築。ftgl_demo の SimpleDemo にて、


glPushMatrix();
glMaterialfv(GL_FRONT, GL_AMBIENT, front_ambient);
glColorMaterial(GL_FRONT, GL_DIFFUSE);
glTranslatef(0.0, 0.0, 20.0);
glRotatef(n / 1.11, 0.0, 1.0, 0.0);
glRotatef(n / 2.23, 1.0, 0.0, 0.0);
glRotatef(n / 3.17, 0.0, 0.0, 1.0);
glTranslatef(-260.0, -0.2, 0.0);
glColor3f(1.0, 1.0, 1.0);
//font[fontindex]->Render("Hello FTGL!");
font[fontindex]->Render(L"こんにちわ FTGL");
glPopMatrix();



2009年4月13日月曜日

NOMINMAXの呪縛

 あのなー、いい加減 NOMINMAX を定義しないとコンパイルに支障がでるようなライブラリを作るのは、やめてくれないかなー。しかも、NOMINMAX を定義したら、コンパイルに支障をきたすようなライブラリを作るのもやめてくれないかなー?
 嫌がらせにしか思えないぞ・・・。
2011/09/08 追記:一番スマートな回避法はこちら

フォント

 Gigazine の無料で使えるフォントを見て閃いた。
  1. Tex メタフォントのように、パラメータを調整して、いろんなデザインのフォントを作成できるようなツールを作成する
  2. おまえフォント・サービスを構築
  3. 怪しげなアンケートと共に、オリジナルフォントを作成し配布
つまんないか・・・

2009年4月12日日曜日

SpamAssassinに関する雑記

 松田さんが、熱いポストをしたので、いつか書こうと思っていました。SpamAssassin が日本語対応していない時など、松田さんのルールのお世話になっていた人は多いはずだと思います。私もお世話になっていました。私が日本SpamAssassinユーザ会に参加しようと思ったのは、久保さんの呼びかけもあったけど、松田さんの強い意志と呼びかけによるもので、松田さんの呼びかけが無かったら、自分が行動を起こしていたかどうかは、わかりませんでした。そんな影響で、自分も微力ながら日本語対応パッチをあてた SpamAssassin 用のルールを公開しています。
 最近は、活動が停滞していますが、これに関しては、自分のためよりも、君のために書いています(ほんとだよ)。ボランティアのコンセプトは、以下のようなものです。
 Spamメールにより汚染されたメールを読むのに人々は膨大な時間を費やしています。そして、頭の良い優秀な人であっても、この汚染により無駄な時間を強いられている現状が推定できます。1人あたり1日に10分のロスがあったとしたら、1年で 365 x 10 min = 3650 min = 60 h のロスです。1万人を対象に考えれば、60万時間のロスになります。こう考えたら、自分のちょっとした活動の時間単価は、物凄く高い仕事になります。こういうのって怠惰で傲慢なコンセプトって言うんでしょうか?

 コンテンツの復旧もしないと・・・

千歳川


本日は、久しぶりのダウンリバーでした。この時期は、だいたい千歳川で肩慣らし…(しかし、今シーズンも肩慣らしだけで、ほとんど終了してしまいそうな予感)。水が冷たくてロールしたくないとか言っていたTさん、あれー、たまり(マナブというプール)で、グルグル回ってロールしてんじゃん。「はい、沖さんも、なんか技入れてロールして」とかリクエスト出されて、結局ロールしたら、水が冷たいですー。運動しないと、頭も馬鹿になるから月に1回ぐらいは川へ心の洗濯しに出かけたいな・・・。
 さすがに、こういう時は、車が無いと手も足も出ません。友人の itapon さんにのせてもらいました。筋肉痛なのか、軽く肩が重いです。

若者の車離れを無くすには?



 カーシェア・ビジネスが伸びているといったニュースでも、車が売れなくなる事は問題だ!みたいなコメントがされていたけど、時代が変わったのに、これはちょっと、おかしな議論ではないか?
 この時代に百科事典を売るには?と、いくら考えたところで仕方が無いと思うのだ。車離れを無くすには?というお題よりも、どのような車・どのような売り方なら売れるか?を考えるべきだと思う。一家に一台の時代は、根本的に車の方を変えないと無理なのではないか?努力する方向を間違えると、無駄な時間を費やす上に、ほとんど何も得るものが無いと思うのだが・・・。
 だいたい都心に住んでいて、車が必要ですか?私も車無し生活を送って5ヶ月になるけど、車が無くても、なんとかなるものだ。本当に必要な時はレンタルで十分だろう。まだ一度もレンタルしていないが、それはカーシェア・ビジネスやレンタカー・ビジネスが近所まで浸透していないからだ。極端な話、業務車以外は走行禁止にして、自転車を優先させても良いぐらいだと感じている。

追伸:ポートピア連続殺人事件って、懐かしすぎる。「ボス、おはようございます」たどたどしい PC-6001 mk2 の声を思い出す…。「えーと、あの日はですね・・・」


 

2009年4月11日土曜日

グリーン革命(下)途中の感想(2)

 もうひとつ、思いついたアイデアをとにかく書いとく。
地球外の人工衛星か宇宙基地か月面基地に太陽光発電施設を作り、電磁波で地球に向けてエネルギーを送信するという壮大な計画。いろいろと思いついてるんだけど、メモってないんでわすれちゃったよ・・・。

『C++テンプレートテクニック』予約したどすぇ~

 もちろん、ここから買ったどすぇ~。ついでに、気にのうて CUDA ってみましたけど、GeForce 8600M GS (256M)のノート版では、ほとんど動作しなかったどすぇ~orz。

グリーン革命(下)の途中感想

 いやー、トーマス・フリードマンさんの本は、脳が活性化します。かしこいエネルギー、面白いけど、ひとつだけ気になった。いくら車が発電するからと言っても専用の発電機を設置する方が効率がいいだろうから、駐車場ビジネスは夢物語だろうと思います。
 で、朝に閃いたのは、スラドに出ていたベルシオンを利用して、自動車の燃費をアップできないだろうか?というもの。F1レースなんかでは、ダウンフォースを得るのにウィングの調整をしたりしてますが、このベルシオンは空気を掴むという感覚なんだそうで、トラックであれば浮力を制御するとか、乗用車であればダウンフォースを制御するとか、これによってタイヤから路面に伝えるエネルギー効率を飛躍的に上げれたりしませんかね?というもの。普通のプロペラと違って取り付けやすいような気もするし・・・。

2009年4月9日木曜日

printf デバッグについて

 毛嫌いするほどのものでもないと思う。だいたい、10万ループとかしているうちのあるデータがおかしくて、7万ループ目ぐらいにハングするといったような場合、まず、どのデータで落ちるのかログを取って見当をつけないと、デバッガでデバッグのやりようが無い。まさか、7万回もステップ実行するわけにゃいかんだろう。頭いい人は、ダンプファイルから推察でもするのかな?で、ハングできるデータを作成する?複合的な原因で落ちる場合にはどうすればいい?バグが再現できないだろう?
 次に、昨今のソフトウェアは複雑で、この間書いたやつなんか、複数の拠点間で
  1. クライアント・アプリケーション
  2. クライアント・アプリケーションが利用するコンポーネント
  3. コンポーネントから別マシンのサーバにアクセスするサーバ・システム
  4. そのサーバ・システムからWAN越しにSOAP接続
  5. SOAPモジュールから、WANのセンター・サーバへ接続
  6. センター・サーバから、3.へ再配信するためのSOAP接続
  7. そのSOAPモジュールから3.へアクセス
ログでも取らないと、デバッグなんて無理です。しかも、ダンプとれるほど単純でもないし、スレッドが絡んでくる。1行たりともソースをいじるべからず!素晴らしいけど、俺には無理だ。
 手っ取り早いログは、printf でしょう。テスト・ユニットでテストしてれば、こういう事態は減るんでようけどねぇ。それでもバグは混入する。

2009年4月7日火曜日

グリーン革命(上)の感想

 やっと「グリーン革命(上)」を読み終えた。「フラット化する世界」の著者が書いたものであれば、期待感は大である。しかしながら、アメリカ人に向けて書かれているようで、私にとって第1章と第8章が面白くなかった。実際に、この章は流し読みした。
 第4章の独裁者を満タンにし続けるのか?は、視点が面白く、流石だ。第5章の地球惑乱は、以前に書いたように肌で実感している事だった。続きを書くと、例年であれば、ウッドデッキに積もる雪が1メートル以上になり、デッキの柵を越えて雪庇を形成するところが、今年は、積雪が柵の三分の一までしかいかずに冬が終了した。本気になって対策をはじめようというよりも、既に手遅れではないか?と感じているところだ。
 では、どうすれば良いか?というと、WACC(World Air Control Center)という世界組織を作って、地中深くに二酸化炭素を閉じ込めるという事業を開始すべきだと閃いた。費用は先進国で負担すべきだ。グリーン革命が終わった頃には、取り返しが付かない事態に陥っているのではないか?
 下巻は、どのような展開になるのだろうか…。これだけ展開していて、まだ半分とは恐れ入る。

2009年4月6日月曜日

devenv.exe ひでぇな


volatile bool bexit = false;

while(1) {
devenv.exe が終了しない!どうしますか?

C:\> taskkill /F /T /IM devenv.exe
成功: PID xxxx のプロセス(PID xxxx の子プロセス)は強制終了されました。
成功: PID xxxx のプロセス(PID xxxx の子プロセス)は強制終了されました。
成功: PID xxxx のプロセス(PID xxxx の子プロセス)は強制終了されました。

devenv.exe が現れた!どうしますか?

C:\> taskkill /F /T /IM devenv.exe
成功: PID xxxx のプロセス(PID xxxx の子プロセス)は強制終了されました。
成功: PID xxxx のプロセス(PID xxxx の子プロセス)は強制終了されました。
成功: PID xxxx のプロセス(PID xxxx の子プロセス)は強制終了されました。

if( bexit ) {
// 制御不能です。電源を長押しして、強制オフしてください。
// 死んでいいぞ
}

}


追記:犯人は、intellisense くさい
追記:こんな情報をみつけた。今日も devenv.exe が現れた!電源切るしかねーよもう。この情報にすがってみるよ…。
追記:

2009年4月5日日曜日

boost::asio で pop3

 とりあえず、boost 1.38.0 と cmake で焼きなおしてアップしました。

2009年4月4日土曜日

プログラマーのピーク

 今度は、プログラマー35歳説について述べよというお題が出た気がするので、書いてみます。私の現在の年齢が42.6歳です。本当に限界は35歳か?
 振り返ってみると、ピークは36歳ぐらいだろうと感じます。この年齢から徐々に瞬発力と、全体の詳細までを記憶する力が無くなります。ここからは、もう財産の食いつぶし。しかし限界が36歳というのは都市伝説でしょう。知っているプログラマで、60歳近くになるのにバリバリ書いてる方もいます。レベルも1級品です。
 それよりも私は、新たな定説を提唱したい。プログラマ28歳限界説。これはプログラマに限った事ではありませんが、28歳にもなって努力を怠り何もしない人間は、それが習慣化し、周囲から助言を得ても、今までに是正する事が無かったので変わりようがありません。あとは硬直化して伸びる事がありません。よって、能力を得る見込みの無い人は、この年齢でお払い箱。
 話を自分の状態に戻して、ではどうか?瞬発力が無くなったので、以前の自分に比べればコーディング・スピードは倍近く時間がかかるようになったかもしれません。しかし、構想力は今の方が上がっていると感じます。若い人にコーディングを任せた方が良い場合も想定できるし、そうでない場合もあります。
 能力に関するものでは、「<勝負脳>の鍛え方」という本が科学的で、面白いです。プログラマ36歳限界説は2割真実で、8割嘘、気にする事は無いけど工夫は必要のような気がしてます。どんな工夫が必要なのかは、もう少し先の年齢でないと書けそうもありません。

2009年4月3日金曜日

来年あたりは決断の年かな

 自分は、どうしようもない根っからのプログラマだ。それが今、ネットワーク(システム)管理者を兼任して、個人情報管理責任者をして、マネジメントを任されて(会社を辞めても失業手当が出ない経営者の一角だ)、実システムのコーディングにタッチして(ひどい時には、3現場掛け持ち)、選択肢の広い技術に触れて取捨選択をしながら、明日のコンセプトを創出し、社員教育も考えなければならないが実質的にそんな余裕がない。
 ネットワーク管理者の地位は、信じられないぐらい低い、何かトラブった時には、徹夜も辞さない覚悟が必要で、ちょっとした無知のせいで他所(インターネット上の他のところ)へ多大な迷惑をかける。お前のところのルータの設定 DHCP が外に対して有効になって、不正経路に使われてるぞというお叱りのメールを英語で受けた事や、SMTPリレーの穴が開いていてスパムに悪用されたりして、対処に追われたり、他人に任せたら不正侵入されてプロバイダに謝ったりと、ネットワーク管理者なら、こんな経験のひとつやふたつはあるだろう。軌道に乗っている時は、あまりやる事は無いかもしれないが、そう簡単に切り出せる類のものでもない。兼任では本業が疎かになって当たり前なのだ。
 マネジメントは方針や判断を行って人に命令する仕事である。そのマネジメントすべき人間が、3つの現場のコーディングを掛け持ちして、納期が間に合わなくてピリピリと神経を尖らせている状況の時もある(こんな時は、ネットワークトラブルや何かの相談が無い事を祈っている余裕すらない)。
 そして、この不景気だ。受託開発は、よほどの隙間でなければ、この先もうやっていけないだろうと思う。SaaS へシフトしていかないと生き残れないと思っている。中途半端な過去の資産が無い方が今は有利だ。当然そのための構想をいろいろ考えて試行錯誤する。傍から見ていると遊んでいるように見えるだろう。ここは自分の真骨頂で苦にはならない。しかし、近年は何でも高度化していて、並大抵の努力とリソースではおぼつかない。問題は会社の体力だ。どこも似たようなものだと思うが、新しい試みで失敗できるゆとりが無い。あれこれ考えても本気でアクセルを踏める状況にはならない。そうこうしているうちに、何をしても無駄感が募るばかりである。
 なによりも自分の心のベクトルと実ベクトルとの方向が大きくずれつつある。誰のための人生か?来年あたりは、どうするか決断すべきだろう。

2009年4月1日水曜日

それでも windows vista は眠らない

 まあ、windows vista は嫌いだ。とにかく終了しない。昨日はシャットダウンしようと思ってもログオフ中のままなので、放置プレーで帰ったら、翌朝もログオフ中であった。またかよ…。
おかげで、こんなコマンドを覚えてしまったではないか

C:\> chkdsk /f
C:\> shutdown /r /t 0

いい加減にしてほしい。で、犯人の目星はついている。devenv.exe だ。こいつが残ると、タスクマネージャで殺しにいっても死なない。ひどいと1日に2回チェックディスクをかけている。
あまりに酷いので、babysitter というシャットダウン時に devenv.exe のプロセスが残っていたら殺すサービスを作成しようかと、まじめに考えている。
 windows 3.51 あたりが一番好きかも? GDI がカーネルに侵食してからは、どうも好きになれん。

文字コード変換

 やっぱ、お手軽に使える感じの文字コード変換が欲しい…。というわけで作りました。
wconv.hpp
#ifndef WCONV_HPP
#define WCONV_HPP

#include <string>

std::wstring string_to_unicode( const std::string& src, unsigned code_page );
std::string unicode_to_string( const std::wstring& src, unsigned code_page );

template <int CODEPAGE>
std::wstring string_to_unicode( const std::string& src ) {
  return string_to_unicode( src, CODEPAGE );
}

template <int CODEPAGE>
std::string unicode_to_string( const std::wstring& src ) {
  return unicode_to_string( src, CODEPAGE );
}

template <int DST_CODE_PAGE, int SRC_CODE_PAGE>
std::string code_to_code( const std::string& src ) {
  return unicode_to_string<DST_CODE_PAGE>( string_to_unicode<SRC_CODE_PAGE>( src ) );
}

#endif // WCONV_HPP


codepage.hpp
#ifndef CODE_PAGE_HPP
#define CODE_PAGE_HPP

/// form winnls.h
//@{
#define CP_ACP               0  // Current Code Page
#define CP_UTF7          65000  // UTF7
#define CP_UTF8          65001  // UTF8
//@}

#define CP_OEM_US          437
#define CP_OEM_ALABIC      720
#define CP_OEM_GREEK       737
#define CP_OEM_BALTIC      775
#define CP_OEM_MLATIN1     850
#define CP_OEM_LATIN2      852
#define CP_OEM_CYRILLIC    855
#define CP_OEM_TURKISH     857
#define CP_OEM_MLATIN1P    858
#define CP_OEM_HEBREW      862
#define CP_OEM_RUSSIAN     866

#define CP_THAI            874
#define CP_SJIS            932
#define CP_GBK             936
#define CP_KOREA           949
#define CP_BIG5            950

#define CP_EUROPE         1250
#define CP_CYRILLIC       1251
#define CP_LATIN1         1252
#define CP_GREEK          1253
#define CP_TURKISH        1254
#define CP_HEBREW         1255
#define CP_ARABIC         1256
#define CP_BALTIC         1257
#define CP_VIETNAM        1258

#define CP_ISO_LATIN1    28591
#define CP_ISO_LATIN2    28592
#define CP_ISO_LATIN3    28593
#define CP_ISO_BALTIC    28594
#define CP_ISO_CYRILLIC  28595
#define CP_ISO_ARABIC    28596
#define CP_ISO_HEBREW    28598
#define CP_ISO_TURKISH   28599
#define CP_ISO_LATIN9    28605

#endif // CODE_PAGE_HPP


wconv.cpp
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winnls.h>
#include <string>
#include <boost/scoped_array.hpp>

#include "wconv.hpp"

std::wstring string_to_unicode( const std::string& src, unsigned code_page ) {
  int result_length = MultiByteToWideChar( code_page, 0, src.c_str(), -1, 0, 0 );
  if( result_length > 255 ) {
    boost::scoped_array<wchar_t> tbuff( new wchar_t[ result_length + 2 ] );
    MultiByteToWideChar( code_page, 0, src.c_str(), -1, tbuff.get(), result_length );
    std::wstring result = tbuff.get();
    return result;
  } else {
    wchar_t tbuff[ 256 ];
    MultiByteToWideChar( code_page, 0, src.c_str(), -1, tbuff, result_length );
    std::wstring result = tbuff;
    return result;
  }
}

std::string unicode_to_string( const std::wstring& src, unsigned code_page ) {
  int result_length = WideCharToMultiByte( code_page, 0, src.c_str(), -1, 0, 0, 0, 0 );
  if( result_length > 511 ) {
    boost::scoped_array<char> tbuff( new char[ result_length + 2 ] );
    WideCharToMultiByte( code_page, 0, src.c_str(), -1, tbuff.get(), result_length, 0, 0 );
    std::string result = tbuff.get();
    return result;
  } else {
    char tbuff[ 512 ];
    WideCharToMultiByte( code_page, 0, src.c_str(), -1, tbuff, result_length, 0, 0 );
    std::string result = tbuff;
    return result;
  }
}

//#define WCONV_TEST_APP
#ifdef WCONV_TEST_APP

#include "codepage.hpp"
#include <fstream>
#include <iostream>

//#define YOURPAGE  CP_SJIS
#define YOURPAGE  CP_ACP

int main(int argc, char* argv[]) {
  if( argc < 3 )  return 1;
  std::ifstream ifs( argv[1] );
  std::ofstream ofs( argv[2] );
  //std::wcout.imbue( std::locale("") );
  std::string str;
  while( std::getline( ifs, str ) ) {
    std::string dst = code_to_code<CP_UTF8,YOURPAGE>( str );
    ofs << dst << std::endl;
    //ofs << code_to_code<YOURPAGE,CP_UTF8>( str ) << std::endl;
  }
  return 0;
}

#endif
2018/08/29 追記 std::basic_string のバッファを直接使っていたが、それだと null terminated まで組み込まれてしまうため、修正を行った。

boost::gil で bicubic

 昨日、gil で挑戦してみてはいかが?と書いたが、必要になって挑戦するはめになった。
libs/gil/example/resize.cpp というのを見つけて、これはもしや?と思ったが、boost/gil/extension/numeric/* が、ごっそりと抜け落ちていてコンパイルできない…。どこにあるんだべーと探したら、GIL本家のダウンロードページにあった(現在、ここからサルベージするしかない)。

さっそく bicubic が落ちていないか探したが、bilinear までしか実装されていないようだ。チャレンジしようと思ったが、gil をよく知らないので苦労した。チュートリアルの日本語訳があって、非常に助かりました。
という訳で、csampler.hpp です。
/*************************************************************************************************/

#ifndef GIL_CSAMPLER_HPP
#define GIL_CSAMPLER_HPP

#include "../../extension/dynamic_image/dynamic_image_all.hpp"
#include "pixel_numeric_operations.hpp"
#include "sampler.hpp"

namespace boost { namespace gil {

struct truncate_channel_fn {
    template <typename SrcChannel, typename DstChannel>
    void operator()(const SrcChannel& src, DstChannel& dst) {
        typedef typename channel_traits<DstChannel>::value_type dst_value_t;
        if(std::numeric_limits<dst_value_t>::max() <= src)
          dst = std::numeric_limits<dst_value_t>::max();
        else if( src < 0 )  dst = dst_value_t();
        else  dst = dst_value_t(src);
    }
};

template <typename SrcPixel, typename DstPixel>
void truncate_pixel(const SrcPixel& src, DstPixel& dst) {
    static_for_each(src,dst,truncate_channel_fn());
}


/// \brief A sampler that sets the destination pixel as the bicubic interpolation of the four closest pixels from the source. 
/// If outside the bounds, it doesn't change the destination
/// \ingroup ImageAlgorithms
struct bicubic_sampler {};

template <typename DstP, typename SrcView, typename F>
bool sample(bicubic_sampler, const SrcView& src, const point2<F>& p, DstP& result) {
    typedef typename SrcView::value_type SrcP;
    point2<int> p0(ifloor(p)); // the closest integer coordinate top left from p
    if (p0.x < 0 || p0.y < 0 || p0.x>=src.width() || p0.y>=src.height()) return false;

    pixel<F,devicen_layout_t<num_channels<SrcView>::value> > mp(0);                     // suboptimal
    typename SrcView::xy_locator loc=src.xy_at(p0.x,p0.y);

    for( int y = -1; y < 3; ++y ) {
      for( int x = -1; x < 3; ++x ) {
        point2<F> frac(std::abs(p.x-static_cast<F>(p0.x+x)),std::abs(p.y-static_cast<F>(p0.y+y)));
        F wx, wy;
        if( frac.x < static_cast<F>(1) )    wx = (frac.x - 1) * (frac.x * frac.x - frac.x - 1);
        else                                wx = (1 - frac.x) * (frac.x - 2) * (frac.x - 2);
        if( frac.y < static_cast<F>(1) )    wy = (frac.y - 1) * (frac.y * frac.y - frac.y - 1);
        else                                wy = (1 - frac.y) * (frac.y - 2) * (frac.y - 2);
        int offx = ( p0.x+x < 0 || p0.x+x>=src.width() ) ? 0 : x;
        int offy = ( p0.y+y < 0 || p0.y+y>=src.height() ) ? 0 : y;
        detail::add_dst_mul_src<SrcP,F,pixel<F,devicen_layout_t<num_channels<SrcView>::value> > >()( loc(offx,offy), wx * wy, mp );
      }
    }

    // Convert from floating point average value to the source type
    SrcP src_result;
    truncate_pixel(mp,src_result);

    color_convert(src_result, result);
    return true;
}

} }  // namespace boost::gil

#endif

お試しコードは、resize.cpp をちょいと改造するだけ。せっかくの bicubic なので拡大してみました。
#include <boost/gil/image.hpp>
#include <boost/gil/typedefs.hpp>
#include <boost/gil/extension/io/jpeg_io.hpp>
#include <boost/gil/extension/numeric/sampler.hpp>
#include <boost/gil/extension/numeric/csampler.hpp>
#include <boost/gil/extension/numeric/resample.hpp>

int main() {
    using namespace boost::gil;

    rgb8_image_t img;
    jpeg_read_image("test.jpg",img);

    // test resize_view
    // Scale the image to 100x100 pixels using bilinear resampling
    rgb8_image_t square100x100(600,600);
    resize_view(const_view(img), view(square100x100), bicubic_sampler());
    jpeg_write_view("out-resize.jpg",const_view(square100x100));

    return 0;
}