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   DependentFiles::const_iterator fi;
00181   for (fi = _files.begin(); fi != _files.end(); ++fi) {
00182     const DependentFile &dfile = (*fi);
00183     indent(out, indent_level + 2)
00184       << setw(10) << dfile._size << " "
00185       << format_timestamp(dfile._timestamp) << " "
00186       << dfile._pathname << "\n";
00187   }
00188 }
00189 
00190 ////////////////////////////////////////////////////////////////////
00191 //     Function: BamCacheRecord::format_timestamp
00192 //       Access: Private, Static
00193 //  Description: Returns a timestamp value formatted nicely for
00194 //               output.
00195 ////////////////////////////////////////////////////////////////////
00196 string BamCacheRecord::
00197 format_timestamp(time_t timestamp) {
00198   static const size_t buffer_size = 512;
00199   char buffer[buffer_size];
00200 
00201   if (timestamp == 0) {
00202     // A zero timestamp is a special case.
00203     return "  (no date) ";
00204   }
00205 
00206   time_t now = time(NULL);
00207   struct tm *tm_p = localtime(&timestamp);
00208 
00209   if (timestamp > now || (now - timestamp > 86400 * 365)) {
00210     // A timestamp in the future, or more than a year in the past,
00211     // gets a year appended.
00212     strftime(buffer, buffer_size, "%b %d  %Y", tm_p);
00213   } else {
00214     // Otherwise, within the past year, show the date and time.
00215     strftime(buffer, buffer_size, "%b %d %H:%M", tm_p);
00216   }
00217 
00218   return buffer;
00219 }
00220 
00221 ////////////////////////////////////////////////////////////////////
00222 //     Function: BamCacheRecord::register_with_read_factory
00223 //       Access: Published, Static
00224 //  Description: Tells the BamReader how to create objects of type
00225 //               BamCacheRecord.
00226 ////////////////////////////////////////////////////////////////////
00227 void BamCacheRecord::
00228 register_with_read_factory() {
00229   BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
00230 }
00231 
00232 ////////////////////////////////////////////////////////////////////
00233 //     Function: BamCacheRecord::write_datagram
00234 //       Access: Published, Virtual
00235 //  Description: Writes the contents of this object to the datagram
00236 //               for shipping out to a Bam file.
00237 ////////////////////////////////////////////////////////////////////
00238 void BamCacheRecord::
00239 write_datagram(BamWriter *manager, Datagram &dg) {
00240   TypedWritableReferenceCount::write_datagram(manager, dg);
00241   dg.add_string(_source_pathname);
00242   dg.add_string(_cache_filename);
00243   dg.add_uint32(_recorded_time);
00244   dg.add_uint64(_record_size);
00245 
00246   dg.add_uint16(_files.size());
00247   DependentFiles::const_iterator fi;
00248   for (fi = _files.begin(); fi != _files.end(); ++fi) {
00249     const DependentFile &file = (*fi);
00250     dg.add_string(file._pathname);
00251     dg.add_uint32(file._timestamp);
00252     dg.add_uint64(file._size);
00253   }
00254 }
00255 
00256 ////////////////////////////////////////////////////////////////////
00257 //     Function: BamCacheRecord::make_from_bam
00258 //       Access: Protected, Static
00259 //  Description: This function is called by the BamReader's factory
00260 //               when a new object of type BamCacheRecord is encountered
00261 //               in the Bam file.  It should create the BamCacheRecord
00262 //               and extract its information from the file.
00263 ////////////////////////////////////////////////////////////////////
00264 TypedWritable *BamCacheRecord::
00265 make_from_bam(const FactoryParams &params) {
00266   BamCacheRecord *object = new BamCacheRecord;
00267   DatagramIterator scan;
00268   BamReader *manager;
00269 
00270   parse_params(params, scan, manager);
00271   object->fillin(scan, manager);
00272 
00273   return object;
00274 }
00275 
00276 ////////////////////////////////////////////////////////////////////
00277 //     Function: BamCacheRecord::fillin
00278 //       Access: Protected
00279 //  Description: This internal function is called by make_from_bam to
00280 //               read in all of the relevant data from the BamFile for
00281 //               the new BamCacheRecord.
00282 ////////////////////////////////////////////////////////////////////
00283 void BamCacheRecord::
00284 fillin(DatagramIterator &scan, BamReader *manager) {
00285   TypedWritableReferenceCount::fillin(scan, manager);
00286 
00287   _source_pathname = scan.get_string();
00288   _cache_filename = scan.get_string();
00289   _recorded_time = scan.get_uint32();
00290   _record_size = scan.get_uint64();
00291 
00292   unsigned int num_files = scan.get_uint16();
00293   _files.reserve(num_files);
00294   for (unsigned int i = 0; i < num_files; ++i) {
00295     _files.push_back(DependentFile());
00296     DependentFile &file = _files.back();
00297     file._pathname = scan.get_string();
00298     file._timestamp = scan.get_uint32();
00299     file._size = scan.get_uint64();
00300   }
00301 }
 All Classes Functions Variables Enumerations