00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef __GA_AttributeDict__
00019 #define __GA_AttributeDict__
00020
00021 #include "GA_API.h"
00022 #include <UT/UT_SymbolTable.h>
00023 #include <UT/UT_Pair.h>
00024 #include <UT/UT_OrderedIterator.h>
00025 #include "GA_Attribute.h"
00026 #include "GA_AttributeProxy.h"
00027
00028 class GA_AttributeSet;
00029
00030
00031
00032
00033
00034
00035 class GA_API GA_AttributeDict
00036 {
00037 public:
00038 GA_AttributeDict() {}
00039 ~GA_AttributeDict() {}
00040
00041
00042
00043 const GA_AttributeSet &getSet() const { return *mySet; }
00044 GA_AttributeSet &getSet() { return *mySet; }
00045
00046
00047
00048 int64 getMemoryUsage() const
00049 {
00050 int64 mem = sizeof(*this);
00051 mem += myTable.getMemUsage();
00052 iterator it;
00053 for (it = begin(); !it.atEnd(); ++it)
00054 mem += it.proxy()->getMemoryUsage();
00055 return mem;
00056 }
00057
00058 GA_AttributeProxy *findProxy(GA_AttributeScope scope,
00059 const char *name) const;
00060 GA_AttributeProxy *findProxyByFullName(const char *name) const
00061 {
00062 UT_Thing thing;
00063 if (myTable.findSymbol(name, &thing))
00064 {
00065 return thing.asPointer<GA_AttributeProxy>();
00066 }
00067 return NULL;
00068 }
00069
00070 GA_Attribute *find(GA_AttributeScope scope, const char *name) const;
00071 GA_Attribute *findByFullName(const char *name) const
00072 {
00073 GA_AttributeProxy *proxy = findProxyByFullName(
00074 name);
00075 return proxy ? proxy->getAttribute() : NULL;
00076 }
00077
00078 void addByFullName(const char *name, GA_AttributeProxy *proxy)
00079 { myTable.addSymbol(name, proxy); }
00080 int removeByFullName(const char *name)
00081 { return myTable.deleteSymbol(name); }
00082 void clear()
00083 { myTable.clear(); }
00084
00085 uint entries() const
00086 { return myTable.entries(); }
00087 uint entries(GA_AttributeScope scope) const
00088 {
00089 if (scope != GA_SCOPE_INVALID)
00090 {
00091 iterator it = begin(scope);
00092 uint count = 0;
00093 for ( ; !it.atEnd(); ++it)
00094 count++;
00095 return count;
00096 }
00097 else
00098 return entries();
00099 }
00100 uint empty() const
00101 { return myTable.entries(); }
00102 uint empty(GA_AttributeScope scope) const
00103 { return entries(scope) == 0; }
00104
00105 typedef int (*AttributeTraverseCallback)(GA_Attribute*, const char*, void*);
00106 int traverseConst( AttributeTraverseCallback F, void *data) const
00107 {
00108 UT_Pair<AttributeTraverseCallback, void*> p(F, data);
00109 return myTable.traverseConst(traverseProxyCallback, &p);
00110 }
00111
00112 class GA_API iterator
00113 {
00114 public:
00115 iterator() : myTraverser(), myDict(NULL),
00116 myScope(GA_SCOPE_INVALID) {}
00117 iterator(GA_AttributeScope scope) : myTraverser(), myDict(NULL),
00118 myScope(scope) {}
00119 iterator(const iterator &src) { *this = src; }
00120 ~iterator() {}
00121
00122 const char *internalName() const
00123 { return myTraverser.name(); }
00124 const char *name() const
00125 {
00126 const GA_Attribute *atr =
00127 const_cast<iterator *>(this)->attrib();
00128 return atr ? atr->getName() : 0;
00129 }
00130 GA_AttributeProxy *proxy()
00131 {
00132 return myTraverser.thing().
00133 asPointer<GA_AttributeProxy>();
00134 }
00135 GA_Attribute *attrib()
00136 {
00137 return proxy()->getAttribute();
00138 }
00139 GA_Attribute *operator*()
00140 {
00141 return attrib();
00142 }
00143 int operator==(const iterator &cmp) const
00144 { return myTraverser == cmp.myTraverser; }
00145 int operator!=(const iterator &cmp) const
00146 { return myTraverser != cmp.myTraverser; }
00147 bool atEnd() const
00148 {
00149 return myTraverser.atEnd();
00150 }
00151 iterator &operator++()
00152 {
00153 ++myTraverser;
00154 if (myScope != GA_SCOPE_INVALID)
00155 {
00156 while (!atEnd() &&
00157 attrib()->getScope() != myScope)
00158 ++myTraverser;
00159 }
00160 return *this;
00161 }
00162 const iterator &operator=(const iterator &src)
00163 {
00164 myTraverser = src.myTraverser;
00165 myDict = src.myDict;
00166 myScope = src.myScope;
00167 return *this;
00168 }
00169 private:
00170 iterator(const GA_AttributeDict *dict,
00171 GA_AttributeScope scope)
00172 : myTraverser(dict->myTable.begin()),
00173 myDict(dict), myScope(scope)
00174 {
00175 if (myScope != GA_SCOPE_INVALID)
00176 {
00177 if (!atEnd() && attrib()->getScope() != myScope)
00178 operator++();
00179 }
00180 }
00181 UT_SymbolTable::traverser myTraverser;
00182 const GA_AttributeDict *myDict;
00183 GA_AttributeScope myScope;
00184 friend class GA_AttributeDict;
00185 };
00186
00187 static int compareAlpha(GA_Attribute *const*a, GA_Attribute *const*b)
00188 {
00189 const char *aname = (*a)->getName();
00190 const char *bname = (*b)->getName();
00191 if (!strcmp(aname, "P"))
00192 return -1;
00193 if (!strcmp(bname, "P"))
00194 return 1;
00195
00196
00197 return UT_String::compareNumberedString(aname,bname,false);
00198 }
00199
00200
00201 typedef UT_OrderedIterator< GA_Attribute *, iterator > ordered_iterator;
00202
00203
00204
00205 iterator begin(GA_AttributeScope scope = GA_SCOPE_INVALID) const
00206 { return iterator(this, scope); }
00207 iterator end(GA_AttributeScope scope = GA_SCOPE_INVALID) const
00208 { return iterator(scope); }
00209
00210
00211
00212
00213 ordered_iterator obegin(GA_AttributeScope scope = GA_SCOPE_INVALID) const
00214 {
00215 iterator it(this, scope);
00216 return ordered_iterator(it, compareAlpha);
00217 }
00218 ordered_iterator oend(GA_AttributeScope scope = GA_SCOPE_INVALID) const
00219 {
00220 return ordered_iterator();
00221 }
00222
00223
00224
00225
00226 void setSet(GA_AttributeSet *s) { mySet = s; }
00227 void setMinLoadFactor(float minload) { myTable.setMinLoadFactor(minload); }
00228 void reserveNewSymbolTableSpace(int n)
00229 {
00230 if (myTable.entries() + n > myTable.size())
00231 myTable.reserveTableSize(myTable.entries() + n);
00232 }
00233
00234
00235 private:
00236 static int traverseProxyCallback(UT_Thing &thing, const char *key,
00237 void *data)
00238 {
00239 UT_Pair<AttributeTraverseCallback, void*> *p =
00240 static_cast<UT_Pair<AttributeTraverseCallback,
00241 void*> *>(data);
00242 GA_Attribute *a =
00243 static_cast<GA_AttributeProxy *>(
00244 thing.value.voidp)->getAttribute();
00245 return (*p->myFirst)(a, key, p->mySecond);
00246 }
00247
00248 UT_SymbolTable myTable;
00249 GA_AttributeSet *mySet;
00250 };
00251
00252 #endif
00253