00001 // Filename: xFileDataObject.cxx 00002 // Created by: drose (03Oct04) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) Carnegie Mellon University. All rights reserved. 00008 // 00009 // All use of this software is subject to the terms of the revised BSD 00010 // license. You should have received a copy of this license along 00011 // with this source code in a file named "LICENSE." 00012 // 00013 //////////////////////////////////////////////////////////////////// 00014 00015 #include "xFileDataObject.h" 00016 #include "xFileTemplate.h" 00017 #include "xFile.h" 00018 #include "xFileDataNodeTemplate.h" 00019 #include "xFileDataObjectInteger.h" 00020 #include "xFileDataObjectDouble.h" 00021 #include "xFileDataObjectString.h" 00022 #include "config_xfile.h" 00023 #include "indent.h" 00024 00025 TypeHandle XFileDataObject::_type_handle; 00026 00027 //////////////////////////////////////////////////////////////////// 00028 // Function: XFileDataObject::Destructor 00029 // Access: Public, Virtual 00030 // Description: 00031 //////////////////////////////////////////////////////////////////// 00032 XFileDataObject:: 00033 ~XFileDataObject() { 00034 } 00035 00036 //////////////////////////////////////////////////////////////////// 00037 // Function: XFileDataObject::is_complex_object 00038 // Access: Public, Virtual 00039 // Description: Returns true if this kind of data object is a complex 00040 // object that can hold nested data elements, false 00041 // otherwise. 00042 //////////////////////////////////////////////////////////////////// 00043 bool XFileDataObject:: 00044 is_complex_object() const { 00045 return false; 00046 } 00047 00048 //////////////////////////////////////////////////////////////////// 00049 // Function: XFileDataObject::get_type_name 00050 // Access: Public, Virtual 00051 // Description: Returns a string that represents the type of object 00052 // this data object represents. 00053 //////////////////////////////////////////////////////////////////// 00054 string XFileDataObject:: 00055 get_type_name() const { 00056 return get_type().get_name(); 00057 } 00058 00059 //////////////////////////////////////////////////////////////////// 00060 // Function: XFileDataObject::add_int 00061 // Access: Public 00062 // Description: Appends a new integer value to the data object, if it 00063 // makes sense to do so. Normally, this is valid only 00064 // for a DataObjectArray, or in certain special cases for 00065 // a DataNodeTemplate. 00066 //////////////////////////////////////////////////////////////////// 00067 XFileDataObject &XFileDataObject:: 00068 add_int(int int_value) { 00069 XFileDataObject *object = 00070 new XFileDataObjectInteger(get_data_def(), int_value); 00071 add_element(object); 00072 return *object; 00073 } 00074 00075 //////////////////////////////////////////////////////////////////// 00076 // Function: XFileDataObject::add_double 00077 // Access: Public 00078 // Description: Appends a new floating-point value to the data 00079 // object, if it makes sense to do so. Normally, this 00080 // is valid only for a DataObjectArray, or in certain 00081 // special cases for a DataNodeTemplate. 00082 //////////////////////////////////////////////////////////////////// 00083 XFileDataObject &XFileDataObject:: 00084 add_double(double double_value) { 00085 XFileDataObject *object = 00086 new XFileDataObjectDouble(get_data_def(), double_value); 00087 add_element(object); 00088 return *object; 00089 } 00090 00091 //////////////////////////////////////////////////////////////////// 00092 // Function: XFileDataObject::add_string 00093 // Access: Public 00094 // Description: Appends a new string value to the data object, if it 00095 // makes sense to do so. Normally, this is valid only 00096 // for a DataObjectArray, or in certain special cases for 00097 // a DataNodeTemplate. 00098 //////////////////////////////////////////////////////////////////// 00099 XFileDataObject &XFileDataObject:: 00100 add_string(const string &string_value) { 00101 XFileDataObject *object = 00102 new XFileDataObjectString(get_data_def(), string_value); 00103 add_element(object); 00104 return *object; 00105 } 00106 00107 //////////////////////////////////////////////////////////////////// 00108 // Function: XFileDataObject::add_Vector 00109 // Access: Public 00110 // Description: Appends a new Vector instance. 00111 //////////////////////////////////////////////////////////////////// 00112 XFileDataObject &XFileDataObject:: 00113 add_Vector(XFile *x_file, const LVecBase3d &vector) { 00114 XFileTemplate *xtemplate = XFile::find_standard_template("Vector"); 00115 nassertr(xtemplate != (XFileTemplate *)NULL, *this); 00116 XFileDataNodeTemplate *node = 00117 new XFileDataNodeTemplate(x_file, "", xtemplate); 00118 add_element(node); 00119 node->zero_fill(); 00120 00121 node->set(vector); 00122 00123 return *node; 00124 } 00125 00126 //////////////////////////////////////////////////////////////////// 00127 // Function: XFileDataObject::add_MeshFace 00128 // Access: Public 00129 // Description: Appends a new MeshFace instance. 00130 //////////////////////////////////////////////////////////////////// 00131 XFileDataObject &XFileDataObject:: 00132 add_MeshFace(XFile *x_file) { 00133 XFileTemplate *xtemplate = XFile::find_standard_template("MeshFace"); 00134 nassertr(xtemplate != (XFileTemplate *)NULL, *this); 00135 XFileDataNodeTemplate *node = 00136 new XFileDataNodeTemplate(x_file, "", xtemplate); 00137 add_element(node); 00138 node->zero_fill(); 00139 00140 return *node; 00141 } 00142 00143 //////////////////////////////////////////////////////////////////// 00144 // Function: XFileDataObject::add_IndexedColor 00145 // Access: Public 00146 // Description: Appends a new IndexedColor instance. 00147 //////////////////////////////////////////////////////////////////// 00148 XFileDataObject &XFileDataObject:: 00149 add_IndexedColor(XFile *x_file, int index, const LColor &color) { 00150 XFileTemplate *xtemplate = XFile::find_standard_template("IndexedColor"); 00151 nassertr(xtemplate != (XFileTemplate *)NULL, *this); 00152 XFileDataNodeTemplate *node = 00153 new XFileDataNodeTemplate(x_file, "", xtemplate); 00154 add_element(node); 00155 node->zero_fill(); 00156 00157 (*node)["index"] = index; 00158 (*node)["indexColor"] = LCAST(double, color); 00159 00160 return *node; 00161 } 00162 00163 //////////////////////////////////////////////////////////////////// 00164 // Function: XFileDataObject::add_Coords2d 00165 // Access: Public 00166 // Description: Appends a new Coords2d instance. 00167 //////////////////////////////////////////////////////////////////// 00168 XFileDataObject &XFileDataObject:: 00169 add_Coords2d(XFile *x_file, const LVecBase2d &coords) { 00170 XFileTemplate *xtemplate = XFile::find_standard_template("Coords2d"); 00171 nassertr(xtemplate != (XFileTemplate *)NULL, *this); 00172 XFileDataNodeTemplate *node = 00173 new XFileDataNodeTemplate(x_file, "", xtemplate); 00174 add_element(node); 00175 node->zero_fill(); 00176 00177 node->set(coords); 00178 00179 return *node; 00180 } 00181 00182 //////////////////////////////////////////////////////////////////// 00183 // Function: XFileDataObject::add_element 00184 // Access: Public, Virtual 00185 // Description: Adds the indicated element as a nested data element, 00186 // if this data object type supports it. Returns true 00187 // if added successfully, false if the data object type 00188 // does not support nested data elements. 00189 //////////////////////////////////////////////////////////////////// 00190 bool XFileDataObject:: 00191 add_element(XFileDataObject *element) { 00192 return false; 00193 } 00194 00195 //////////////////////////////////////////////////////////////////// 00196 // Function: XFileDataObject::output_data 00197 // Access: Public, Virtual 00198 // Description: Writes a suitable representation of this node to an 00199 // .x file in text mode. 00200 //////////////////////////////////////////////////////////////////// 00201 void XFileDataObject:: 00202 output_data(ostream &out) const { 00203 out << "(" << get_type() << "::output_data() not implemented.)"; 00204 } 00205 00206 //////////////////////////////////////////////////////////////////// 00207 // Function: XFileDataObject::write_data 00208 // Access: Public, Virtual 00209 // Description: Writes a suitable representation of this node to an 00210 // .x file in text mode. 00211 //////////////////////////////////////////////////////////////////// 00212 void XFileDataObject:: 00213 write_data(ostream &out, int indent_level, const char *) const { 00214 indent(out, indent_level) 00215 << "(" << get_type() << "::write_data() not implemented.)\n"; 00216 } 00217 00218 //////////////////////////////////////////////////////////////////// 00219 // Function: XFileDataObject::set_int_value 00220 // Access: Protected, Virtual 00221 // Description: Sets the object's value as an integer, if this is 00222 // legal. 00223 //////////////////////////////////////////////////////////////////// 00224 void XFileDataObject:: 00225 set_int_value(int int_value) { 00226 xfile_cat.error() 00227 << get_type_name() << " does not support integer values.\n"; 00228 } 00229 00230 //////////////////////////////////////////////////////////////////// 00231 // Function: XFileDataObject::set_double_value 00232 // Access: Protected, Virtual 00233 // Description: Sets the object's value as a floating-point number, 00234 // if this is legal. 00235 //////////////////////////////////////////////////////////////////// 00236 void XFileDataObject:: 00237 set_double_value(double double_value) { 00238 xfile_cat.error() 00239 << get_type_name() << " does not support floating-point values.\n"; 00240 } 00241 00242 //////////////////////////////////////////////////////////////////// 00243 // Function: XFileDataObject::set_string_value 00244 // Access: Protected, Virtual 00245 // Description: Sets the object's value as a string, if this is 00246 // legal. 00247 //////////////////////////////////////////////////////////////////// 00248 void XFileDataObject:: 00249 set_string_value(const string &string_value) { 00250 xfile_cat.error() 00251 << get_type_name() << " does not support string values.\n"; 00252 } 00253 00254 //////////////////////////////////////////////////////////////////// 00255 // Function: XFileDataObject::store_double_array 00256 // Access: Protected 00257 // Description: Stores the indicated array of doubles in the nested 00258 // elements within this object. There must be exactly 00259 // the indicated number of nested values, and they must 00260 // all accept a double. 00261 //////////////////////////////////////////////////////////////////// 00262 void XFileDataObject:: 00263 store_double_array(int num_elements, const double *values) { 00264 if (get_num_elements() != num_elements) { 00265 xfile_cat.error() 00266 << get_type_name() << " does not accept " 00267 << num_elements << " values.\n"; 00268 return; 00269 } 00270 00271 for (int i = 0; i < num_elements; i++) { 00272 get_element(i)->set_double_value(values[i]); 00273 } 00274 } 00275 00276 00277 //////////////////////////////////////////////////////////////////// 00278 // Function: XFileDataObject::get_int_value 00279 // Access: Protected, Virtual 00280 // Description: Returns the object's representation as an integer, if 00281 // it has one. 00282 //////////////////////////////////////////////////////////////////// 00283 int XFileDataObject:: 00284 get_int_value() const { 00285 return 0; 00286 } 00287 00288 //////////////////////////////////////////////////////////////////// 00289 // Function: XFileDataObject::get_double_value 00290 // Access: Protected, Virtual 00291 // Description: Returns the object's representation as a double, if 00292 // it has one. 00293 //////////////////////////////////////////////////////////////////// 00294 double XFileDataObject:: 00295 get_double_value() const { 00296 return 0.0; 00297 } 00298 00299 //////////////////////////////////////////////////////////////////// 00300 // Function: XFileDataObject::get_string_value 00301 // Access: Protected, Virtual 00302 // Description: Returns the object's representation as a string, if 00303 // it has one. 00304 //////////////////////////////////////////////////////////////////// 00305 string XFileDataObject:: 00306 get_string_value() const { 00307 return string(); 00308 } 00309 00310 //////////////////////////////////////////////////////////////////// 00311 // Function: XFileDataObject::get_double_array 00312 // Access: Protected 00313 // Description: Fills the indicated array of doubles with the values 00314 // from the nested elements within this object. There 00315 // must be exactly the indicated number of nested 00316 // values, and they must all return a double. 00317 //////////////////////////////////////////////////////////////////// 00318 void XFileDataObject:: 00319 get_double_array(int num_elements, double *values) const { 00320 if (get_num_elements() != num_elements) { 00321 xfile_cat.error() 00322 << get_type_name() << " does not contain " 00323 << num_elements << " values.\n"; 00324 return; 00325 } 00326 00327 for (int i = 0; i < num_elements; i++) { 00328 values[i] = ((XFileDataObject *)this)->get_element(i)->get_double_value(); 00329 } 00330 } 00331 00332 //////////////////////////////////////////////////////////////////// 00333 // Function: XFileDataObject::get_num_elements 00334 // Access: Protected, Virtual 00335 // Description: Returns the number of nested data elements within the 00336 // object. This may be, e.g. the size of the array, if 00337 // it is an array. 00338 //////////////////////////////////////////////////////////////////// 00339 int XFileDataObject:: 00340 get_num_elements() const { 00341 return 0; 00342 } 00343 00344 //////////////////////////////////////////////////////////////////// 00345 // Function: XFileDataObject::get_element 00346 // Access: Protected, Virtual 00347 // Description: Returns the nth nested data element within the 00348 // object. 00349 //////////////////////////////////////////////////////////////////// 00350 XFileDataObject *XFileDataObject:: 00351 get_element(int n) { 00352 xfile_cat.warning() 00353 << "Looking for [" << n << "] within data object of type " 00354 << get_type_name() << ", does not support nested objects.\n"; 00355 return NULL; 00356 } 00357 00358 //////////////////////////////////////////////////////////////////// 00359 // Function: XFileDataObject::get_element 00360 // Access: Protected, Virtual 00361 // Description: Returns the nested data element within the 00362 // object that has the indicated name. 00363 //////////////////////////////////////////////////////////////////// 00364 XFileDataObject *XFileDataObject:: 00365 get_element(const string &name) { 00366 xfile_cat.warning() 00367 << "Looking for [\"" << name << "\"] within data object of type " 00368 << get_type_name() << ", does not support nested objects.\n"; 00369 return NULL; 00370 }