Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include "vgfx.h"
00036
00037 #include <sstream>
00038
00039 #include "common/wave_ex.h"
00040
00041
00042 namespace vgfx {
00043
00044
00045 ObjectMap::~ObjectMap(void) throw() { }
00046
00047
00048 typedef std::map<std::string, smart_ptr<Primitive> > primitive_map_t;
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058 class MapImpl : public ObjectMap {
00059 public:
00060 MapImpl(void) throw();
00061 ~MapImpl(void) throw();
00062
00063
00064 void initialize(void);
00065
00066
00067 long size(void) const throw();
00068 void newObjectID(IN const char * prefix,
00069 OUT std::string& id);
00070 void addObject(IN smart_ptr<Primitive>&);
00071 Primitive * findObject(IN const char * id) const throw();
00072 smart_ptr<Primitive> removeObject(IN const char * id);
00073
00074 private:
00075
00076 primitive_map_t m_map;
00077 long m_counter;
00078 bool m_destroying;
00079 };
00080
00081
00082
00083 MapImpl::MapImpl
00084 (
00085 void
00086 )
00087 throw()
00088 {
00089 m_destroying = false;
00090 m_counter = time(NULL) >> 16;
00091 }
00092
00093
00094
00095 MapImpl::~MapImpl
00096 (
00097 void
00098 )
00099 throw()
00100 {
00101 m_destroying = true;
00102 m_map.clear();
00103 }
00104
00105
00106
00107 void
00108 MapImpl::initialize
00109 (
00110 void
00111 )
00112 {
00113
00114 }
00115
00116
00117
00118 void
00119 MapImpl::newObjectID
00120 (
00121 IN const char * prefix,
00122 OUT std::string& id
00123 )
00124 {
00125 if (!prefix) {
00126 prefix = "obj";
00127 }
00128
00129 char buffer[64];
00130 while (true) {
00131 sprintf(buffer, "%s%lx", prefix, m_counter);
00132 if (!objtree::isValidPropertyName(buffer)) {
00133 WAVE_EX(wex);
00134 wex << "Bad prefix--invalid property name: '" << buffer;
00135 wex << "'";
00136 }
00137 ++m_counter;
00138
00139 vgfx::Primitive * p = this->findObject(buffer);
00140 if (!p) {
00141 id = buffer;
00142 return;
00143 }
00144 }
00145 }
00146
00147
00148
00149 long
00150 MapImpl::size
00151 (
00152 void
00153 )
00154 const throw()
00155 {
00156 if (m_destroying)
00157 return 0;
00158 return m_map.size();
00159 }
00160
00161
00162
00163 void
00164 MapImpl::addObject
00165 (
00166 IN smart_ptr<Primitive>& p
00167 )
00168 {
00169 ASSERT(!m_destroying, "destroying ourselves");
00170 ASSERT(p, "null primitive passed in to addObject()");
00171 const char * id = p->getID();
00172 ASSERT(id, "object has a null ID");
00173
00174 if (!objtree::isValidPropertyName(id)) {
00175 WAVE_EX(wex);
00176 wex << "Invalid object id: '" << id << "'. IDs should contain";
00177 wex << " lower-case letters and numbers only, and must begin ";
00178 wex << "with a lower-case letter.";
00179 }
00180
00181 if (this->findObject(id)) {
00182 WAVE_EX(wex);
00183 wex << "Already have an object with id '" << id << "'";
00184 }
00185
00186 m_map[id] = p;
00187 }
00188
00189
00190
00191 Primitive *
00192 MapImpl::findObject
00193 (
00194 IN const char * id
00195 )
00196 const throw()
00197 {
00198 ASSERT(id, "null ID passed in to findObject()");
00199 if (m_destroying)
00200 return NULL;
00201
00202
00203 if (!objtree::isValidPropertyName(id)) {
00204 WAVE_EX(wex);
00205 wex << "malformed object id: '" << id << "'";
00206 }
00207
00208 primitive_map_t::const_iterator i = m_map.find(id);
00209 if (m_map.end() == i) {
00210
00211 return NULL;
00212 }
00213
00214
00215
00216
00217
00218
00219 const Primitive * p = i->second;
00220 return (Primitive *) p;
00221 }
00222
00223
00224
00225 smart_ptr<Primitive>
00226 MapImpl::removeObject
00227 (
00228 IN const char * id
00229 )
00230 {
00231
00232
00233
00234 if (m_destroying) {
00235 return NULL;
00236 }
00237
00238
00239 ASSERT(id, "NULL id passed in to removeObject()");
00240 primitive_map_t::iterator i = m_map.find(id);
00241 if (m_map.end() == i) {
00242 WAVE_EX(wex);
00243 wex << "Cannot remove object from map: id '" << id;
00244 wex << "' not found.";
00245 }
00246 smart_ptr<Primitive> p = i->second;
00247 ASSERT(p.get_ref_count() > 1, "Bad ref count?");
00248
00249
00250 long refs = p->getRefCount();
00251 if (refs > 0) {
00252 WAVE_EX(wex);
00253 wex << "Cannot remove object '" << id << "' from map: ";
00254 wex << refs << " object(s) are still using it!";
00255 }
00256
00257
00258 m_map.erase(i);
00259
00260
00261
00262 return p;
00263 }
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273 smart_ptr<ObjectMap>
00274 ObjectMap::create
00275 (
00276 void
00277 )
00278 {
00279 smart_ptr<MapImpl> local = new MapImpl;
00280 ASSERT(local, "out of memory");
00281
00282 local->initialize();
00283
00284 return local;
00285 }
00286
00287
00288 };
00289