11/18追記:Vectorでの登録が遅れています

Vectorに登録申請したものの、音沙汰がありません。
正直最近のVectorさんは大分困ったさんです*1


自分のサーバ(レンタルですが)でソフトを管理するのは
セキュリティ上危険だと認識しているので、もう少々お待ちください。


あと、英語環境だとちょっと文字化けするみたいですね。
私個人は英語だとPainterがまともに動かないので試したこともなかったのですが...
対応検討します。

*1:ナビゲーションが赤点もの。トップページから「ソフト登録フォーム」のページにいく方法が分からない。というかライブラリに行く方法もよくわからない。

Rb2007の継承が、ちょっと変だ

Rb2007(r3/r4)だと、変。

r3でREALbasicにもJavaで言うところのパッケージの概念が導入されました。
ところが、この実装が凄く中途半端な気がします。

実例

  • ModuleAを作成
    • ModuleA.ClassAを作成
    • ModuleA.ClassAにコンストラクタ"Sub Constructor()"を宣言(中身は空でok)
  • ModuleBを作成
    • ModuleB.ClassBを作成
    • ModuleB.ClassBのスーパークラスをModuleA.ClassAに設定
    • ModuleB.ClassBにコンストラクタ"Sub Constructor()"を宣言

すると、ModuleB.ClassBにコンストラクタの中身がRbによって自動的に補完されます。

スーパークラスのコンストラクタを忘れずに呼びましょう、といっているようです。
このおせっかいサポートはRb2006の頃からずっとなので、別に問題はないのですが、
なんというか、これが、そのままだと動きません。
ビルドすると→

「そんなメソッド知りませんが?」とかいわれる。
そのコード書いたの、私じゃないんだけど

要するに

RbのSuperの実装が、バグッテル

回避法

キーワードSuperをやめて、ModuleA.ClassA.Constructorって書けは、
一応回避はできます。

うーん..めんどうだねぇ

なんとかして><

Intel入ってみたので、絵箱の猫はカラーにしてみる


絵箱は猫がポイントなのですが、この猫が「やたら口が大きい」と時々言われます。
確かに...
そんなわけでカラー化をもくろんでみました。

次のバージョンは4にしようと思っていたのです。
でも、よくよく考えたらそんなに機能的な進化点は
ないから、自重してver3.5にしようかと思い直し中。

ここへ来て、絵箱が条件によって不安定になる原因を
一つ見つけてしまったので、少し抜本的な構造改革
してから出そうと思います。


一応予定している変更点

  • Intel対応
  • Spotlight検索
  • アイコンがカラーに
  • 大量ファイル一覧時のメモリ使用量をまともに
    • サムネイルさえついていれば実消費メモリは40MB位で動きます
  • 安定性向上
  • その他細かいの色々

もし要望があれば

コメント等でお願いします。

REALbasicのCancelCloseとかDesutructorとかまとめてみた

Rbを普通に使っていると、後片付けのことをほとんど気にしなくてよいのだけど、
色々付け足して、終了時に設定保存したり、「本当に終わっちゃっていいの?」って
聞いたりしていると、たまに動作が不安定になることがあるのです。


というか、今の絵箱(ver3.2.1)がそれ。
たまに、終了時にエラーはいたりするのです。


というわけで、整理!
REALbasicのいろんな後片付けイベントの呼び出し順をまとめてみました。
使ったのはREALbasic2007r4。

準備

順番を調べるもの :

  • Appオブジェクト
    • CancelCloseイベント
    • Closeイベント
    • Destructor*1
  • Windowオブジェクト
    • CancelCloseイベント
    • Closeイベント
    • Destructor*2
  • Appにプロパティとしてセットしたオブジェクト*3
    • Destructor
  • Windowにプロパティとしてセットしたオブジェクト*4

これら7個のイベント、メソッドの呼ばれる順番を調べます。

結果

  1. App.CancelClose
  2. MyWindow.CancelClose
  3. MyWindow.Close
  4. MyObjOnWindow.Destructor(::MyClass)
  5. MyWindow.Destructor
  6. App.Close
  7. App.Destructor
  8. MyObjOnApp.Destructor(::MyClass)

考察

基本は当たり前に「参照する側」→「参照される側」の順番で解放される。
でも、Windowはちょっと特別扱い*5
WindowはApplicationクラスからは(REALbasic的には)参照されていない。

だったらどうなの?

  • WindowのCloseとかデストラクタから、Appを操作するのはOK
  • AppのCancelCloseからWindowを操作するのもOK
  • AppのCloseからWindowを操作するのはNG*6
  • Appのプロパティ(間接的にでも)であるオブジェクトのデストラクタからAppを操作するのはNG

のはずが、死んだAppにアクセスできる!

なぜかApp.Destructorが終了した後も、Appにはアクセスできる...

これってありなの??

Appのデストラクタで後片付けしたつもりが

その後、別なオブジェクトのデストラクタのせいで、Appをさらにいじられる可能性がある...

Window以外のデストラクタで

Appを呼ぶのはやめよう。組み方次第で何が起こるか><
デストラクタは自分の後始末をする物だから、Appに頼るのがそもそもいけないのか。



*1:Destructorの呼び出しを検出するために、このAppはApplicationクラスの直下サブクラスではなく、Application継承のカスタムクラスのインスタンスにする

*2:これも*1のAppと同じ

*3:Objectの直継承

*4:これもObjectの直継承

*5:マニュアルにも記載があるし、確かにそうあるのが好都合なのだけど、合理的な説明は思いつきません

*6:この「操作」のためにWindowの参照を保持しておけば、Window.Destructorの実行は延期される。けど、既にCloseしてしまっていることには変わりないので、下手に触るとNilObjectExceptionか、最悪無言で落ちるようです。

円グラフすら描けなかったのか

ということに今更改めて気づいた。

なんでかREALbasicは円弧を描けない。
円弧なんてQuickDrawの時代から当然のように描けたはずなのに

仕方がないから、作ってみました。

DrawArc.rbp

使い方

  • サンプル見てください。簡単です
  • メソッドはDrawArc , FillArcの二つだけ
  • 実体はRb標準のDrawPolygonです。ので、あんまり速くないです。
  • 実装がしょぼいので、誰か手直ししてください
    • 縦横比が微妙なとき、線が汚いかも。どっかで誤差してる??

って後半使い方じゃないし。

改変自由の著作権表示も強制しないぬるいライセンスにしときました。
別にライセンスとかどうでもいいんだけどね


折角だからExtendsキーワードを使いたかった。

GraphicsExtension.DrawArc Window.Graphics,0,0,100,100,30,120でもいいけどさ、
Window.Graphics.DrawArc 0,0,100,100,30,120 って描けたら、すごくいい。

GraphicsはExtendsできなかった...

そっか、Graphicsは抽象クラスだった。
Extendsはインスタンスとメソッドを擬似的にリンクさせる文法糖だから、抽象クラスには使えないわけです。
その理屈は、わかる

わかるけど

Rbが隠蔽しちゃって、Graphicsサブクラスの本当の名前がわからない...


むー...

絵箱をUnversalBinaryしてみるテスト

今更ですか、REALbasicが直販になったので、「REALbasic 2007 Release 2」を入れてみる。
とりあえずトライアルモードで。

早速比べてみよう。使うのは

  1. 絵箱3.2.1PPC
    • 今公開しているバージョン。Rb2006r3でビルド
  2. 絵箱3.2.1Intel
    • そのままRb2007r2でひらいて、UniversalBinaryとしてビルドし直したもの

の二つ。MacはiMac2.16GHz Intel Core2 Duo、メモリ1GB

TEST1 サムネイル作成速度

準備
  1. 予め絵箱環境設定でサムネイルサイズを256*256ピクセル(最大)に変更
  2. 470枚のJpeg写真(640*480〜1280*960まで色々)すべて選択
テスト
  1. ファイルメニューから「プレビューを作成」

具体的な処理内容は

    • メモリへの画像展開(QuickTime使用)
    • リサイズ
    • リソースフォークへの書き込み(...時代を感じるなぁ)

絵箱PPC 50sec
絵箱Intel 30sec

TEST2 画像表示

準備
  1. iMac(OS10.4)付属のデスクトップピクチャ「Nature」フォルダを開く
  2. 14枚の画像(2560*1600ピクセル)をすべて選択
テスト
  1. ダブルクリックで、開く

具体的な処理内容は

    • メモリへの画像展開(QuickTime使用)
    • リサイズ
    • 画面表示(+タブアニメーション)

絵箱PPC 21sec
絵箱Intel 16sec

TEST3 画像処理(RbScriptによる演算)

準備
  1. iMac(OS10.4)付属のデスクトップピクチャ「Nature」からクマノミの写真2560*1600ピクセル)を開く
  2. 「画像」メニューから「プラグイン」>「なみ」を開く
  3. 設定値を「波の高さ=60,波の周期=20」にする
テスト
  1. 実行

具体的な処理内容は

    • ピクセルごとのメモリコピー
    • 簡単な演算
    • ちょっとだけディスクに書き込み(取り消し用の履歴)

絵箱PPC 10sec
絵箱Intel 7sec

結論

大体30%前後の高速化。体感的にもそのくらい。
なにも修正してないのに、結構早いよ。

あと、

バグが幾つか直ってた。

ということは

買いでしょうか?

Dictionaryをシリアライズしてみる



やっぱりシリアライズは鬼門?

どうもRbユーザの結構な数が、データのシリアライズに苦労しているみたい。
Key=Value形式のテキストで保存して、改行のエスケープ忘れてファイル壊しているような人もいるし...
初心者さんにやさしいはずのREALbasicがこんなことでいいのかなぁ

作ってみた

ちょうど必要だったから、作ってみた。
Dictionaryを丸ごとファイルに書き込みます。
数値系、文字列、色、日付、真偽、とDictionay。
入れ子になったDictionaryを型や構造を保ったまま、まとめて一気に保存できるので便利。
MemoryBlock使ってるから、まあそこそこの速さです。

もともと絵箱で使ってたコードをきちんとクラスにしただけだけど。

使ってみた

Dictionary継承だから、使い方も簡単


Sub App.Open
//新しいファイル作成。既存なら自動的に読み込み
Dim Pref as NekoDictionaryFile(DesktopFolder.Child("MySetting.pref"))

//後は普通のDictionay
//Pref.Value("foo") = "bar"とかご自由に

//保存
Pref.Save
End Sub

Dictionaryも保存できるよ。
たとえば、追記型日記帳。


Dim Diary as NekoDictionaryFile
Dim Dict as Dictionary
Dim D as Date

//日記帳を開く。なければ作る
Diary = New NekoDictionaryFile(DesktopFolder.Child("日記帳"))

//空なら初期値設定
If Diary.Count = 0 Then
Diary.Value("Title") = "ユキの日記帳"
Diary.Value("TopPage") = "http://hatena.ne.jp/Mattsun/"
Diary.Value("Contents") = New Dictionary
End If
Dict = Dictionary(Diary.Value("Contents"))

//今日の日記を追加
Dict.Value(new Date) = "http://hatena.ne.jp/Mattsun/20070512" //今日の

//保存
Diary.Save

感想

意外と感動した。ファイルとDictionaryが一対一に対応してるとなんとなく安心感。
いやむしろ、この程度で感動できるREALbasicに感動した。

ダウンロード

http://nekobooks.com/tools/nekodict/NekoDict.zip

  • 細かいことはソース読んで下さい。
  • ライセンスとかどうでもいいので、好きに使ってください。
  • Rb200X対応でちょっと手を入れたのでバグ混入してるかも。自己責任で
  • Rb2006以降 Mac/Win両対応。圧縮はWinでしてます