PalmSource Japan Forum 2002記念、特別寄稿
=======================================================
『PalmOSに秘められた下克上』 mizuno-ami
〜 Hackers Salon@Palm Source Japan Forum で ネタにして欲しい 〜
=======================================================
『ボタンをふたつ作ってそれぞれに簡単なコードを書き、全く重ねると、普通は上のボタンが動作すると思うのですが、全然動かなかったり、下が動作したりします。
そういうことってありません?』
NS Basicを使ったサイトを公開している私の元には、色々な質問が届きます。 この質問も、自称「専門家ではない」という専門家の方からでした。
質問の意味を考えた末、自分に素直に返答してみました。
「どういうキッカケで、そういうことを考えられたのでしょうか。そちらの方が興味があります。」
どういう状況で、ボタンを2枚重ねるんだろう、実は、これが一番の疑問でした。
そして、氏からの回答は、
「ボタンを貼って色々なコードを試しているうちに、画面がいっぱいになってきたので、
とりあえず、ボタンをまとめて1ヶ所に置いたときに、偶然気がついた」
という由の内容でした。
なるほど。偶然に、発見してしまったのですか。
理由を聞いても、ボタンを2つ重ねて使う状況が思いつきませんが、立場上、曖昧な回答もできませんし
興味もあります。早速、サンプルなど作ってみることにしました。
サンプルは簡単です。2つのボタンを用意して、一方のイベントモジュールとして
もう一方に
と記述するだけです。これで、1のボタンをタップすると「1」が、2のボタンでは「2」が表示されます。 これで、ボタンの位置と大きさを完全に重ねて、コンパイルします。これで、サンプルの完成です。
ボタンの上下は、フォームの上に、ボタン1、その上に、ボタン2、と重ねてみましたので、表面にはボタン2が 露出している形になります。
直感的には、表面にある側のボタン2が反応しそうですね。
さて、手元にある環境で、ひとまず試すとなれば、PalmOS4.0のCLIE N600C(以下、CLIE)と、PalmOS3.52Hの
VISOR Platinum(以下、VISOR)の2機種。NS Basicのランタイム(以下、ランタイム)は、最新版の Ver.2.10と、A.S.M.Ver.0.4.1.などに同梱のVer.2.05。
これらの組み合わせで、調べた結果、次のようになりました。
------+------+--------
2.10 2.05
------+------+--------
CLIE 2 2
VISOR 1 1
------+------+--------
この結果から、
・ランタイムのバージョンは、無関係かな?
・PalmOSのバージョンに関係がありそう
もし、ランタイムのバージョンに関係があるなら、私は、アーカーブしてある、歴代のVer.1.06以降の全部の 正規版とベータ版で試す予定でしたが、この結果で、内心、ホッとしました。
これで
「PalmOSのバージョン間の違いで、動きが違ってくる」
ということが確定的になってきました。 また、私を含めて、NS Basicユーザーさんの中には、
「PalmOS Ver.3.1とVer.3.5、つまり、VISOR Delux
と Platinumで動きが違う」
という話題を思い出される方が少なくないでしょうからね。
PalmOSのバージョン間の互換性は、表面上、気にならないほどの差異で、通常ではそれほど不具合を感じない 完成されたOSに思われます。(これは、某大手M社のアプリケーションは見習って欲しいものです。)
しかし、見知らぬ所で発生する動きの違い、これは、神様の一声で確定的なものになりました。
『これはPalmOS 3.5で仕様が変わったのだと思います。 それまでは下にあるボタンが優先されてしまっていたのを画面上で上にある(見えている)ボタンが
反応するようになったようです。』
偶然で発見してしまった動作の違い。しかし、PalmOSの3.5と4.0では、ボタンの上下関係が逆転するという、 「下克上」が、密かに、また、大胆にもこの掌の中で行われていたのです。
このような仕様の変化は、開発者サイドとしては、あまり望ましくない部類に入るものですが、開発者サイドも こういう事実があることを知っておくことが大切でしょう。
・・・・・・さて、ここで読み物としては、完結しているように思われます。が、実は、この下克上が あるアプリに影響を与えていた、というおまけをお届けしましょう。
これは、ある方からのバグレポートがキッカケでした。
要旨は『A.S.M.Ver.0.4.1で、欄に数字をGraffiti入力するとハングアップする事がある』との事でした。
公開から日数が経っていますが、はじめて聞いた不具合です。 まずは、再現を試みましょう。
・・・あ、見つけちゃった。
確かに、CLIEでも発生しました。再現性もバッチリです。
会社にCLIEの充電器を置いてきた自分には、HotSyncとリセットの繰り返しは痛かったですが、まずは、問題が 確認できたわけです。
さて、ご存知の通り、NS Basic上でGraffitiから文字を入力すると、スクリーンのイベントを発生させます。 したがって、スクリーン上の、どのオブジェクトにフォーカスがあっても、キー入力は1つのスクリーンイベントで
処理をしているわけです。そして、A.S.M.でもこれは同様です。 そこで、まずは、スクリーンのイベントをチェックしてみました。
A.S.M.には、左に10行の文字欄、右に10行の数値欄があります。
このうち、数値欄に数字を入力する処理は、Graffitiからの入力と画面上に配置したテンキーの両方をサポート していますので、スクリーンのイベントには「入力が数字だったら」という条件で処理を分けています。
そして、この条件に当てはまった時、内部的な配列変数の更新処理をしていました。
しかし、イベントが発生したのが「数字欄であるか?」という条件が抜けていたため、文字欄でGraffitiから 数字を入力すると、この条件が成立して、存在しない配列にアクセスするため、ハングアップしていました。
原因がわかれば、それほど修正は難しくありません。作業時間、約10分で修正完了です。
幸いなことに、質問された方と同じ環境、VISOR Platinumが手元にあり、修正されたことが確認できました。 良かった良かった。が、ふと、疑問が沸いてきました。
「なぜ、そんなことが発生したのだろうか?」
A.S.M.は、いわば、簡易版の集計票(足し算だけ)ですので、表計算をイメージしてみてください。
普通、値を入力するのに「カーソルがある位置」に入力しますね(当たり前ですが) しかし、このカーソル位置がずれている、という報告はありませんでしたので、疑問に思ったわけです。
そこで、もう少し、VISORで試してみると、意外なことが分かりました。
画面上で、文字欄や数字欄をタップしても、見かけ上、カーソルが移動しますが、内部的なフォーカスが変化していないのです。 A.S.M.は、ジョグやボタンによって、カーソルを移動させることが出来るように作りました。
しかし、NSBSystemLibを使っていなかった当時は、そのままでは、SetFocusくらいしか、フォーカスコントロールが出来ないため、
力技的にグローバル変数に、現在のフォーカス位置を持たせていました。 そして、移動の処理がくると、その変数の値を調整して、カーソルを移動させていたわけです。
じゃ、入力するFieldをタップしたときに、変数の値を変えれば?と思われますよね。
でも、Fieldオブジェクトは「フォーカスを失った時」イベントを発生しますから、今までどこにフォーカスがあったのか、 ということが分かっても「どこに移動したのか」が分からないという事になります。
そこで、こちらも力技で、Gadgetオブジェクトを、Fieldオブジェクトの上に貼りつけることにしました。 A.S.M.の画面上、文字欄と数値欄、合わせて20個のField、そして、その上にGadgetが20個が乗っていることになります。
Gadgetをタップしたら、それに対応するFieldがフォーカスを持っている、と変数を更新するわけです。
これは大きなアプリですが、なんとか実用上問題のない程度の速度が出せたので、公開することにしました。
さて、FieldにGadgetを重ねて使う力技・・・ここまできたら、お分かりでしょうか?
実は、ボタンで発生した下克上問題は、ボタンに限らず、全てのオブジェクトでも発生していたのです。
したがって、VISORでは、他の欄をタップしてカーソルが移動しても、内部的なフォーカスは移動せず、元の位置のままです。
そう、上にあるGadgetのイベントは、PalmOS Ver.3.5の「フォーム側にあるオブジェクト優先」という仕様に従って、
無視されていました。(これは、タップしてカーソル移動した後、ボタンなどで、カーソルを移動させると分かります。)
そのため、自分が数字欄に数値を入力しているつもりでも、内部的には、文字欄に入力していることがあり、それが、先ほどの ハングアップを引き起こしていたわけです。
ボタンを2つ重ねるなんて・・・という偶然の発見が、実は、自分のアプリに影響していたとは驚きでした。
小さなサポートでも、開発者には宝物かもしれません。そんなことを肌で実感した次第です。
|