メインページ | ネームスペース一覧 | クラス階層 | 構成 | Directories | ファイル一覧 | ネームスペースメンバ | 構成メンバ | ファイルメンバ | 関連ページ

FIDocNode.h

00001 #ifndef FIDOCNODE_H
00002 #define FIDOCNODE_H
00003 
00004 #include "FIIterator.h"
00005 #include "FITypeDesc.h"
00006 #include <Base/BaseUtility.h>
00007 #include <list>
00008 #include <algorithm>
00009 
00010 namespace Spr {;
00011 
00012 /// 文字列の型
00013 typedef std::string FIString;
00014 /// 長さ0の文字列
00015 extern FIString zeroLengthString;
00016 /// 文字列の比較
00017 struct FIStringLess{
00018     bool operator() (const FIString& s1, const FIString& s2) const { return s1.compare(s2) < 0;}
00019 };
00020 /// 文字列の表示
00021 inline std::ostream& operator << (std::ostream& os, FIString s){
00022     os << s.c_str();
00023     return os;
00024 }
00025 
00026 
00027 
00028 
00029 /*  DocNodeの設計について
00030     D3Dの場合,データファイル.VRMLはスクリプト.
00031     たとえば,VRMLの場合,orientation が 何度も出てくるような Transform ノード
00032     がありえる.
00033     Xの場合,順番が固定で,データだけが書いてある.
00034 
00035     XのDocNodeは,同じ名前のフィールドを1つだけ持つので,C++のクラスと1対1に対応する.
00036     VRMLのDocNodeは複数ありえて,処理が割り当たる.
00037 
00038     同じIFにするのはよいのか?
00039     →よい
00040 
00041 
00042     イタレータは,ノードを巡回するけれど,組み立て型はどうするか?
00043     Xは属性が組み立て型になることがある.
00044     VMRLは単純型だけ.
00045     Xだと
00046         MeshFace{ int n; int vtx[]; }
00047         Mesh{ MeshFace face; MeshMaterialList{} }
00048     があり.
00049     これをDocNodeで書くには?
00050         Mesh{
00051             face -> {
00052                 int n;
00053                 int vtx[];
00054             }
00055             children -> MeshMatrialList{
00056             }
00057         }
00058 
00059 
00060     組み立て型の中を巡回するなら属性の値として,ノード型をありにしなければならない.
00061     属性→ノード名
00062     ノード→Childrenに入れておく
00063     とする?
00064 */
00065 
00066 class FITypeDesc;
00067 /** ファイル入出力ノード.
00068     シーングラフをファイルからロードしたり,ファイルにセーブする際に,
00069     ファイルを直接扱わずに,ドキュメントオブジェクトを介してセーブ・
00070     ロードすると,ファイルの扱いをドキュメントオブジェクトに任せる
00071     ことができるので,セーブ・ロードのコードを減らすことができる.
00072     このクラスは,ドキュメントオブジェクトを構成するノードの基本クラス.
00073 
00074     ドキュメントノードでは,属性値として,ノードを取ることが出来るようにしている.
00075     子ノードと属性値の両方にノードが来ることがあり得る.*/
00076 class SPR_DLL FIDocNodeBase:public UTRefCount{
00077 public:
00078     friend class FISaveScene;
00079     /// 仮想デストラクタを用意
00080     virtual ~FIDocNodeBase(){}
00081 
00082     //@name ノードの基本属性
00083     //@{
00084     /// このノードの名前の取得
00085     virtual UTString GetName() const =0;
00086     /// このノードの名前の設定
00087     virtual void SetName(UTString s)=0;
00088     /** このノードの型名の取得.
00089         リファレンスについて:
00090         このノードが他のノードへのリファレンスだった場合,
00091         GetType() は "REF" を返し,GetName()は参照先のノード名を返す.*/
00092     virtual UTString GetType() const =0;
00093     /** このノードの型名の設定.
00094         リファレンスの場合は, "REF"を設定する.*/
00095     virtual void SetType(UTString t){ assert(0); }
00096     /// 型記述子の設定
00097     virtual void SetTypeDesc(FITypeDesc* desc){ assert(0); }
00098     bool IsReference() const { return GetType().compare("REF") == 0; }
00099     //@}
00100     
00101     //@name 木構造の操作
00102     //@{
00103     /// 親ノード
00104     virtual FIDocNodeBase* GetParent()=0;
00105     /// 子ノードの数
00106     virtual int NChildren() const =0;
00107     /// 子ノード
00108     virtual FIDocNodeBase* GetChild(int i){ return Child(i); }
00109     /// 子ノード(Const版)
00110     virtual const FIDocNodeBase* GetChild(int i) const { return ((FIDocNodeBase*)this)->Child(i); }
00111     /// 子ノードの追加
00112     virtual void AddChild(FIDocNodeBase* n){ n->SetParent(this); }
00113     /// 親ノードの設定
00114     virtual void SetParent(FIDocNodeBase*)=0;
00115     /// 子ノードをすべて削除
00116     virtual void ClearChildren()=0;
00117     //@}
00118 
00119     //@name 属性の操作
00120     //@{
00121     /** 全属性を設定 */
00122     template <class T> bool SetWholeData(const T& t){ return SetWholeData(&t, sizeof(t)); }
00123     virtual bool SetWholeData(const void* data, size_t sz);
00124     /// 属性全体を取得.
00125     template <class T> bool GetWholeData(T& t){ return GetWholeData(&t, sizeof(t)); }
00126     virtual bool GetWholeData(void* data, size_t sz);   
00127     
00128     /// 指定のデータ属性の設定
00129     template <class T> bool SetData(const T& t, FIString id, FIString type){ return FindAttr(id).SetData(t, type); }
00130     /// 指定のデータ属性の設定(配列の一括設定可)
00131     bool SetData(const void* data, size_t& dataSize, size_t elementSize, FIString id, FIString type){ return FindAttr(id).SetDataImp(data, dataSize, elementSize, id, type); }
00132     /// 指定のデータ属性の取得
00133     template <class T> bool GetData(T& t, FIString id){ return FindAttr(id).GetData(t); }
00134     /// 指定のデータ属性の取得
00135     bool GetData(void* data, size_t sz, FIString id){ return FindAttr(id).GetDataImp(data, sz); }
00136     //@}
00137 
00138     //@name 属性操作の実装
00139     //@{
00140     /// 現在の属性に新しいノードをセットする.
00141     virtual FIDocNodeBase* SetNewNode(FIString id, FIString type)=0;
00142     
00143     /// 先頭の属性値を指すイタレータを取得
00144     virtual FIIterator FirstAttr() const =0;
00145     /// 最後の次の属性値を指すイタレータを取得
00146     virtual FIIterator LastAttr() const =0;
00147     /// イタレータが最後に来たら true
00148     virtual bool IsLast(const FIIterator& it) const { return it == LastAttr(); }
00149     /// 指定のノードを指すイタレータを取得
00150     virtual FIIterator FindAttr(FIString id, size_t pos=0) const =0;
00151     //@}
00152 
00153     /// ノードのツリーを表示
00154     virtual void Print(std::ostream& os, int indent=0) const;
00155     /// 属性を表示
00156     virtual void PrintAttr(std::ostream& os, int indent=0) const;
00157     /// 子ノードのツリーを表示
00158     virtual void PrintChildren(std::ostream& os, int indent=0) const;
00159 protected:
00160     /// 子ノードを返す関数の実装
00161     virtual FIDocNodeBase* Child(int i) = 0;
00162 };
00163 
00164 /// ドキュメントノードの基本クラスのvector
00165 class SPR_DLL FIDocNodes:public UTStack< UTRef<FIDocNodeBase> >{
00166 public:
00167     virtual void Print(std::ostream& os, int indent=0) const;
00168 };
00169 
00170 /// ドキュメントノード
00171 class SPR_DLL FIDocNode:public FIDocNodeBase, public UTTreeNode<FIDocNode>{
00172 public:
00173     struct TData{
00174         typedef std::vector<char> container;
00175         FIString type;                          ///<    値の型
00176         size_t elementSize;                     ///<    要素のサイズ
00177         container data;                         ///<    バッファ
00178         TData(){ elementSize=0; }
00179         /// データを最後に追加
00180         void PushBack(const void* d){
00181             data.resize(data.size()+elementSize);
00182             container::iterator it = data.end()-elementSize;
00183             memcpy(&*it, d, elementSize);
00184         }
00185         /// 最後のデータを削除
00186         void PopBack(){
00187             data.resize(data.size() - elementSize);
00188         }
00189         /// 1要素のサイズ
00190         size_t ElementSize() const { return elementSize; }
00191         void ElementSize(size_t s){ elementSize = s; }
00192         /// データ数
00193         void Size(size_t n){ data.resize(n*elementSize); }
00194         size_t Size() const { return elementSize ? data.size()/elementSize : 0; }
00195         /// 全データのバイト数
00196         size_t DataSize(){ return data.size(); }
00197         /// n番目のデータへのポインタ
00198         char* Data(size_t i){ return &*data.begin() + i*elementSize; }
00199         /// 最初のデータへのポインタ
00200         char* Begin(){ return &*data.begin(); }
00201         /// 最初のデータへのポインタ
00202         const char* Begin() const { return &*data.begin(); }
00203         /// 最初のデータの次へのポインタ
00204         char* End(){ return &*data.end(); }
00205         /// 最初のデータの次へのポインタ
00206         const char* End() const { return &*data.end(); }
00207         /// サイズの設定
00208         void Resize(size_t s){ data.resize(s*elementSize); }
00209     };
00210     /// ノードかバイナリデータの配列
00211     struct TValue{
00212         /// ノード値(バイナリ値がある場合は空)
00213         std::vector< UTRef<FIDocNode> > nodes;
00214         /// バイナリデータ
00215         TData data;
00216         /// ノードまたはデータの数.
00217         size_t Size() const {
00218             return nodes.size() ? nodes.size() : data.Size();
00219         }
00220     };
00221     struct TAttr: public TValue{
00222         UTString id;                ///<    属性名
00223         TAttr(){}
00224         TAttr(FIString i):id(i){}
00225         bool operator < (const TAttr& b) const { return id.compare(b.id) < 0; }
00226         bool operator == (const TAttr& b) const { return id.compare(b.id)==0; }
00227     };
00228     class TAttrs:public std::vector<TAttr>{
00229     public:
00230         typedef std::vector<TAttr> base;
00231         TAttrs(){}
00232         TAttrs(size_t sz, const TAttr a):base(sz,a){}
00233         iterator Find(FIString id) const;
00234     };
00235     class TIteratorImp:public FIIteratorImpBase{
00236     public:
00237         TAttrs::iterator it;    //  属性へのポインタ
00238         size_t pos;             //  属性内での位置
00239         FIDocNode* node;
00240 
00241         TIteratorImp(FIDocNode* n, TAttrs::const_iterator i, size_t p):node(n), it((TAttrs::iterator&)i), pos(p){}
00242         virtual FIIteratorImpBase* Clone() const { return new TIteratorImp(*this); }
00243         virtual void Next(){
00244             if (pos < it->Size()) { ++pos; }
00245             else {
00246                 if (Validate()) ++pos;
00247             }
00248         }
00249         bool Equal(const FIIteratorImpBase* bBase) const {
00250             const TIteratorImp* a = this;
00251             const TIteratorImp* b = (TIteratorImp*) bBase;
00252             return a->it == b->it && a->node == b->node && a->pos == b->pos;            
00253         }
00254         bool Validate() const;
00255 //      bool ValidateNode();
00256 //      bool ValidateData();
00257         //@{    中身へのアクセス
00258         /// idを取得
00259         virtual FIString GetId() const;
00260         /// データ属性の型を取得
00261         virtual FIString GetType() const;
00262         /// データ属性の1要素のサイズを取得
00263         virtual size_t GetElementSize() const;
00264         /// データ属性の要素数を取得
00265         virtual size_t GetNElement() const;
00266         /// データ属性を設定する.szには,実際にセットしたサイズが返る.
00267         virtual bool SetDataImp(const void* data, size_t& sz, size_t esz, FIString id, FIString type);
00268         /// データ属性を取得する.szには,実際に読み出したサイズが返る.
00269         virtual bool GetDataImp(void* data, size_t& sz);
00270         /// ノードを設定する
00271         virtual bool SetNode(FIDocNodeBase* node);
00272         /// ノードを取得する
00273         virtual FIDocNodeBase* GetNode();
00274         //@}
00275     };
00276 
00277     /// 基本クラス
00278     typedef UTTreeNode<FIDocNode> FITree;
00279 
00280 public:
00281     TAttrs attrs;
00282     FIString name;
00283     FIString type;
00284 public:
00285     ///
00286     FIDocNode(){}
00287     ///
00288     ~FIDocNode(){}
00289     //@name ノードの属性
00290     //@{
00291     /// このノードの名前の取得
00292     virtual UTString GetName() const { return name; }
00293     /// このノードの名前の設定
00294     virtual void SetName(UTString s){ name = s; }
00295     /// このノードの型名のせってい
00296     virtual void SetType(FIString t);
00297     /// このノードの型名の取得
00298     virtual FIString GetType() const;
00299     //@}
00300     
00301     //@name 木構造の操作
00302     //@{
00303     /// 親ノード
00304     virtual FIDocNodeBase* GetParent(){ return FITree::GetParent(); }
00305     /// 子ノードの数
00306     virtual int NChildren() const { return (int)FITree::Children().size(); }
00307     /// 親ノードの設定
00308     virtual void SetParent(FIDocNodeBase* n){ FITree::SetParent((FIDocNode*)n); }
00309     /// 子ノードをすべて削除
00310     virtual void ClearChildren(){ FITree::ClearChildren(); }
00311     /// 子ノードを返す
00312     virtual FIDocNodeBase* Child(int i){ return FITree::Children()[i]; }
00313     //@}
00314     
00315     //@name 属性の操作
00316     //@{    
00317     virtual FIDocNodeBase* SetNewNode(FIString id, FIString type);
00318     virtual FIIterator FirstAttr() const;
00319     virtual FIIterator LastAttr() const;
00320     virtual FIIterator FindAttr(FIString id, size_t pos=0) const;
00321     virtual bool IsLast(const FIIterator& it) const;
00322     //@}
00323 };
00324 }
00325 #endif

Springheadに対してSun Apr 16 01:57:51 2006に生成されました。  doxygen 1.4.1