2011年7月31日日曜日

データベース開発 その6

全然完成していないようで完成してきています(笑) 今日はBuild("MyLog.log"); という形で出力フォルダへ簡単にビルドログを出力できるところまで作成しました。それから、メモリ上からビルドする方法とローカルパスから読み込んでビルドできるようにして速度比較もしてみました。それで、メモリ上からビルドする方法が速かったです。時間差 00:00:00.37 で体感速度は2秒くらいです。体感速度2秒というのは実際にビルドするまでにビルダーを読み込んで表示するまでにかかる時間です。これで今回の目的のビルド速度の向上もできました。まだ作らないといけない部分としては、Csprojの同時ビルドは.NetFrameWork内で実装されていないので作成する必要があることと、ログファイルをメモリ上に出力する方法がないかとか、気になる部分もあります。後はAssemblyInfo.csの自動作成ができたら、データベース側へ実装してデータベースソフトを完成させる予定です。

2011年7月27日水曜日

データベース開発 その5 テストビルドー

 テストビルダーからプロジェクトを生成して保存してから、VisualStudioで読み込めることを確認しました。今回はデータベースから直接DLLを作成できるようにしようと思います。

2011年7月25日月曜日

XNA対応ファイル操作

 XNAでファイル操作するにはStorageContainerクラスがありますが、原始的に操作することになれてしまうと便利でも以前の方法が便利な場合もあります。

このソースはXNAで開発し初めて初期の段階で作成したので技術的不足により、ソースコードは難解だと思います。しかし、機能自体はちゃんとできているのでメソッドアクセスする分には問題ないと思います。

動作プラットフォーム:XNA、Windows

using System;

using System.Threading;
using System.IO;
using System.Collections.Generic;
using System.Collections;

namespace GGD.StorageSet
{
/// <summary>
/// ディレクトリ操作クラス
/// </summary>
public class EditStorage
{
#region exDF
/// <summary>
/// ファイル(\\なし)またはディレクトリ(\\なし)確認処理
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
public bool exDF(string path)
{
bool exD = Directory.Exists(path);
bool exF = File.Exists(path);
if (exD != exF)
{
exD = true;
}
return exD;
}
#endregion exDF

#region RenameDirectory
/// <summary>
/// ファイル(\\なし)名前変更
/// </summary>
/// <param name="srcPath">移動元の名前</param>
/// <param name="tarPath">移動先の名前</param>
public void renamefile(string srcPath, string tarPath)
{
bool exF = File.Exists(srcPath);

if (exF == true)
{
File.Move(srcPath, tarPath);
}
}

/// <summary>
/// ディレクトリ(\\なし)名前変更 ドライブ間は無理
/// </summary>
/// <param name="srcPath">移動元の名前</param>
/// <param name="tarPath">移動先の名前</param>
public void renameDirectory(string srcPath, string tarPath)
{
bool exD = Directory.Exists(srcPath);

if (exD == true)
{
Directory.Move(srcPath, tarPath);
}
}

/// <summary>
/// ディレクトリ(\\なし)名前変更 ドライブ間の移動も可能
/// </summary>
/// <param name="srcPath">移動元の名前</param>
/// <param name="tarPath">移動先の名前</param>
/// <param name="startDir">移動元のEXEのスタートアップディレクトリ</param>
public void renameDirectory2(string srcPath, string tarPath, string startDir)
{
if (Path.GetPathRoot(srcPath) == Path.GetPathRoot(tarPath) ||
Path.GetDirectoryName(srcPath) == Path.GetDirectoryName(tarPath))
{
Directory.Move(srcPath, tarPath);
}
else
{
string baseName = Path.GetFileName(srcPath);
string baseDir = startDir + "\\" + baseName;
if (File.Exists(srcPath))
{
renameDirectory(srcPath, tarPath);
}
else
{
Directory.CreateDirectory(tarPath);
string dirPaste = Path.GetDirectoryName(tarPath);

foreach (string dir in getDirectories(srcPath))
Directory.CreateDirectory(tarPath + "\\" + dir.Remove(0, baseDir.Length + 1));

List<string> includeList = new List<string>();
foreach (string file in getFiles(srcPath))
includeList.Add(file.Remove(0, baseDir.Length + 1));

foreach (string include in includeList)
File.Move(baseDir + include, tarPath + include);
}
}
}
#endregion RenameDirectory

#region nameUnRepetition
/// <summary>
/// パス名の重複防止処理ファイル(\\なし)またはディレクトリ(\\なし)
/// </summary>
/// <param name="path">ファイルのパス</param>
/// <returns>ファイル名</returns>
public string nameUnRepetition(string path)
{
int j = 1;

for (int i = 0; i <= j; i++)
{
// 重複ファイル・フォルダがあったら
if (exDF(path) == true)
{
string dir = Path.GetDirectoryName(path);
string fileName = getFileName2(path) + i.ToString();
string ext = getExtName2(path);

string passName = dir + "\\" + fileName + ext;

// 重複ファイル・フォルダがなければ
if (exDF(passName) == false)
{
// 上書き
path = passName;
break;
}
}
else
{
break;
}
j++;
}
return path;
}

/// <summary>
/// 2重以上の拡張子も省き、ファイル名を取得
/// </summary>
/// <param name="filePath"></param>
/// <returns></returns>
public string getFileName2(string filePath)
{
string delName = filePath;
for (; ; )
{
string extCount = Path.GetExtension(delName);
delName = Path.GetFileNameWithoutExtension(delName);
if (delName.Contains(".")==false)
break;
}
return delName;
}

/// <summary>
/// 2重以上の拡張子も取得
/// </summary>
/// <param name="filePath"></param>
/// <returns></returns>
public string getExtName2(string filePath)
{
string extName = "";
string delName = filePath;
for (; ; )
{
string extCount = Path.GetExtension(delName);
extName = extCount + extName;
delName = Path.GetFileNameWithoutExtension(delName);
if (delName.Contains(".") == false)
break;
}
return extName;
}
#endregion nameUnRepetition

#region copyDirectory
/// <summary>
/// ファイル(\\なし)またはディレクトリ(\\なし)、およびその内容を新しい場所にコピーします
/// </summary>
/// <param name="srcPath">
/// コピー元のディレクトリ(推奨)のパス</param>
/// <param name="tarPath">
/// コピー先のディレクトリのパス</param>
/// <param name="isOverWrite">
/// コピー先が上書きできる場合は true。それ以外の場合は false。</param>
public void copyDirectory(string srcPath, string tarPath, bool isOverWrite)
{
if (srcPath != tarPath)
{
#region コピー貼り付け開始処理
// コピー先のディレクトリがファイルであるなら
if (File.Exists(tarPath) == true)
{
// パス名からディレクトリを抽出
tarPath = Path.GetDirectoryName(tarPath);
}

tarPath = tarPath + "\\" +
Path.GetFileName(srcPath);

// コピー先のディレクトリがなければ作成する
if (exDF(tarPath) == false)
{
Directory.CreateDirectory(tarPath);
}

#if WINDOWS
if (isOverWrite)
{
//属性もコピー
File.SetAttributes(tarPath, File.GetAttributes(srcPath));
}
#endif
#endregion コピー貼り付け開始処理

copyFolda(srcPath, tarPath, isOverWrite);
}
}

#region copyFolda
void copyFolda(string srcPath, string tarPath, bool isOverWrite)
{
if (srcPath != tarPath)
{
// コピー先のディレクトリがなければ作成する
if (exDF(tarPath) == false)
{
Directory.CreateDirectory(tarPath);
#if WINDOWS
if (isOverWrite)
{
//属性もコピー
File.SetAttributes(tarPath, File.GetAttributes(srcPath));
}
#endif
}

// コピー元のディレクトリがファイルであるなら
if (File.Exists(srcPath) == true)
{
// ファイルコピー貼り付け
copyFile(srcPath, tarPath, isOverWrite);
}
else
// コピー元のディレクトリがフォルダであるなら
{
// コピー先のディレクトリがファイルであるなら
if (File.Exists(tarPath) == true)
{
// パス名からディレクトリを抽出
tarPath = Path.GetDirectoryName(tarPath);
}

// コピー元のディレクトリをすべてコピーする
foreach (string dirs in Directory.GetDirectories(srcPath))
{
// コピー先のパスとコピー元のファイルパスを結合
string pastPath = tarPath + "\\" +
Path.GetFileName(dirs); ;

// 再帰処理
copyFolda(dirs, pastPath, isOverWrite);
}


// コピー元のファイルをすべてコピーする
foreach (string files in Directory.GetFiles(srcPath))
{
// コピー先のパスとコピー元のファイルパスを結合
string pastPath = tarPath + "\\" +
Path.GetFileName(files);

// 再帰処理
copyFile(files, pastPath, isOverWrite);
}
}
}
}
#endregion copyFolda

#region copyFile
/// <summary>
/// ファイル(\\なし)のコピー
/// </summary>
/// <param name="srcPath"></param>
/// <param name="tarPath"></param>
/// <param name="isOverWrite"></param>
public void copyFile(string srcPath, string tarPath, bool isOverWrite)
{
if (srcPath != tarPath)
{
// コピー先のファイルがディレクトリであるなら
if (Directory.Exists(tarPath) == true)
{
// コピー元のファイルパスをコピー先のパスに変換
tarPath = tarPath + "\\" + Path.GetFileName(srcPath);
}

// 上書き不可能な場合は存在しない時のみコピーする
File.Copy(srcPath, tarPath, isOverWrite);
#if WINDOWS
if (isOverWrite)
{
//属性もコピー
File.SetAttributes(tarPath, File.GetAttributes(srcPath));
}
#endif
}
}
#endregion copyFile
#endregion copyDirectory

#region cutDirectory
/// <summary>
/// ファイル(\\なし)またはディレクトリ(\\なし)、およびその内容を新しい場所に切り取ります
/// </summary>
/// <param name="srcPath">ディレクトリ(推奨)</param>
/// <param name="tarPath"></param>
/// <param name="isOverWrite"></param>
public void cutDirectory(string srcPath, string tarPath, bool isOverWrite)
{
if (srcPath != tarPath)
{
#region 切り取り貼り付け開始処理
// コピー先のディレクトリがファイルであるなら
if (File.Exists(tarPath) == true)
{
// パス名からディレクトリを抽出
tarPath = Path.GetDirectoryName(tarPath);
}

tarPath = tarPath + "\\" +
Path.GetFileName(srcPath);

// コピー先のディレクトリがなければ作成する
if (exDF(tarPath) == false)
{
Directory.CreateDirectory(tarPath);
}

#if WINDOWS
if (isOverWrite)
{
//属性もコピー
File.SetAttributes(tarPath, File.GetAttributes(srcPath));
}
#endif
#endregion 切り取り貼り付け開始処理

cutFolda(srcPath,tarPath,isOverWrite);
}
}

#region cutFolda
/// <summary>
/// フォルダ(\\なし)の中身を移動
/// </summary>
/// <param name="srcPath"></param>
/// <param name="tarPath"></param>
/// <param name="isOverWrite"></param>
void cutFolda(string srcPath, string tarPath, bool isOverWrite)
{
string cutPath = srcPath;
cutFolda2(srcPath, tarPath, isOverWrite);

deleteDirectory(cutPath);
}

/// <summary>
/// フォルダ(\\なし)の中身を移動
/// </summary>
/// <param name="srcPath"></param>
/// <param name="tarPath"></param>
/// <param name="isOverWrite"></param>
void cutFolda2(string srcPath,string tarPath,bool isOverWrite)
{
if (srcPath != tarPath)
{
// コピー先のディレクトリがなければ作成する
if (exDF(tarPath) == false)
{
Directory.CreateDirectory(tarPath);
#if WINDOWS
if (isOverWrite)
{
//属性もコピー
File.SetAttributes(tarPath, File.GetAttributes(srcPath));
}
#endif
}

// コピー元のディレクトリがファイルであるなら
if (File.Exists(srcPath) == true)
{
// ファイル切り取り貼り付け
cutFile(srcPath, tarPath, isOverWrite);
}
else
// コピー元のディレクトリがフォルダであるなら
{
// 移動元のディレクトリをすべて移動する
foreach (string stCopyFrom in Directory.GetDirectories(srcPath))
{
string stCopyTo = tarPath +"\\" +
Path.GetFileName(stCopyFrom);

cutFolda(stCopyFrom,stCopyTo,isOverWrite);
}

// 移動元のファイルをすべて移動する
foreach (string stCopyFrom in Directory.GetFiles(srcPath))
{
string stCopyTo = tarPath + "\\" +
Path.GetFileName(stCopyFrom);

cutFile(stCopyFrom, stCopyTo, isOverWrite);
}
}
}
}
#endregion cutFolda

#region cutFile
/// <summary>
/// ファイル(\\なし)の移動
/// </summary>
/// <param name="srcPath"></param>
/// <param name="tarPath"></param>
/// <param name="isOverWrite"></param>
public void cutFile(string srcPath, string tarPath, bool isOverWrite)
{
if (srcPath != tarPath)
{
// コピー先のファイルがディレクトリであるなら
if (Directory.Exists(tarPath))
{
// コピー元のファイルパスをコピー先のパスに変換
tarPath = tarPath + "\\" + Path.GetFileName(srcPath);
}

// 貼り付け先のファイルを削除
if (File.Exists(tarPath) && isOverWrite)
deleteFile(tarPath);

File.Move(srcPath, tarPath);
}
}
#endregion cutFile
#endregion cutDirectory

#region deleteDirectory
/// <summary>
/// ファイル(\\なし)・フォルダ(\\なし)を根こそぎ削除
/// </summary>
private void deleteDirectory(string path)
{
if (File.Exists(path) == true)
{
deleteFile(path);
}
else
{
deleteFolda(path);
}
}

#region deleteFile
/// <summary>
/// ファイル(\\なし)を根こそぎ削除する(ReadOnlyでも削除)
/// </summary>
/// <param name="filePath">削除するファイル</param>
public void deleteFile(string filePath)
{
if (filePath != null && filePath != "")
{
if (File.Exists(filePath) == true)
{
#if WINDOWS
//ファイルの属性を削除
removeAttributeFile(filePath);
#endif
/*
//ファイルを削除する(ごみ箱に入れる)
Microsoft.VisualBasic.FileIO.FileSystem.DeleteFile(
filePass,
Microsoft.VisualBasic.FileIO.UIOption.OnlyErrorDialogs,
Microsoft.VisualBasic.FileIO.RecycleOption.SendToRecycleBin);
*/
//#else
//ファイルを根こそぎ削除
File.Delete(filePath);
}
}
}

#if WINDOWS
void removeAttributeFile(string filePass)
{
//DirectoryInfoオブジェクトの作成
FileInfo fi = new FileInfo(filePass);

//基のファイルの属性を変更
fi.Attributes = FileAttributes.Normal;
}
#endif
#endregion DeleteFile

#region deleteFolda
/// <summary>
/// フォルダ(\\なし)を根こそぎ削除する(ReadOnlyでも削除)
/// </summary>
/// <param name="dir">削除するフォルダ</param>
public void deleteFolda(string dir)
{
if (dir != null && dir != "")
{
if (Directory.Exists(dir) == true)
{
#if WINDOWS
//フォルダ以下のすべてのファイル、フォルダの属性を削除
removeAttributeDir(dir);
#endif
/*
//フォルダを削除する(ごみ箱に入れる)
Microsoft.VisualBasic.FileIO.FileSystem.DeleteDirectory(
dir,
Microsoft.VisualBasic.FileIO.UIOption.OnlyErrorDialogs,
Microsoft.VisualBasic.FileIO.RecycleOption.SendToRecycleBin);
*/

//フォルダ内のすべてのファイルの属性を変更
foreach (var fi in getFiles(dir))
deleteFile(fi);
foreach (var fi in getDirectories(dir))
deleteFolda(fi);

//フォルダを削除
Directory.Delete(dir);
}
}
}

#if WINDOWS
void removeAttributeDir(string dir)
{
//DirectoryInfoオブジェクトの作成
DirectoryInfo dirInfo = new DirectoryInfo(dir);

//基のフォルダの属性を変更
dirInfo.Attributes = FileAttributes.Normal;

//フォルダ内のすべてのファイルの属性を変更
foreach (FileInfo fi in dirInfo.GetFiles("*", SearchOption.AllDirectories))
fi.Attributes = FileAttributes.Normal;

//サブフォルダの属性を回帰的に変更
foreach (string dir2 in Directory.GetDirectories(dir))
removeAttributeDir(dir2);
}
#endif
#endregion deleteFolda
#endregion deleteDirectory

#region getDirFiles
/// <summary>
/// 指定したディレクトリ内のファイルとディレクトリ取得
/// </summary>
/// <param name="path"></param>
public string[] getEntries(string path)
{
return Directory.GetFileSystemEntries(path,"*.*",SearchOption.AllDirectories);
}
#endregion getDirFiles

#region getDirectories
/// <summary>
/// フォルダ(\\)からフォルダ名を全部取得
/// </summary>
/// <param name="dirPath"></param>
/// <returns></returns>
public List<string> getDirectories(string dirPath)
{
List<string> dirsList = new List<string>();

return getDirectories2(dirPath, ref dirsList);
}
/// <summary>
/// フォルダ(\\)からフォルダ名を全部取得
/// </summary>
/// <param name="dirPath"></param>
/// <param name="dirsList"></param>
/// <returns></returns>
List<string> getDirectories2(string dirPath, ref List<string> dirsList)
{
string[] Dirs;

Dirs = Directory.GetDirectories(dirPath);
dirsList.AddRange(Dirs);

foreach (string Dir1 in Dirs)
{
getDirectories2(Dir1, ref dirsList);
}

return dirsList;
}

#region getFiles
/// <summary>
/// フォルダ(\\なし)からファイル名を全部取得
/// </summary>
/// <param name="dirPath"></param>
/// <returns></returns>
public List<string> getFiles(string dirPath)
{
List<string> filesList = new List<string>();

return getFiles2(dirPath, ref filesList);
}
/// <summary>
/// フォルダ(\\なし)からファイル名を全部取得
/// </summary>
/// <param name="dirPath"></param>
/// <param name="filesList"></param>
/// <returns></returns>
List<string> getFiles2(string dirPath, ref List<string> filesList)
{
string[] Files;

Files = Directory.GetFiles(dirPath);
filesList.AddRange(Files);

foreach (string dir in Directory.GetDirectories(dirPath))
{
getFiles2(dir, ref filesList);
}

return filesList;
}
#endregion getFiles
#endregion getDirectories

#region isPassOrFileName
/// <summary>
/// パスやフェイル名に使用できない文字か確認
/// </summary>
/// <param name="target"></param>
/// <returns></returns>
public bool isPassOrFileName(string target)
{
bool isResulct = false;

if (target != null)
{
if (isInvalidFile(target))
isResulct = true;
if (isInvalidPath(target))
isResulct = true;
}

return isResulct;
}

/// <summary>
/// フェイル名に使用できない文字かどうか
/// </summary>
/// <param name="target"></param>
public bool isInvalidFile(string target)
{
bool isResulct = false;

//1 ~ 31 の ASCII 文字の制御文字
foreach (char chstr in target.ToCharArray())
if (Char.IsControl(chstr))
isResulct = true;

//および引用符 (")
if (target.Contains(@""""))
isResulct = true;
//不等号 (より小) (<)
if (target.Contains("<"))
isResulct = true;
//不等号 (より大) (>)
if (target.Contains(">"))
isResulct = true;
//パイプ (|)
if (target.Contains("|"))
isResulct = true;
//バックスペース (\b)
if (target.Contains("\b"))
isResulct = true;
//null (\0)
if (target.Contains("\0"))
isResulct = true;
//タブ (\t)
if (target.Contains("\t"))
isResulct = true;
//スラッシュ (/)
if (target.Contains("/"))
isResulct = true;
//コロン (:)
if (target.Contains(":"))
isResulct = true;
//コメ (*)
if (target.Contains("*"))
isResulct = true;
//クェスション (?)
if (target.Contains("?"))
isResulct = true;
//エン (\)
if (target.Contains(@"\"))
isResulct = true;

return isResulct;
}

/// <summary>
/// パス名に使用できない文字かどうか
/// </summary>
/// <param name="
target"></param>
/// <returns></returns>
public bool isInvalidPath(string target)
{
bool isResulct = false;

char[] invalidch = Path.GetInvalidPathChars();
foreach(char ival in invalidch)
if(ival.ToString()==target)
isResulct = true;

return isResulct;
}
#endregion isPassOrFileName
}
}



2011年7月22日金曜日

いいね! ボタン設置

いいね! コードを動かしてみる。プレビューで表示されなかったので動かないと思っていましたがブログ側では表示できました。

2011年7月20日水曜日

画像フォントの作成

フォントファイルというのは以外にも重い。1フォントファイルあたり約6MBくらいになるものもある。さすがにそうなるとフォントファイルを付属させてVectorとかのファイル登録サイトにアップロードするのをためらってしまう。そこで、今回は究極にフォントファイルを最適化する方法を考えてみた。今回はあいうえおの50音だけを画像として出力する。50音あたりのファイルサイズは1音あたり128×128で全体の面積は819200 px^2とする。このときメモリ上のサイズは約3MBになる。ディスク上での保存サイズはPNGで約600KBくらいになるだろうか。フォントファイルに比べたら約六分の一の容量になる。後はこの画像をゲーム上で読み込めばいいだけになる。
 フォントファイルから読み込んで画面に出力するのと最適化した画像フォントから読み込む場合の読み込み速度は最適化した画像フォントの方がファイル容量が軽いので読み込むのが速い。そして、画面への出力速度はだいたい同じだと思う。それで、漢字とかになるとこの画像フォントというのが最適な方法なのかいまいち怪しくなってくる。常用漢字だけで1945字あるので、先ほどの1音あたり128×128で計算すると、メモリ上のサイズは約127MBでディスク上のサイズはPNGで約50MBといったところだろうか。また、一文字23pxとした場合はメモリ上のサイズは約40MBでディスク上のサイズはPNGで20MBといったところだろうか。このような場合にはフォントファイルから画面へ文字を出力した方が簡単そうだ。
 それで、ゲームでの会話などで使用する部分だけを画像化してディスク上に保存した場合を考えてみる。原稿用紙300枚で1945字だけを使用する。一文字23pxで、そのときのメモリ上のサイズは約126MBとなる。ディスク上のサイズはPNGで約63MBだろうか。原稿用紙一枚あたりの場合はメモリ上で約1MBになるので速度は確保できていると思う。
 上記の方法だと画像フォントはひらがなだけで十分ということになってしまうので、画像フォントを運用するには一工夫することが必要になりそうですね。
 結論、漢字をつかうなら、ひらがなも入っているフォントでいい。また、ひらがなだけ使用するゲームならひらがな画像だけを作成して使用した方が最適化できる。

2011年7月13日水曜日

データベース開発 その4

再生プレイヤーの概観だけ完成できました。それから、コンテンツのサイズの容量を適切に表示できるようにもしてみました。フォルダ容量の表示可能容量はSI規格のYB(ヨタバイト)まで対応しています。ファイル容量はエクサバイトまで表示できます。

DXアーカイブの最適化への可能性

アーカイブ内は最適化した状態でファイルを格納したい。そこで、DXアーカイブ内から画像ファイルを複数の設定をして読み込めるようにしたい。
DXアーカイブ内のファイルを画像ファイル0, 設定ファイル1, 設定ファイル2 とした場合に、設定ファイル1、設定ファイル2から画像ファイル0を呼び出すと、読み込み設定になっているので読み込めないような気がした。そこで、DXライブラリのアーカイブの仕様を調べてみた。
ttp://hpcgi2.nifty.com/natupaji/bbs/patio.cgi?mode=view&no=2262
ベータ版のDXライブラリだと読み書き設定になっているので設定ファイル1と設定ファイル2から同時に画像ファイル0を読み出すことができるようになっている。したがって、アーカイブ内の最適化はDXアーカイブでも可能だとわかった。

2011年7月12日火曜日

データベース開発 その3

ミリ秒単位で表示する再生プレイヤーを作成中です。このプレイヤーを作成したあとはDXライブラリにデータベースを渡せるようにしようと思います。これらの作業の後はキャラクターの再生プレイヤーも作成して、データベース側から制御できるようにしてしまおうと思います。

2011年7月11日月曜日

リレーショナルなデータベースができたら

検索機能を付けようかどうか迷いますね。

それで、ゲームとかでファイル検索の目的でファイル名にタグを直接付けて管理する方法とかありますね。例えば、[武器]ドラゴンバスター とかですね。この[武器]という部分でファイル検索が容易に行えるわけですよ。さて問題になってくるのは[武器][アイテム]ドラゴンバスター のように名づけると、名前が冗長的に長くなることです。また、ファイル名とタグを分類してしまえばもっと簡単に管理できるようになるはずですよね。

 さて、ゲームでのアイテム管理では、このタグ名で管理するといのも一つの手段なんですが、違う種類のデータベースに移動させてしまうとこの[武器][アイテム]ドラゴンバスターではリレーショナルな関係を維持できません。例えば、ドラゴンの武器のデータベースからドラゴンの盾のデータベースへ[武器][アイテム]ドラゴンバスターを配置した場合、このドラゴンの盾のデータベースと[武器][アイテム]ドラゴンバスターは何も関連性がありません。したがって、リレーショナルな関係を維持できていませんよね。ここで、リレーショナルな関係を保つためには[武器][アイテム]ドラゴンバスターの名前をドラゴンバスターに変更してしまえば、リレーショナルな状態を維持できますよね。

 それで、リレーショナルなデータベースを作成してしまうと、検索が不要になるんでよね。わざわざ[武器][アイテム]で検索する必要がなくなるのですから。

・・・・・・

検索機能は要望があったらつけようと思います。

2011年7月5日火曜日

理想の椅子を求めて その前に

 求める椅子は頑丈な椅子。背もたれが軋むことのない椅子。前傾姿勢ができる椅子。この三つを満たすことのできる椅子はお金を出せばアーロンチェアというのがあるらしい。それで、そんな高級な椅子は買えないので理想の椅子を作ることにした。

 まず、頑丈な椅子です。これは四脚椅子で十分です。安物の回転椅子だとネジを固定させるための台座が木製でできているので長年座っているとネジが取れるようになります。それで、値段的に頑丈な椅子を求めるとなると回転椅子よりも四脚椅子の方が安いです。それから、回転椅子よりも四脚の方がバランスがとれているので座ったときに自由に座る位置を変えることもできますね。

 そして、背もたれが軋むことのない椅子。これも回転椅子だと、後ろの背もたれが安物の椅子だとバネで背もたれを支えているので軋みます。したがって、背もたれにバネを使わない椅子が必要です。

 さらに、前傾姿勢ができる椅子。これができる椅子は非常に少ないですね。しかし、前傾姿勢自体は座るところを前に傾けることができればいいので、クッションで代用できます。そして、長時間座るのでポリウレタンのクッションだとすぐに形が戻らなくなるような気がします。したがって、耐久性に優れたポリエステルのクッションが必要です。

 したがって、理想の椅子を作るのに必要なものはクッションと四脚椅子です。あるいは少し値段が張りますがロッキングチェアというのも良さそうですね。それで、四脚椅子の問題点は高さ調節ができないことですね。身長に合った椅子を探してみようと思います。

2011年7月2日土曜日

データベース開発 その2

エクスプローラの表示形式とか変更できるようにしてみましたけど、操作画面が二つでも一つでもそんなに変わりないので、前回の多分木表示のままになりましたorz 複数選択処理はCtrlキーで作成するのは簡単なんですけど、Shit+マウスキーでドラッグアンドドロップ処理が難しいです。それで複数選択はやめましたw とりあえずは圧縮操作から開発しようと思います。