2/10/2011
CppCheckの雑感
11/06/2010
Google C++ Test Framework
最近Google C++ Test Framework(以下googletest)を いまさら 導入してみました。
googletestはxUnitの流れをくむTestのFrameworkで少しでもxUnit系のテストについての知識があれば、すぐに使えるという触れ込みです。とりあえず公式な情報を翻訳したサイトで勉強すれば、何とかわかります。ちょっと面白いのは、OpenCVのドメインでGoogleTestDocsの日本語訳がホストされていることかなぁ。
肝心の使い方は、公式に書かれているので、割愛しますが、ちょっと読み解くときに面倒に感じたことをいくつか。
- メジャーなコンパイラのためにはすでに特別なプロジェクトが用意されているので、それを利用すること。MSVCとかG++とかは用意されているので、それを利用すればいいので、Cmakeを利用しなくてもいいこと。ただしCmakeを利用した生成もサポートされているので、そちらを利用してもいい。
- MSVCに限らないと思うが、Runtimeの種類で別のSolutionが用意されている。たとえば、マルチスレッドとマルチスレッドDLLで別のRuntime体系になるので、別のSolutionが用意されていて、基本的にはマルチスレッドになっている。なので、MSVCの人でMDdとかMDのRuntimeを使う人は、gtest_md.slnを利用する。
- MSVCはテスト用のプロジェクトにgtest.projもしくはgtest_md.projをプロジェクトに含めて、テスト用のProjectはその追加したgoogletestのProjectへの依存関係を作ることが必要である。
- TEST_Fを使う場合には事前に::testing::Testクラスを継承したクラスをつくる必要性がある。TEST_F(test_fixture, test_name)でtest_fixtureの部分には利用したい::testing::Testを継承したクラス名を使う。またTest部分ではクラス内部のように変数を扱ってテストできる、はず。
- ::testing::Testの仮想メソッドにはSetup(),TearDown()があるが、名前は厳密に継承元にある奴でないと動作しない。(当たり前) またそれぞれのクラスの利用のタイミングであるが、それぞれデフォルトコンストラクタやデストラクタでは利用できない仮想メソッドや例外が発生しやすいメソッドの利用などの場合には、利用する価値が出てくると思う。この質問に対する回答もある。
10/08/2010
Code Kata的な 練習
// Kata000.cpp : コンソール アプリケーションのエントリ ポイントを定義します。
//
#include "stdafx.h"
#include
#include
#include
#include
#include
void foreachMethod(const size_t& size)
{
boost::progress_timer t;
using namespace boost::lambda;
using namespace std;
vectortmpArray(size);
tmpArray[50] = 200;
boost::progress_display show_progress( tmpArray.size());
for_each(
tmpArray.begin(),
tmpArray.end(),
(_1 + 1) );
}
void forMethod(const size_t& size)
{
boost::progress_timer t;
using namespace std;
vectortmpArray(size);
tmpArray[50] = 200;
boost::progress_display show_progress( tmpArray.size());
for( size_t i = 0; i < tmpArray.size(); i++){
int itt = tmpArray[i] + 1;
++show_progress;
//cout << tmpArray[i] << endl;
}
}
void foriterMethod(const size_t& size)
{
boost::progress_timer t;
using namespace std;
vectortmpArray(size);
tmpArray[50] = 200;
boost::progress_display show_progress( tmpArray.size());
for(
vector::const_iterator i = tmpArray.begin();
i != tmpArray.end(); i++){
int itt = *i + 1;
++show_progress;
//cout << *i << endl;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
const size_t size(1000000);
foreachMethod(size);
forMethod(size);
foriterMethod(size);
return 0;
}
とりあえずいえるのは、VS2008のReleaseならforeachがはやい。Debugならforが早い。とりあえずどれでもイテレータは遅い。でもこの場合に重要な点は、こんな単純なケースで通常のイテレータ回しはあまり有用ではない、という点と、イテレータでの制御はもっと凝ったもののほうがいいかもしれない。とりあえずforeachすげー。投げる要素数が増えるとかなり露骨に早くなる。
9/18/2010
WinSxSについて
今日はVC++2005から導入されているManifestについての再配置について。
VC++2005以上でコンパイルされたプログラムは、以前存在していたDLL地獄に対応するために、ManifestによるDLLの選択という機構を取り入れました。
これによって起こっている問題は、VC++2003以前でコンパイルして、配布する際には、プライベートアセンブリや共有DLLは同名のDLLファイルが存在していれば、動作できるのです。しかし、これは正しいDLLかどうかは保障されませんでした。DLL地獄の本当のところは調べれば出てきますので、割愛します。
とりあえず手っ取り早く配布をしたい場合には、以下の手順を踏めばいけます。
・VSコマンドプロンプトでmt.exeを動作させます。
・mt.exe -inputresource:
・分離されたManifestに記述されているDLLを集めます。
・DLLの場所はVisualStudio/VC/redistのところにある場合とWINDOWS/WinSxSにあります。そこから該当するものを取得します。
・WinSxSの場合には、該当するDLLとそのDLLに合致するManifestが必要になります。ManifestファイルはManifestフォルダにあります。ここから取得します。
・アプリケーションを入れるディレクトリにEXEとDLLと同じフォルダ内に、最初に取得したManifestのName属性に記述されている名前と合致するようにフォルダ名を変更して、そこにDLLとそのDLLのためのManifestを入れます。
これでたいてい動きます。それでもWinSxSのエラーが出るときには、コントロールパネル:コンピュータの管理:イベントビュアーにエラーログがでますので、そこから、問題のDLLを調べることができます。
またmt.exeを利用しなくても、VSのソリューションにExeやDLLを登録して、開くとリソースビューが開き、MT_MANIFESTとかかれている項目があります。そこにEXEなら1、DLLなら2と書かれた項目が格納されていますので、それを開きます。その際に表示された文字列が埋めこまれたManifestになります。これは最初に分離したものと同じになります。
またMSDNで記述されているようなDLLのライブラリをフォルダに入れて云々は、Manifestファイルに記述されていない際には、EXEと同じ階層に置くようになりますので、この方法から除外されます。しかしながらDLLのManifestのほうも問題がありますので、そこも要調整になります。
6/27/2010
DBの覚書
DBの開発に関する選択肢として、Access、SQLite、PostgreSQLを挙げてみる。
AccessはMicrosoftの製品であり、比較的容易にデータベースを構築出来る。
SQLiteはPublicLicenseであり、ソースもすべて手に入る。
PostgreSQLも似たようなものだが、最近人気になりつつある?MySQLがライセンスが変更されたことによる代替か?
AccessはRDBMSではあるらしいが、データベーストリガとストアドプロシージャがない。
SQLiteはアプリケーションに組み込んで使うタイプのDBMSである。
PostgreSQLがRDBMSとして手軽に利用できるもののようであるが、よく分からない。
RDBMSはコッドの12の法則に準拠してることが必要らしい。
ACIDとかいろいろ定義はあるんだろうけど、DBをやるなら本気で腰をすえていろいろいじらないとTuneUpできそうにない。
SQLite
MicrosoftAccess
Firebird
関連データベース管理システム
6/21/2010
拡張保護を使用した統合 Windows 認証ってなんだ?
http://msdn.microsoft.com/ja-jp/library/dd639324(v=VS.90).aspx
http://msdn.microsoft.com/ja-jp/library/dd470100(VS.95).aspx
Extended Protection for Client Applications
4/25/2010
SilverlightにおけるCustom Content Control
どうもJudaです。
Silverlight Custom Content Control
まさに掲題のとおり、Contentを表示したい時があります。
けれども簡単に行う方法はよくよく調べないとわかりません。Custom Template Bindingもひとつの手ですが、それもそれでなかなか大変なのです。(本当か?
Silverlight 2 のカスタム コントロールを作成する
うん、なんかいろいろめんどくさい。
3/27/2010
HgInitの試訳
どうもJudaです。
JoelがMercurialの入門手引きを書いたので、かっとなって日本語に訳してみた。最初の頁のとちゅうまでだけどね。
--以下訳--
私の会社にいるプログラマたちがSubversionからMercurialへ乗り換えることを決めたとき、ジョエル少年は混乱してしまった。
はじめに、あらゆる乗り換えるべきでないくだらない理由に付き合ってくれた。”私は中央サーバにリポジトリを保持すべきであり、それが安全だと思う。””君はしっているのか?君はあまり詳しくないだろうがMercurialでは全ての開発者が自らのハードディクス上にリポジトリ全体のコピーをもつんだよ。それは実際にはより安全だろう。なにより、大抵のMercurialを採用したチームは中央サーバもつかうし、君がBackupをとらなければならないという強迫観念にかられるようなら、そうしよう。また君は3層にもなるセキュリティー、Cylons、Stromtroopers、またはをささやかな開放的な領域を構築できるよ。"
"煩雑なバージョン管理によるトラブルはブランチすることによってすぐに起きてしまうし、ブランチをつくることは常に問題を起こす。””結局この考えも良くない。いずれ悪い結果がおきる。Subversionでブランチすることは問題を発生するのは、Subversionはマージ処理をおこなうのに十分な情報を持っていないからだ。Mercurialでは、マージは苦痛じゃないし、簡単だ、そしてブランチはありふれたことだし、害もない。
”そいつはいいね、つかってみるよ。でもとても僕には理解できるようには思えないよ”僕はJacobにMercurialでSubversionで行っていた事と同等のことをできるようにCheatSheetをつくってくれるように頼んだ。
いま、私はこのCheatSheetを君にみせれる、でもしない。それは数カ月のものあいだ混乱のもとだったからだ。
結局のところ、Subvesionをつかっていたとしよう、それは君の脳をすこし、えっと礼儀正しく言うにはどうすればいいのかな。その、イカれちまってる。おっとこれはよくない。君には少し再教育が必要になる。私が半年の間MercurialがSubvesionよりも複雑だと考えることによってイカれちまった部分を探してみた。でもそれは私がMercurialがどういう働きをするのか理解していなかったから、一度分かれば、ちんからほい、Mercurialはある意味簡単だ。
だから私は君のために手引書を書いている。この手引書では、慎重にSubvesionの意味で説明しないようにした。それもこれ以上の混乱のもとをなくすためだ。もう混乱のもとはたくさんだ。代わりにSubvesionからきた人たちのためにMercurialを勉強するために可能な限り綺麗な状態に戻そうと一章つかってやってみようと思う。
Subvesionを使ったことがないのなら、次の章にいくといいよ。見逃さないでね!
準備はいい?いくよ。ここで簡単なクイズ!
Q1. 初回で完璧なソースを書けますか?
もし君がはいと答えたら、君はとんでもない嘘つきだし、詐欺師だ。君は失格。また試験を受けてくれ。
新しいコードはバグに満ちている。ちゃんと働かせるには、すこし時間がかかります。その間の時間、チームの他の開発者の苦痛になります。
このとき、Subvesionはどのように働くか、
新しいコードをチェックインするとき、みんなトラウマコードを取得します。
君の書いた全ての新しいコードはバグだらけですので、君は悩みます。
バグのあるコードをチェックインして、他の開発者に苦痛を与える。
バグがなくなるまでの間、チェックインをしないようにする。
Subvesionは常にこの苦しいジレンマを起こします。リポジトリはバグで満ちている。新しいコードを入れてもバグを含むし、また新しいコードを管理しないならそれもバグだ。
Subvesionをつかうひとなら、このジレンマが存在しないことを想像できないでしょう。
Subversionをつかうチームはしばしば何日もあるいは何週間も何もチェックインしないことがある。Subversionチームでは、新入りはあらゆるコードをチェックインすることを恐れる。ビルドを壊してしまうこと、つまり年長の開発者のマイクさんやそういったお歴々を怒らせるを恐れる。マイクはすぐにチェックインによってビルドが壊れたことに腹を立てて、インターンのいるパーティションまでやってきて、彼の机の上のものを全部払いのけて、「てめぇはクビだ!」と叫ぶでしょう。(もっともそうならなくても、哀れなインターンはパンツを濡らしちゃいますけどね。)
あらゆるこの種のチェックインに関するおそれはみんながコードを何週もの間バージョン管理のご利益を得ずにソースを書くことをいみし、そしてこの状況に気づいたある年長の開発者がそれらをチェックインするように助けて回る。
どうしてバージョン管理が使えないのに、バージョン管理を導入したいと考えるだろう。
--ここまで訳--
確かにSubversionのジレンマはそのとおりだと思う。しかもこれでブランチを作りまくれば、まぁ大変になるのも仕方なし。とりあえずはやく全部読む。
3/24/2010
3/23/2010
いきなりSilverlightというか、WPFというか、
Bindingで使われるDependencyPropertyの話をMSDNの項目からかなり抜粋するが、
細かな部分だが結構込み入った使い方をする。
依存関係プロパティは、DependencyObjectに存在するPropertyのことで、
DependencyObjectプロパティストアに格納されている。
このプロパティストアを所有するDependencyObjectは、
public static readonlyで修飾されるDependencyProperty識別子を使って、識別される。
この依存関係プロパティを実装しようと思うと、通常のプロパティ(CLRプロパティ)をラップする必要性がある。
この依存関係プロパティがなぜ「依存関係」プロパティというのかという一因は、
あるプロパティが別のプロパティを値としてい持てるからであり、
実行時までその値を評価するのを遅延させることができ、
そのことによってプロパティに依存関係を作ることができるからである。
これはBindingとも関連する。
このプロパティを記法は似ているが、異なる添付プロパティが存在する。
例えば、Canvas.Leftのような個別のオブジェクトが所有していないプロパティである。
この添付プロパティの実装は、依存関係プロパティと似ているが、
設定された値が、自身ではなく、要素に対する付加的な意味合いがある。
カスタムしたイベント群を作っていこうと思うと、後半の添付プロパティをうまく使っていかないと、
XAMLで楽をできない。
ましてや、サポートされていない機能であるDrag&DropやDoubleClickの基本構造を適応していこうと思うと、
添付プロパティを使わなくてはとてもコーディングできると思えない。
ただイベントの登録をどうするのかが若干困りものではある。
大まかにはわかるのだが、
Propertyとして設定しようとして
そのプロパティを呼び出したときのオブジェクトを知らせてくれるならば、
オブジェクトとともにイベントハンドラを持てばいいのだろう。
関連付けさえうまくできればなんとかできそうではあるが、煩雑なことにはかわりない。
あとはListBoxからのDrag&Dropに関しても、内部で取得されるItemsSourceが不定であるので、
Converterを指定し、さらにDrag時の描画や、Dragのイベントなどの処理まで考えるとうんざりしてしまう。
ちょうどいいことにライブラリはあるのだが、Telerikのライブラリいいんだけど、10万も出せません><
でもこの機能で10万は安い買い物だと思います。
ちなみに体験版もあるので、ぜひ!
1/23/2010
WPFって?
今さらですが、
Windows® Presentation Foundation - Microsoft
Windows Presentation Foundation - Wiki
まぁSliverLightの基礎的なフレームワークなんですけど、
これは既存のWindowsのFrameworkから脱却する目的で開発されているので、MFCとは違いますし、.net Frameworkとも違います。まぁ.netとはとても近いですけどね。
重要なのはこれがまぁ新しいフレームワークで、なおかつDesktopとWebをそれほど区別しない点、UIとLogicの分離をフレームワーク的に強制するところです。
これによってMVCのような粗な結合を作ることが推奨されますし、これによってOOP、テストの導入などがしやすくなると考えられます。しかしこれは、ある程度以上の興味と技術をもっていないと上手くいかないので、学習コストをそれなりに払う必要があると思います。
もっとも悲しい事例をあげるなら、すべてが無理やり結合されている。もしくはそれに近い状態におかれることでしょう。例えるなら果物ナイフで巨木を切り倒すようなことにならないように、適宜道具の吟味とその使用法を確認する必要があります。
WPFはC#とVBから利用できる点も特筆しておきたいです。
NVIDIAのCUDAを利用したSolution
とりあえずこれを見てほしい。
NVIDIA「OptiX」エンジン発表、GPUでレイトレーシングを高速処理
NVIDIA® OptiX™ ray tracing engine
引用、ただし体裁は変更。
System Requirements
- Operating System: 32 or 64-bit versions of Windows XP, Windows Vista, Windows 7, Linux
- CPU: x86 compatible
- System Memory: matches graphics board recommendations
- GPU*: NVIDIA Quadro FX or NVIDIA Tesla (GT200 class required for multi-GPU scaling and technical support)
- Frame buffer memory: varies with data complexity
- Driver: NVIDIA Unified Driver r190 or later, CUDA toolkit 2.3 or later
- C/C++ Compiler: Visual Studio 2005 or 2008, along with CMAKE
- NVIDIA GeForce to be supported with NVIDIA's upcoming "Fermi" GPU architecture- see OptiX 2 Beta.
以前は40万からしかOptiXを実行することができなかったのですが、今回は2万円のGPUでも実行可能らしいので、とても楽しみです。
これはCUDAベースのライブラリ群です。開発用にSDKを取得するのは、ちょこっと登録すればダウンロードできるので、オッケーです。
でもGPUをまだ買ってきていないので、実験すらままなりません。どうしましょう、どうしましょう。
1/16/2010
TracかRedmineかそれが問題だ
プロジェクト管理ツールとして、Tracを採用するか、それともRedmineを導入するのか、思案中。
CVSがMercurialとSubverisonを併用しているので、両方扱える方がいい。
また導入しやすくて、当面はローカルなサーバーとして運用できる方がいい。
この二つの条件から考えると上記の二つに絞れるのだけど、まだ別の選択肢もあるのかなぁ。と思う。
ちなみに会社のPCに試験的にTracは導入してみた。Trac Lightingではないので、導入に戸惑ったがSubversionの導入はそれなりに簡単にできた。でもHgとの連携のためのPluginの設定方法が分からなかった。とりあえず管理画面からできるという情報を入手したが、まだよくわからない。
Redmineはとりあえず調べなければ、うむうむ。
1/10/2010
ソフトウェアテストについても並行して学習開始
『体系的ソフトウェアテスト入門』
『ソフトウェアテスト293の鉄則』
を買ってきた。
これでソフトウェアテストについて勉強を並行して開始。開発サイクルと言う考え方を適応するならば、開発フェーズとテストフェーズは隣接しているので、一緒に勉強するのはとっても重要!って言ってみる。
12/23/2009
理由はわかっているけれど、やってしまう間違い
今日はXMLシリアライズな話
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Serialization;
using System.IO;
using System.Xml.Serialization;
namespace SerializeDaemon
{
class Program
{
static void Main(string[] args)
{
XmlSerializer xmlSel = new XmlSerializer(typeof(Deamon));
StringWriter wStrm = new StringWriter();
Deamon hoge = new Deamon();
xmlSel.Serialize(wStrm, hoge);
Console.WriteLine(wStrm.ToString());
}
}
public class TestA : ISerializable
{
protected int m_id = 0;
public TestA() { }
public int Id
{
get { return m_id; }
set { m_id = value; }
}
#region ISerializable
protected TestA(SerializationInfo info, StreamingContext context)
{
m_id = info.GetInt32("Id");
}
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("ID", m_id);
}
#endregion
}
public class TestB : TestA
{
public TestB() : base() { }
protected TestB(SerializationInfo info, StreamingContext context) : base(info, context) { }
}
public class TestC : TestA
{
public TestC() : base() { }
protected TestC(SerializationInfo info, StreamingContext context) : base(info, context) { }
}
public class Deamon : ISerializable
{
TestA m_id0;
public TestA Id0
{
get { return m_id0; }
set { m_id0 = value; }
}
TestA m_id1;
public TestA Id1
{
get { return m_id1; }
set { m_id1 = value; }
}
TestA m_id2;
public TestA Id2
{
get { return m_id2; }
set { m_id2 = value; }
}
public Deamon()
{
m_id0 = new TestA();
m_id0.Id = 100;
m_id1 = new TestB();
m_id1.Id = 4000;
m_id2 = new TestC();
m_id2.Id = 6000;
}
protected Deamon(SerializationInfo info, StreamingContext context)
{
m_id0 = (TestA)info.GetValue("ID0", typeof(TestA));
m_id1 = (TestA)info.GetValue("ID1", typeof(TestA));
m_id2 = (TestA)info.GetValue("ID2", typeof(TestA));
}
#region ISerializable
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("ID0", m_id0);
info.AddValue("ID1", m_id1);
info.AddValue("ID2", m_id2);
}
#endregion
}
}
コンパイルは通るけれども、実行はできないソースコード。
問題点は、シリアライズ対象のクラスがもっている要素に継承クラスが代入されていること。これはシリアライズにおいて、とても大変な問題をはらんでいる。
サブクラスをシリアライズする方法なんてわからないのだから。
シリアライズという行為が現状を復元可能な形で保存することにあるときに、継承クラスかどうかの判定なんて誰がどうやってするんだろーって事で原理的に今は無理です。柔軟に対応しないといけないならば、むしろ別の方法でそれを実現する方法を探す方が賢いと思います。あるいはできるなら、それを教えてください。
とりあえずは素直にすべての要素が構造体で定義されているものをシリアライズするコンテナクラスとして使用しましょう。というお話です。
細かな点ですが、インターフェイスはコンストラクタを規定できないので、実はISerializableの実装はちゃんとコンストラクタを特別に作っておかないとダメです。
ややこしいですねー。
12/20/2009
画像処理ライブラリ
画像処理ライブラリは汎用性が高くて、使用頻度も高く、なおかつ逐一スクラッチで作るにはめんどうで、それでいて速度が求められて、細かな仕様に左右されることの多いライブラリだと最近思います。
例えばOpenCVのRGBコンポーネントの内部的な配置はRGBではなくBGRであるなど(一応内部的にRGBへ変換する関数が存在するようですが)コンポーネントの問題があり、その画像がRGB24なのかRGBA32なのか、それともGrayScale16なのかGrayScale32なのかYUIなのかHSVなのかなど色空間の問題もあります。
それらすべてに汎用的なものを用意するのは、非常に困難であり、通常画像処理ライブラリはRGBでの画像処理をもとに考えられています。もっともこれ自体は特にプログラマにとって問題なく読替を効かせることのできるものです。問題はそのライブラリは高速にすることや、面倒を回避するために汎用化することです。
一部細かな話しですが、.netでのImageの操作は通常はメソッド経由なので、オーバーヘッドが尋常ではないので、特定の一点から取得するなどのアクセス頻度の低い作業以外は、なるべく低レベルな操作で構築する必要性があり、BitmapのLock/Unlockは.net系の画像処理では必須であり、これはコンポーネントの構成に大きく左右されるので、通常のマネージドな感覚で行っていると速度の低下が発狂せんばかりになります。Lock/Unlock以外にもUnsafeでガリガリ行う方法もありますが、移植性が下がるので、なるべくそれはやめた方がよいです。それに性能もそれほど向上しないので、最終手段として覚えて置く程度でいいと思います。
話は戻りますが、画像処理は速度と精度と汎用性、多種多様性、移植性、利便性など多くの点が求められるので、なかなか構築が面倒なのですが、作ることは非常に有益だと考えます。
またコンセプト的な嗜好も混ぜ込めるので、個人的にはある程度以上のレベルからは自己のライブラリとして蓄積することを考えてしまいます。
そうするとオープンソースがとても魅力的ですが、仮にこれを業務で特定のアプリケーションに組み込もうと思うと商用ある程度のライセンス料が必要です。そもそも煩雑で有用な知識の集積は、その労力によって企業による上澄みの簒奪を唾棄し、その行為への怒りをこめて、オープン化する場合もあるので、有用なものを安く使いたいという心とライブラリの制作にかかるコストを最低限でも回収したいというジレンマがよくわかります。個人で開発しだすとよくわかります。
だから個人で開発しだしても、やはり企業に差し出すなどということは許容できないなぁと思います。
企業はもっとライブラリライセンスに金を払えやこらー!っていうのがある意味本音です。安くあがる分けねぇだろ、知識の集積を利用しようとしているのに。
12/10/2009
ControlController
.net Frameworkをつかって、フォームをデザインするときにでるあの特別なコントローラーが気になります。
あれがとってもほしいのです。
考えられる方法は幾つかありますが、C#,VBがOOPと言えども、言語的にクラスの継承の間に割り込みはできないので、委譲のほうで問題を回避していくことが重要かもー。
コントロールを入れられるコントロール制御用のコンテナを用意して、そのコンテナに対して制御を加えるようにすれば、汎用的にコントロールを扱えますね。うん、というか、それ以外に思いつきません。
調べたところ、既にこのコントローラを開発した人もいるのですが、2003で作られているし、またこれに限っては車輪の再発明も幾分か自己のOOPへの理解や修練に役立つので少し試行してみる。
取り替えずコンテナをクラスで宣言します。描画の関係もあるので、Controlを継承した方が無難なので、継承する。ただここで考えるのは、
・これにコントロールを入れて、
・Mouse系のイベントを使うこと、
・Key系のイベントでの制御も許容すること。
・同時に周りのコントロールとの数値の関係性によって拘束がかかること。
・選択時には特別な描画処理を行うので、Paintイベントも書くこと。
意外と使い易いコンテナをつくるには問題がありそうだ。
コントロールをコンテナに格納したときに、格納したクラスの個別のマウスやキーのイベントをハックしないといけないので、これが若干気になりますねー。コンテナ格納後に個別のコントロールのイベントが生きていると困るので、殺しておきたいのですが、よくわからないのであとで調べておきますね。
たぶん内側を透明にしてZバッファの順序を入れ替える。もしくはフォーカスイベントが発生するとフォーカスを移すとかですけど、フォーカスのイベント内でフォーカスを移動させると予想外の動きをするので、あまりおすすめできません。以前、実験した際に、呼び出しが規則的に発生しないことを確認したので、フォーカスを制御するのは、確実性に疑問があるので、別の方法を模索するほうがいいです。
あとはコントロールが登録されているものを入れ替えてしまうかですが、これはデータの構造を勝手に書き換えることになるので、おすすめできません。汎用性にかけることは間違いないので、なるべく同一の階層性でイベントの登録のみで解決したいですね。
…別にコンテナを開発しなくても、イベントの登録、削除をうまく制御すれば、データ構造的な面では出来そうですが、すでに存在しているイベントとぶつかったり、そもそももとのイベントが駆動してしまう問題があるので、これはうまくいきそうにないです。
ここまでの問題点で一番大きいのは、コントロールに発生するイベントを一時的に殺して、それをバイパスして別のコントールに移すことができるのかどうかです。そのあとは、ここの機能を分割しながら実装していけば問題はなし。
初回ではなく、選択後つまりコンテナに入れられた後に、そのあとは独占的にコントロールを支配できなければいけません。なにか方法はないものでしょうか?
12/06/2009
コンテンツ、コンテナの話
今回はコンテンツとコンテナの話を。
コンテンツをオリジナルでユニークなそれ自体では複製できないモノとします。それが「なにか」ということについては議論しません。
コンテンツをコンテナに格納すれば、複製可能になるとします。またコンテナに格納されたコンテンツを、別のコンテナに移し替えるこが出来るかどうかは、コンテナの性質になります。
想定している対象物はDVDやMP3です。
コンテナからデータを取り出せないのでは意味がありませんが、このコンテナがコンテンツを完全に取り出せることは保証しません。ただコンテナの存在意義としてそれがあまりにはコンテンツを損傷させるのでは意味がありません。完全に復元可能なものを特別にロスレスという形容をする場合があります。この場合にロスはコンテンツが本来持つ性質を損失しないという意味です。
問題を局所化します。
DVDはコンテナであり、それが内包しているコンテンツが映像やデータになります。通常の販売者はコンテンツをコンテナにいれて、販売します。ただし、このときにコンテンツを売る気はさらさらないです。このコンテンツをコンテナにいれて複写して販売しているので、コンテンツを売ってしまうと困ります。
しかし購入者はコンテンツを購入したと思います。このコンテンツを取り出し、別のコンテナに入れること、複写という行為を含めて権利だと考えます。この時点で既に販売者と購入者の間で意見の相違があります。売買契約から考えると販売者が優位です。このことは既に周知だと思われます。
コンテンツを鑑賞させるけれども、別のコンテナの中にいれることを認めないということは、映画でも同じです。またラジオでも同じです。別のコンテナに入れるときに、コンテンツの作成者は対価を求めます。
さてさてややこしいのは、コンテナとコンテンツは、その構造が入れ子になりうることにあります。この性質のために本来のコンテンツの製作者と利用者の間に介在する存在があることが想定されます。これがもっともややこしい。
すべてのコンテンツの製作者に権利を認めると、その入れ子構造のせいで最終的な利用者以外はすべて権利を持つことになります。オリジナルのコンテンツとしての権利を持つ人ほどそれが無断でコンテナに入れられることに対して、対価請求の機会を損失します。
では本来のオリジナルのコンテンツの制作者からそのコンテンツの権利を手にいれるということは可能か?
これは今までの議論をすっ飛ばしているが、コンテンツの売買というコンテンツの本質に対する問いかけなのだが、これが著作権の本質に直結する。またオリジナルを誰が所有するのかということにもつながる。
オリジナルの所有の問題はもっともややこしい。同一性の問題にもつながり、そこには正統性の話も関わる。正統性の話は歴史の問題であり、そこまで来るならば、それが根ざした背景や環境、文化すらも範囲に入ってしまう。仮に問題を簡素にするなら、何を売っているのかぐらいだろう。
結論から言えば、売っているのはコンテンツをコンテナに詰めることの独占的な販売権だけだろう。
権利というものは、あとから生まれた人為的なものであることを心に止めて置くことが必要だし、それを踏みにじることの代償についてはもっと配慮すべきだ。
9/27/2009
Pluginとマクロのための開発設計
問題はこれらは設計段階でうまく考えておかないといくらリファクタリングしても、ほしい機能を実装するめどを立てられなくなりそうなので、いろいろ書いておく。
PlugInの機能をどうやって管理するのか。
たぶんこれは大別して2種類。
- 内部に管理クラスをもつ実行ファイルがあり、それが内部で呼び出すPlugIn機能を利用する
- 外部に管理クラスをもった実行ファイルがあり、それが生成するDBを元にPlugIn機能を利用する
中間の形式が違うだけだ。入力:並べられたPlugIn、出力:呼び出し可能なPlugInの列挙。
マクロの問題を考えるなら、PlugInをインスタンス化できて、外部に公開されたメソッド名を使えば、そのPlugInをマクロで制御できるようにする構想も必要だ。
マクロ化するならば、内部的な関数の呼び出しも名前で呼べないといけないなぁ。
マクロを認めるなら、結局はスクリプトを認めることで、それならば内部にはParserが必要になる。この部分をPlugIn側にも認めるのか否かは。。。認めないといけないなぁ。
実際はそこまで考える必要性はないけれど、でもそこまで考えておかないと、未来の僕や僕の後を継ぐ人はかわいそうなコードをかわいそうなスケジュールでかわいそうな顔で変更したり、機能追加しないといけない。コメントをいくら書いても、できないものはできない。なので、イケテル設計(笑)をしないと。開発が嫌いになると困るので、十分調査していこう。
とりあえず、PlugInの管理は別の実行ファイルにしたい。それは、この機能は統合的には必要だけど、単体的には必要ない。だからDBもしくはCSV(Debug用)でPlugIn情報を表現する。
さて、ついでに必要になるのは、PlugInを単体でテストすることができる機能。これは開発者向けの必須ツールだ。最低限呼び出し可能かどうかのテストと、読み込んだデータに対して、期待したデータ処理ができるかが重要だ。できれば、テストデータをDefaultで用意できたり、ファイルの読み込みができたり、内部データを動的に表示したり、ログを取れたり、そういうのが絶対にその後の開発者の助けになるし、、、なにより自分がイライラしないだろう。うん、これは必要。
ほしい機能はとりあえず広げてみたけど、ざっくりまとめると
- PlugInの呼び出し、実行(dll)
- マクロ機能の呼び出し、実行、(変換機能:動的+コンパイル済み)
- PlugInのテストツール
- マクロのテストツール
- PlugInのマネージ機能
- Debug用のお助けツールキット(オプション式)
マクロ関係は基本の機能に依存するので、いったんは無視。
PlugInの部分の基本的な考え方は同じなので、これを優先的に作る。
マクロ機能に関しては、既存のスクリプト言語で代替可能であることが望ましい。
個人的にはIronPythonもしくはNativeのPython。大穴Scala?
PlugInの呼び出しは基本的にはShowDialog()のような感じで、Dialogを出して、そこでパラメータを変更する。いくつかのメソッドをPlugIn側に公開する必要性があるので、ここを先に留意する。
後から来る人はかならずInterfaceの概念とCOMの概要は知っている必要性がある。この際にOptionとしてDebugのツールキットインターフェイスを引数に入れられるようにすると、、、、複雑度が上がるか。。。
8/26/2009
JPEGって手のかかる子
最近JPEGのDecoderを自前で用意しなくてはいけないので、大変な思いをしています。しかも特許がらみでなんだか情報も閉鎖的です。とりあえず、エントリをつくっておいて、後で情報を足しておきます。
もーめんどくせぇ。