[CoveredCalc カバー] 気分転換

ちょっと気分転換に、数字入力キーがなく表示部分がメインの電卓カバーを作成中です。
本物の電卓では、キーがなければ入力ができませんが、CoveredCalc の場合はキーボードがあれば入力はできるので、これはこれで使い道があるはず。場所とらないし。
a0011820_281414.jpg

まだデザインしている状態で、CoveredCalc では動きません。
[PR]
# by hironytic | 2005-03-09 02:09 | 開発状況

[CoveredCalc for BeOS] BTextView が……

現在のカバーの情報を表示するダイアログを Dano 版として Dano 上でビルドして Dano で確認してみたら BTextView を使っている部分の背景色が全く反映されていませんでした。
なぜだ~と思って調べてみたら、そもそも BTextView の View Color がリソースにアーカイブした時点で正しくアーカイブされていないみたいです。
Interface Elements で View Color を設定して保存 → いったん閉じて再度そのリソースを開くという操作をしても設定した View Color になっていません。
他にも、GuiBerry (を R5 でビルドしてみたものを Dano で実行)では、BTextView の View Color を指定してもすぐに元に戻ります。

Dano の BTextView の定義を見てたら、SetViewColor() がオーバーライドされているみたいなので何か別のフィールドを使うようになっているのかもしれません。
リソースは R5 で作ったものですからね。

こういう状況になってくると、ウィンドウをリソースで持つことには不安がでてきます。
Zeta では(BMessageの?)フォーマットも変わっているみたいです。(FOB1 の識別子が FOB2 になっているみたい)
まあ、現在リリースしている CoveredCalc が Zeta でも動いているってことは、下位フォーマットもサポートしているんでしょうけど。

すでにリリースしてしまっている状態なのでなんですが、今ならまだダイアログも少ないので別の選択肢に移ることも開発側としては可能です。
でも、リソースだけ置き換えればダイアログの配置なんかを変えられるっていうのは個人的に好きなんですよね~。
[PR]
# by hironytic | 2005-03-07 13:01 | 開発状況

[CoveredCalc for BeOS] カバー情報ダイアログ

昨日の早朝の時点で BeOS 版でもカバー情報ダイアログを表示できるようになりました。
Windows 版ではモーダルダイアログ(そのダイアログが表示されていると他のウィンドウの操作ができないダイアログ)なんですが、BeOS ではモーダルダイアログは一般的ではないのでモードレスダイアログ(他のウィンドウも操作できるダイアログ)にしてあります。

ちょっと時間がかかってしまった理由は、作業時間があまりとれなかったっていうのもありますが、BTextView にスクロールバーを付けるのに苦労したというのもあります。
BTextView を BScrollView でくるんでやればいいのはわかっていました。InterfaceElements でそう配置しようとしたのですが、BScrollView を作ったら BView な子ビューがすでに入ってました。それを削除して BTextView を入れて保存したところ、子 View の順序が変わったのがいけないのか、次に開くと水平スクロールバーがすごい位置に表示されました。本来、BScrollView のターゲットはコンストラクタで指定したあと変えることはできないはずなので、どうしようもないのかもしれません。
結局、InterfaceElements ではただの BTextView を貼り付けておくことにしました。
実行時にそれを親ビューから削除して、新しく BScrollView を作ります。


これで、Windows と BeOS で Version 1.1 をリリースしてもいいんですが、増えた機能がカバーのバージョン情報が表示されるようになっただけであんまりにも情けないのでもうちょっと細々したところをいじってみることにします。BeOS 版で、別スレッドからウィンドウを操作している部分があって少し不安なところもあるので、その辺もなおしたいし。

カバーの著作権情報が表示されないままなのは問題ありますが、今のところ自分以外にカバーを公開してくださっているのは桝田道也さんだけなのでもう少し延ばしてもまあいいかと勝手に判断。桝田さん、ごめんなさい。
[PR]
# by hironytic | 2005-02-28 10:44 | 開発状況

[CoveredCalc for BeOS] Dano 版のビルド

Dano の環境を整えたので、Dano でもビルドできるようにしてみました。
ただビルドできるだけじゃする意味ないので、Dano でサポートされた非矩形ウィンドウを使って Dano バージョンなら Windows 版と同じように背景を透過するようにしました。
a0011820_1542752.jpg

スクリーンショット左は R5 版、右が Dano 版。

ほんとはこんなことやってないで、カバーのバージョン情報を BeOS 版で表示できるようにしないといけないのだけど。(^^;
[PR]
# by hironytic | 2005-02-22 01:55 | 開発状況

[CoveredCalc] カバーのバージョン情報

現在のカバーのバージョン情報(about タグ)を表示するダイアログを作成中。
バージョン情報だけでは寂しいのでタイトル説明文も一緒に表示します。

Windows 版は動くようになりました。とりあえずこれだけの修正でいったんバージョンアップしようと考えているので、バージョン番号を上げて、一連のリリース作業をすれば Windows 版だけ先行でバージョンアップできます。
が、BeOS 版と共通のソースも修正しているので、BeOS 版は現在ビルドできないはずです。ここで BeOS 版をビルドできるようにしていると、たいてい共通ソースにも修正が入って Windows 版にも影響を与えることが多いのです。(要するに Windows 版作成時に共通ソースを修正していると BeOS 版に対する考慮が漏れている部分があるということです)
BeOS 版が動くようになるまでにそうそう時間はかからない(と思っている)のでやっぱり BeOS 版と同時リリースにしようと思います。

ちなみに、機能が増えるので、バージョンは 1.1 になります。
[PR]
# by hironytic | 2005-02-08 17:59 | 開発状況

[CoveredCalc] なんちゃってDOM

CoveredCalc では、カバー定義と設定ファイルに XML を利用しています。
XML にすると汎用のパーサが使えたり、拡張がしやすかったりというメリットがあるからです。(と過去に自分が書いてます

汎用の XML パーサには、SAX と DOM の 2 種類があります。SAX はタグなどが見つかるたびに順に通知されるイベント型。お手軽で簡単な解析に向いています。DOM は XML 文書を解析したあとツリー構造をそのままオブジェクトにマッピングして、文書内のどこでも参照できるような高機能なものです。さらに、そのツリーに変更を加えて、XML 文書として書き出すこともできます。(SAX は読み込みしかしない)
作り始めた当初は、そんなに複雑にするつもりはなかったので、SAX パーサでお手軽にやればいいかと思っていました。でも、作ってみると(特にカバー定義が)思ったより複雑になってしまいました。SAX パーサからのイベントハンドリングは妙に複雑です。
さらに設定をファイルに落とすときに XML 文書を自分で書き出さなくてはいけないので割と面倒です。
これはカバー定義と設定項目の拡張を妨げる原因になっています。やる気がなくなるんだもん。

このあたりで、SAX パーサをやめて DOM パーサに変更しようかと思いました。
現在使っている Expat を採用した背景には、BeOS で使えたことと、ライセンスが希望に合うことがあります。(と、これもまた過去に書いてます
一方、DOM パーサとして有名なのは Xerces(C++ で利用するので Xerces C++)です(なお、Xerces は SAX パーサの機能も持っています)。最新バージョンは 2.6.0 のようですが、BeOS にも 2.4.0 がポーティングされているようです。ライセンスも Apache Software License 2.0 なので問題はないでしょう。
ただし、この BeOS ポートでは共有ライブラリ(.so)のバイナリしかありません。自分でビルドすればスタティックライブラリ(.a)も得られるんでしょうか。共有ライブラリでも構わない(むしろユーザからすればそっちの方がいい?)んですが、シンプルなファイル構成にしたいのと、ユーザの環境によってライブラリが異なっていると動きが変わったりするのを避けたいんです。

でも、そこまでしてフルスペックの DOM パーサがいるか?という気もしてきました。
当然、DOM パーサは処理も重いし、サイズも大きくなります。
Expat がうまく動いてくれていることはわかっているわけですから、解析にはこのまま SAX パーサを使うことにして、DOM ツリーの管理部分とツリーを XML に出力する部分だけを自力で作ればいいんじゃないかと。
別にフルスペック必要なわけではないので、自分が使うような機能だけを実装した「なんちゃってDOM」でいいんです。DOM の仕様を満たす必要なんか全然ありませんしね。

でも、これはそれなりに時間がかかりそうなので、他の機能を実装しながら、平行して進めようかなと思っています。パーサ自体は独立してるので、Subversion でブランチ切って作業してれば、最新ソースへのマージも楽かな~。
[PR]
# by hironytic | 2005-02-01 01:02 | 構想

[CoveredCalc] さらにバージョンアップ

昨日のバージョンアップの修正で仕込んでしまったバグのおかげで連日バージョンアップ。
バグの修正よりもリリースのための作業(マニュアル更新、ZIPへのパッケージング、Web ページの更新など)に時間がかかるんだよな~。もぉ~。
自分で入れてしまった不具合だから文句は言えないけど。
[PR]
# by hironytic | 2005-02-01 00:08 | 開発状況

[CoveredCalc] バージョンアップ

CoveredCalc for Windows 1.0.4、CoveredCalc for BeOS 1.0.1 をリリースしました。
メインの修正点は、起動時に前回終了時に表示していたカバーを読み込もうとして失敗すると、すぐに終了してしまってカバーを変更することができなかった動作を変更したことです。
こんなときはデフォルトカバーを使って起動するようにしました。
ただし、デフォルトカバーが壊れていた場合はどうしようもありません。
[PR]
# by hironytic | 2005-01-30 22:21 | 開発状況

[CoveredCalc] 例外からのエラーメッセージを取得を修正中

BeOS 版もひとまず公開できたので、前々から設計が気になっていた部分を修正中です。
それは、期待した処理が行えなかったときに発生する「例外」オブジェクトに対応するエラーメッセージを取得する部分です。

まず、例外オブジェクトの構造はクラス図にするとこんな感じになっています。
すべて Exception というインタフェースを実装したかたちで例外の種類ごとにクラスがあります。
図には書いていませんが、Exception を実装する各クラスには、そのクラスに特化したメソッドも持っています。
たとえば、XML ファイルの解析中に発生する例外クラス XMLParseException は、例外の発生した行を得るための GetLine() を持っています。

ここで、Exception には GetErrorMessage() があるのですが、これは必ずしもユーザにお見せできるようなものではありません。また、将来、多言語対応を考えているのですが、言語によるエラーメッセージの切り替えを各例外クラスの中で行いたくはありません。
そこで、ExceptionMessageResolver というものを導入しました。クラス図にするとこんなものです。これだけではわかりにくいので、オブジェクト図も一緒に見てください
ExceptionMessageResolver は Resolve() に渡された例外を見て、自分の知っているものなら対応するエラーメッセージを返します。
たとえば、MemoryExceptionMessageResolver は、渡された例外が MemoryException なら「メモリが不足しています」というようなメッセージを返します。
利用する側では、ExceptionMessageResolver の集団に対して、その 1 つ 1 つに「この例外知ってたらメッセージをちょうだい」とお願いしていきます。メッセージをもらえればそれをユーザに表示するわけです。

さて、XMLParseExceptionMessageResolver は CoverDefParseException を渡されたとき、それを XMLParseException だと判断して「XML ファイルの解析に失敗しました」のようなエラーを返しますが、本当は CoverDefParseException なんだから、そこは CoverDefParseExceptionMessageResolver に任せてもっと細かいメッセージをもらいたいものです。
そこで、XMLParseExceptionMessageResolver はまず CoverDefParseExceptionMessageResolver に処理を頼んで、解決できなかったときだけ自分が解決しようとします。そのための仕組みが ChainedExceptionMessageResolver で、あらかじめ登録されたものに処理をお願いできるようにしてあります。
オブジェクト図では各クラスオブジェクトがどういう関係で登録されているかわかるようにしています。
また、この仕組みを使って、1 つ 1 つのオブジェクトに「これ知ってる?」って聞いてまわるだけのやつも作りました。
オブジェクト図で allInOne という名前のついた HandsOffExceptionMessageResolver のオブジェクトです。
こいつは人に頼むばっかりで自分は何も解決しません。

さらに C++ なので誰かがこれらのオブジェクトの寿命を管理してやる必要があります。
そこで、すべての ExceptionMessageResolver オブジェクトの寿命は ExceptionMessageResolverStorage が管理してやることにしました。
欲しいオブジェクトの取得も Get でできます。たとえば、ある例外がすでに XMLParseException だとわかっているなら、allInOne を使う必要はなくて、直接 XMLParseExceptionMessageResolver のオブジェクトを使えばいいのです。
そして、この storage くんが makeStorage() というメソッド内で各オブジェクトの主従(?)関係を登録しています。

こういう設計にしたところ、非常に大きな問題が目の前にのしかかってきました。
1 つ例外を作ろうと思ったらえらく面倒なのです。
その例外に対応する Resolver クラスを用意して(これが面倒)、ExceptionMessageResolverStorage::makeStorage() でその Resolver を生成して、場合によっては主従関係の登録をしなおして、さらに ExceptionMessageResolverStorage::Get() でその Resolver をもらえるように、Resolver の種類を表す列挙型(EMRSClass)を追加しなければいけません。
こういうのを「懲りすぎ」といいます。全くもって無駄に複雑になっています。考えなしに作るとこうなります。
割と早いうちにうすうす気づいてはいたのですが、さっさと動くものを作りたかったこともあって、そのままがんばってました。
Windows と BeOS の両バージョンをとりあえずリリースできたので、これを大きく作り直しています。
単なる作り直しでしかないので、残念ながらここが作り直されてもユーザさんにはメリットはありません。すみません。

ExceptionMessageResolver(とその周辺クラス)にとってかわる新しい ExceptionMessageGenerator は全くもって単純なものです。クラス図はこんな感じ
見てのとおり、すべての例外をこのクラスがすべて扱います。たとえば、今まで XMLParseExceptionMessageResolver が行っていた機能は processXMLParseException メソッドが引き受けます。processXMLParseException メソッドはその中で processCoverDefParseException メソッドを呼んでいます。そうです。主従関係はここにハードコーディングされています。
だいたい、場合によって主従関係をが変えたくなることはまずないんです。これでいいやん!
それから、たとえそれが XMLParseExeption だとわかっていても、他の process~ を使わないといけない作りになりました。実際の例外は、XMLParseException のサブクラスが数個、CoverDefParseException のサブクラスが数個というように細かい例外ごとに 1 つクラスを作っているので全部比較していたら遅いんですが、そんなことはしませんから。そのためにクラスを階層化してあるんであって、親クラスの例外でなければ、それより下のクラスの例外ではないのでたどる必要はありません。
それなら、せいぜい、数個~十数個の比較で、処理できるはずで、そんなに時間がかかる処理でもないからこれでいいやん!

ということで、BeOS 版の公開でふぬけになってさぼっているわけではありません(笑)
一応、やってますよ、ということで。
まあ、玄箱いじったりしてて開発止まってた時期があったのは確かですけど(ぉ
[PR]
# by hironytic | 2005-01-28 22:34 | 開発状況

[CoveredCalc] バグ修正と BeOS 版

昨日の晩、MIY ちゃんとチャットで話していて、カバー切り替え時に画像ファイルが見つからないなどのエラーが発生した場合、そのまま終了すると、次回起動時にエラーメッセージが出て二度と起動できなくなることがあるというバグ報告を受けました。

見た目は切り替え前のカバーになっていますが、内部的にはエラーが発生する切り替え後のカバーに変更されている様子。それが 1 つ目のバグ。で、2 つ目のバグとして、前回のカバーが読めなくなっている状態の場合に二度と起動できないというのも関係しています。まあ、後者は既知の不具合なのですが、プログラムの構造を変更する必要があって、現在 BeOS 版を作ってることもあり、そっちができてから直そうと思ってるものです。

そういうわけで、1 つ目のバグをなんとか修正しました。
でもまだわけあってリリースはしていません。

さて、BeOS 版の方ですが、カバーブラウザのリストのダブルクリックでカバーが切り替わらないという点が Windows 版と異なっていますが、それ以外では(正常系の動作なら)ひととおり実装できたと思っています。
エラー処理になるとちょっと怪しいんですが、それはまあ Windows 版も同じということで(爆)
BeOS 版も近いうちに初回リリースができるかなと思っています。
[PR]
# by hironytic | 2005-01-03 22:56 | 開発状況