SVX日記
2004-12-24(Fri) どんなアクロバットか爆速起動……しかし
それはそうと、以前にPDFのビュアーであるAcrobatReaderについて書いた。主な論点は「起動するだけで数十秒って、何の権利があって貴重な私の時間を消費するんだ」と「紙の概念を何の考えもナシに画面に持ち込んでいるダケじゃねーか」ということである。
いや、上のコメントは怒り半分、嬉しさ半分である。基本的に、バージョンアップを重ねるにつれて遅くなるのはドアホのやることだと思っている。バージョンアップとはいえ、ソフトの基本機能が変わるわけじゃないのだ。せめて前バージョンと同じような速度で動くのは、法律として制定してもらいたいくらいである。
しかし速くなって文句を言うわけではないが、いくらなんでも「速すぎる」ぞ。特に2度目の起動の速さときたらサギレベルである。むー、どんなマジックを使っているのであろうか? ウワサによると爆速起動を担うミドルウェアにはスパイウェア疑いがあるという話も聞くがホントだろうか? むー、今のところ便利に使えてはいるが若干引っかかるトコロではある。
それはそうと、高速化についてはそれでもいいが「紙の概念を何の考えもナシに画面に持ち込んでいるダケじゃねーか」ということについてはナニも変わってはいない。この点についてはPDFのデータの都合上、どーにも改善できないのであろうか? というか、そもそもナゼオイラは「紙の概念」が不便だと思うのか? この点についてもう少し掘り下げてみると意外なコトに気づいた。それは「ページを開いたまま次のページが見られない」ということである。つまり「紙の概念」というよりは「冊子の概念」であることが、使い勝手の悪さを助長しているということだ。
これを解決する方法は単純で「ウィンドウ内ウィンドウ」をヤメればよい。こんなのイマドキ流行らないっつーの。エクセルだってワードだって、いつの間にかヤメているのだ。そもそも、このワケのワカらん概念は初期のウィンドウズの仕様を引きずっているだけなのだろ? まったくアホくさい。頼むから、同じ文書だろうがジャカスカと別ウィンドウで開いちゃってくれ。
いっそ「しおりアイコン」をデスクトップ上に置けるようにするというのはどうだろうか? PDF内の特定のページへのショートカットのようなものである。それを実行することで即座に特定のページが別ウィンドウとして開く。既にそのページが開いている場合には「それをアクティブにする」という動作でもよいだろう。「しおりアイコン」の操作方法としては「ページをつかんでデスクトップにドラッグ」で決まりだ(もしやデキるかも!?と思いやってみたがやっぱりダメだった)。これにより「冊子の概念」は「バインダに綴じられたマニュアルの概念」へと昇華するのである。
2014-12-24(Wed) 敢えてオーバフローしちゃうリングバッファ
先日からXBeeをAPIモードで使うべく、ごちゃごちゃとやっていたのだが、APIモードだと不特定のタイミングでドカッとAPIデータフレームが到着してしまうので、割り込みを使ってシリアル受信しないと、取りこぼしまくってしまうことに気がついた。
割り込みを使って受信するならば、リングバッファしかないよな、と思ったのだが、XBeeのAPIデータフレームは結構大きく、間欠動作、かつ、メモリ効率を考えると、バッファオーバフローの発生を考慮しないわけにはいかない。しかし、どのように考慮するのか? オーバフローを検知して、受信を抑制すれば、新しいフレームを取りこぼしてしまう。ならば、古いデータから捨てていくべきか? いずれにせよ、どちらかをあきらめる必要がある。
考えた末、今回の結論は「オーバフローを考慮しない」となった。読み書きのポインタは丸めずに走らせておいて、リングバッファにアクセスする時だけ、剰余を取ってからアクセスする。まさに「オーバフローを考慮しない」だけ。判断が必要ないので動作も軽い。
これにより、トータルで受け取るバイト数をそのままに、化けたデータや、重複して同じデータフレームを読んでしまう、という仕様となる。言い方を変えると、スタートデリミタとチェックサムの効用により、途中のデータフレームは取りこぼしてしまうが、最後に送信されたデータフレームは正しく受け取れる、という仕様となる。いいじゃん。
#!/usr/bin/env ruby
class LappedRingBuffer
attr_reader :buf
def initialize(size = 16)
@size = size
@buf = []; @size.times {
@buf << '..'
}
@wp = 0; @rp = 0
end
def write(dat)
@buf[@wp % @size] = dat
@wp += 1
end
def read
if(@rp != @wp)
r = @buf[@rp % @size]
@rp += 1
end
r
end
end
buf = LappedRingBuffer.new(16)
p buf.buf
frame = 'A'; 4.times {
(0...10).each {|d| # write n frames
buf.write('%s%d' % [frame, d])
}
frame.next!
}
p buf.buf
dat = []; while(d = buf.read)
dat << d
end
p dat
["..", "..", "..", "..", "..", "..", "..", "..", "..", "..", "..", "..", "..", "..", "..", ".."]
["D2", "D3", "D4", "D5", "D6", "D7", "D8", "D9", "C4", "C5", "C6", "C7", "C8", "C9", "D0", "D1"]
["D2", "D3", "D4", "D5", "D6", "D7", "D8", "D9", "C4", "C5", "C6", "C7", "C8", "C9", "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7", "D8", "D9", "C4", "C5", "C6", "C7", "C8", "C9", "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7", "D8", "D9"]