Panda3D

bamCacheRecord.cxx

00001 // Filename: bamCacheRecord.cxx
00002 // Created by:  drose (09Jun06)
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 "bamCacheRecord.h"
00016 #include "virtualFileSystem.h"
00017 #include "virtualFile.h"
00018 #include "indent.h"
00019 
00020 TypeHandle BamCacheRecord::_type_handle;
00021 
00022 ////////////////////////////////////////////////////////////////////
00023 //     Function: BamCacheRecord::Default Constructor
00024 //       Access: Private
00025 //  Description: Used when reading from a bam file.
00026 ////////////////////////////////////////////////////////////////////
00027 BamCacheRecord::
00028 BamCacheRecord() :
00029   _recorded_time(0),
00030   _record_size(0),
00031   _ptr(NULL),
00032   _ref_ptr(NULL),
00033   _record_access_time(0)
00034 {
00035 }
00036 
00037 ////////////////////////////////////////////////////////////////////
00038 //     Function: BamCacheRecord::Constructor
00039 //       Access: Private
00040 //  Description: Use BamCache::lookup() to create one of these.
00041 ////////////////////////////////////////////////////////////////////
00042 BamCacheRecord::
00043 BamCacheRecord(const Filename &source_pathname, 
00044                const Filename &cache_filename) :
00045   _source_pathname(source_pathname),
00046   _cache_filename(cache_filename),
00047   _recorded_time(0),
00048   _record_size(0),
00049   _ptr(NULL),
00050   _ref_ptr(NULL),
00051   _record_access_time(0)
00052 {
00053 }
00054 
00055 ////////////////////////////////////////////////////////////////////
00056 //     Function: BamCacheRecord::Copy Constructor
00057 //       Access: Private
00058 //  Description: Use make_copy() to make a copy.  The copy does not
00059 //               share the data pointer.
00060 ////////////////////////////////////////////////////////////////////
00061 BamCacheRecord::
00062 BamCacheRecord(const BamCacheRecord &copy) :
00063   _source_pathname(copy._source_pathname),
00064   _cache_filename(copy._cache_filename),
00065   _recorded_time(copy._recorded_time),
00066   _record_size(copy._record_size),
00067   _ptr(NULL),
00068   _ref_ptr(NULL),
00069   _record_access_time(copy._record_access_time)
00070 {
00071 }
00072 
00073 ////////////////////////////////////////////////////////////////////
00074 //     Function: BamCacheRecord::Destructor
00075 //       Access: Published, Virtual
00076 //  Description: 
00077 ////////////////////////////////////////////////////////////////////
00078 BamCacheRecord::
00079 ~BamCacheRecord() {
00080   clear_data();
00081 }
00082 
00083 ////////////////////////////////////////////////////////////////////
00084 //     Function: BamCacheRecord::dependents_unchanged
00085 //       Access: Published
00086 //  Description: Returns true if all of the dependent files are still
00087 //               the same as when the cache was recorded, false
00088 //               otherwise.
00089 ////////////////////////////////////////////////////////////////////
00090 bool BamCacheRecord::
00091 dependents_unchanged() const {
00092   VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
00093 
00094   DependentFiles::const_iterator fi;
00095   for (fi = _files.begin(); fi != _files.end(); ++fi) {
00096     const DependentFile &dfile = (*fi);
00097     PT(VirtualFile) file = vfs->get_file(dfile._pathname);
00098     if (file == (VirtualFile *)NULL) {
00099       // No such file.
00100       if (dfile._timestamp != 0) {
00101         return false;
00102       }
00103     } else {
00104       if (file->get_timestamp() != dfile._timestamp ||
00105           file->get_file_size() != dfile._size) {
00106         // File has changed timestamp or size.
00107         return false;
00108       }
00109     }
00110     
00111     // Presumably, the file is unchanged.
00112   }
00113 
00114   return true;
00115 }
00116 
00117 
00118 ////////////////////////////////////////////////////////////////////
00119 //     Function: BamCacheRecord::clear_dependent_files
00120 //       Access: Published
00121 //  Description: Empties the list of files that contribute to the data
00122 //               in this record.
00123 ////////////////////////////////////////////////////////////////////
00124 void BamCacheRecord::
00125 clear_dependent_files() {
00126   _files.clear();
00127 }
00128 
00129 ////////////////////////////////////////////////////////////////////
00130 //     Function: BamCacheRecord::add_dependent_file
00131 //       Access: Published
00132 //  Description: Adds the indicated file to the list of files that
00133 //               will be loaded to generate the data in this record.
00134 //               This should be called once for the primary source
00135 //               file, and again for each secondary source file, if
00136 //               any.
00137 ////////////////////////////////////////////////////////////////////
00138 void BamCacheRecord::
00139 add_dependent_file(const Filename &pathname) {
00140   VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
00141 
00142   _files.push_back(DependentFile());
00143   DependentFile &dfile = _files.back();
00144   dfile._pathname = pathname;
00145 
00146   PT(VirtualFile) file = vfs->get_file(pathname);
00147   if (file == (VirtualFile *)NULL) {
00148     // No such file.
00149     dfile._timestamp = 0;
00150     dfile._size = 0;
00151 
00152   } else {
00153     dfile._timestamp = file->get_timestamp();
00154     dfile._size = file->get_file_size();
00155   }
00156 }
00157 
00158 ////////////////////////////////////////////////////////////////////
00159 //     Function: BamCacheRecord::output
00160 //       Access: Published
00161 //  Description: 
00162 ////////////////////////////////////////////////////////////////////
00163 void BamCacheRecord::
00164 output(ostream &out) const {
00165   out << "BamCacheRecord " << get_source_pathname();
00166 }
00167 
00168 ////////////////////////////////////////////////////////////////////
00169 //     Function: BamCacheRecord::write
00170 //       Access: Published
00171 //  Description: 
00172 ////////////////////////////////////////////////////////////////////
00173 void BamCacheRecord::
00174 write(ostream &out, int indent_level) const {
00175   indent(out, indent_level)
00176     << "BamCacheRecord " << get_source_pathname() << "\n";
00177   indent(out, indent_level)
00178     << "recorded " << format_timestamp(_recorded_time) << "\n";
00179 
00180   indent(out, indent_level)
00181     << _files.size() << " dependent files.\n";
00182   DependentFiles::const_iterator fi;
00183   for (fi = _files.begin(); fi != _files.end(); ++fi) {
00184     const DependentFile &dfile = (*fi);
00185     indent(out, indent_level + 2)
00186       << setw(10) << dfile._size << " "
00187       << format_timestamp(dfile._timestamp) << " "
00188       << dfile._pathname << "\n";
00189   }
00190 }
00191 
00192 ////////////////////////////////////////////////////////////////////
00193 //     Function: BamCacheRecord::format_timestamp
00194 //       Access: Private, Static
00195 //  Description: Returns a timestamp value formatted nicely for
00196 //               output.
00197 ////////////////////////////////////////////////////////////////////
00198 string BamCacheRecord::
00199 format_timestamp(time_t timestamp) {
00200   static const size_t buffer_size = 512;
00201   char buffer[buffer_size];
00202 
00203   if (timestamp == 0) {
00204     // A zero timestamp is a special case.
00205     return "  (no date) ";
00206   }
00207 
00208   time_t now = time(NULL);
00209   struct tm *tm_p = localtime(&timestamp);
00210 
00211   if (timestamp > now || (now - timestamp > 86400 * 365)) {
00212     // A timestamp in the future, or more than a year in the past,
00213     // gets a year appended.
00214     strftime(buffer, buffer_size, "%b %d  %Y", tm_p);
00215   } else {
00216     // Otherwise, within the past year, show the date and time.
00217     strftime(buffer, buffer_size, "%b %d %H:%M", tm_p);
00218   }
00219 
00220   return buffer;
00221 }
00222 
00223 ////////////////////////////////////////////////////////////////////
00224 //     Function: BamCacheRecord::register_with_read_factory
00225 //       Access: Published, Static
00226 //  Description: Tells the BamReader how to create objects of type
00227 //               BamCacheRecord.
00228 ////////////////////////////////////////////////////////////////////
00229 void BamCacheRecord::
00230 register_with_read_factory() {
00231   BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
00232 }
00233 
00234 ////////////////////////////////////////////////////////////////////
00235 //     Function: BamCacheRecord::write_datagram
00236 //       Access: Published, Virtual
00237 //  Description: Writes the contents of this object to the datagram
00238 //               for shipping out to a Bam file.
00239 ////////////////////////////////////////////////////////////////////
00240 void BamCacheRecord::
00241 write_datagram(BamWriter *manager, Datagram &dg) {
00242   TypedWritableReferenceCount::write_datagram(manager, dg);
00243   dg.add_string(_source_pathname);
00244   dg.add_string(_cache_filename);
00245   dg.add_uint32(_recorded_time);
00246   dg.add_uint64(_record_size);
00247 
00248   dg.add_uint16(_files.size());
00249   DependentFiles::const_iterator fi;
00250   for (fi = _files.begin(); fi != _files.end(); ++fi) {
00251     const DependentFile &file = (*fi);
00252     dg.add_string(file._pathname);
00253     dg.add_uint32(file._timestamp);
00254     dg.add_uint64(file._size);
00255   }
00256 }
00257 
00258 ////////////////////////////////////////////////////////////////////
00259 //     Function: BamCacheRecord::make_from_bam
00260 //       Access: Protected, Static
00261 //  Description: This function is called by the BamReader's factory
00262 //               when a new object of type BamCacheRecord is encountered
00263 //               in the Bam file.  It should create the BamCacheRecord
00264 //               and extract its information from the file.
00265 ////////////////////////////////////////////////////////////////////
00266 TypedWritable *BamCacheRecord::
00267 make_from_bam(const FactoryParams &params) {
00268   BamCacheRecord *object = new BamCacheRecord;
00269   DatagramIterator scan;
00270   BamReader *manager;
00271 
00272   parse_params(params, scan, manager);
00273   object->fillin(scan, manager);
00274 
00275   return object;
00276 }
00277 
00278 ////////////////////////////////////////////////////////////////////
00279 //     Function: BamCacheRecord::fillin
00280 //       Access: Protected
00281 //  Description: This internal function is called by make_from_bam to
00282 //               read in all of the relevant data from the BamFile for
00283 //               the new BamCacheRecord.
00284 ////////////////////////////////////////////////////////////////////
00285 void BamCacheRecord::
00286 fillin(DatagramIterator &scan, BamReader *manager) {
00287   TypedWritableReferenceCount::fillin(scan, manager);
00288 
00289   _source_pathname = scan.get_string();
00290   _cache_filename = scan.get_string();
00291   _recorded_time = scan.get_uint32();
00292   _record_size = scan.get_uint64();
00293 
00294   unsigned int num_files = scan.get_uint16();
00295   _files.reserve(num_files);
00296   for (unsigned int i = 0; i < num_files; ++i) {
00297     _files.push_back(DependentFile());
00298     DependentFile &file = _files.back();
00299     file._pathname = scan.get_string();
00300     file._timestamp = scan.get_uint32();
00301     file._size = scan.get_uint64();
00302   }
00303 }
 All Classes Functions Variables Enumerations