カメラのDLL

とりあえず他人が読んでも分かるようにまとめてみます。


何ていう名前だったか忘れましたが、Squeak mapにwebカメラを扱えるライブラリが公開されています。
このライブラリが公開するVPCameraというクラスがwebカメラから画像を取ってきてくれます。
ただこれには、場合によっては結構致命的となりうる、問題がありました。


問題というのは、プラグイン内の処理が重いために、Squeakが一瞬止まってしまうというものです。
これは何もこのカメラDLLに限った話ではありません。


そこで先ず、Windowsレベルのスレッドを作って、その中でカメラを動かすということをやりました。
ただ、この時点ではスレッド間の同期を一切取っていなかったので、
取得するフレームが必ずしも最新でないという問題が起こってしまいました。
(前にも書いたように、起こることは最初から承知していたわけですが。)


で、次にスレッド間で同期を取る作業に取り組みました。


単純にWindowsセマフォーをSqueakに渡して、
それがシグナル状態になるのをSqueakの中で待つということは出来ません。
何故ならそれではSqueakが止まるという元々の状態に戻ってしまうからです。


というわけで、これとは逆に、
SqueakセマフォーをWindowsのスレッド側からシグナルするということが必要になってくるわけですが、
このカメラDLLはFFIで実行されるように作られているため、
基本的にSqueakの内部仕様とは独立しています。


FFIではなく通常のプリミティブとして作動させるようにするというのも考えたましたが、
個人的なビルド環境の問題とかもあって、ちょっと面倒臭そうだったので、
FFI経由のままでSqueakの内部に食い込むという方法を採ることにしました。


どうすればいいかというと、外部プリミティブがやっているように、VirtualMachine構造体を渡せばいいわけです。
ですが、どうすればこれを取ってこられるか分からなかったなので、
外部プリミティブにVirtualMachine構造体を渡す機構をそのまま利用することにしました。
つまり、最初は外部プリミティブとしてDLLをロードして、それ以降はFFI経由で扱うということです。
恐ろしく邪道なやり方だとは思いますが。。。


外部プリミティブとして作動させるには、やはりInterpreterPluginクラスが提供する
setInterpreterとgetModuleNameを実装すればOKでした。


で、同期するためのコードを書いて一件落着。