00001 // Filename: filenameUnifier.cxx 00002 // Created by: drose (05Dec00) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved 00008 // 00009 // All use of this software is subject to the terms of the Panda 3d 00010 // Software license. You should have received a copy of this license 00011 // along with this source code; you will also find a current copy of 00012 // the license at http://www.panda3d.org/license.txt . 00013 // 00014 // To contact the maintainers of this program write to 00015 // panda3d@yahoogroups.com . 00016 // 00017 //////////////////////////////////////////////////////////////////// 00018 00019 #include "filenameUnifier.h" 00020 00021 #include <executionEnvironment.h> 00022 00023 Filename FilenameUnifier::_txa_filename; 00024 Filename FilenameUnifier::_txa_dir; 00025 Filename FilenameUnifier::_rel_dirname; 00026 00027 FilenameUnifier::CanonicalFilenames FilenameUnifier::_canonical_filenames; 00028 00029 //////////////////////////////////////////////////////////////////// 00030 // Function: FilenameUnifier::set_txa_filename 00031 // Access: Public, Static 00032 // Description: Notes the filename the .txa file was found in. This 00033 // may have come from the command line, or it may have 00034 // been implicitly located. This has other implications 00035 // for the FilenameUnifier, particularly in locating the bam 00036 // file that saves the filenameUnifier state from last 00037 // session. 00038 //////////////////////////////////////////////////////////////////// 00039 void FilenameUnifier:: 00040 set_txa_filename(const Filename &txa_filename) { 00041 _txa_filename = txa_filename; 00042 _txa_dir = txa_filename.get_dirname(); 00043 if (_txa_dir.empty()) { 00044 _txa_dir = "."; 00045 } 00046 make_canonical(_txa_dir); 00047 } 00048 00049 //////////////////////////////////////////////////////////////////// 00050 // Function: FilenameUnifier::set_rel_dirname 00051 // Access: Public, Static 00052 // Description: Sets the name of the directory that texture filenames 00053 // will be written relative to, when generating egg 00054 // files. This is not the directory the textures are 00055 // actually written to (see set_map_dirname()), but 00056 // rather is the name of some directory above that, 00057 // which will be the starting point for the pathnames 00058 // written to the egg files. If this is empty, the full 00059 // pathnames will be written to the egg files. 00060 //////////////////////////////////////////////////////////////////// 00061 void FilenameUnifier:: 00062 set_rel_dirname(const Filename &rel_dirname) { 00063 _rel_dirname = rel_dirname; 00064 if (!_rel_dirname.empty()) { 00065 make_canonical(_rel_dirname); 00066 } 00067 } 00068 00069 //////////////////////////////////////////////////////////////////// 00070 // Function: FilenameUnifier::make_bam_filename 00071 // Access: Public, Static 00072 // Description: Returns a new filename that's made relative to the 00073 // bam file itself, suitable for writing to the bam file. 00074 //////////////////////////////////////////////////////////////////// 00075 Filename FilenameUnifier:: 00076 make_bam_filename(Filename filename) { 00077 make_canonical(filename); 00078 filename.make_relative_to(_txa_dir); 00079 return filename; 00080 } 00081 00082 //////////////////////////////////////////////////////////////////// 00083 // Function: FilenameUnifier::get_bam_filename 00084 // Access: Public, Static 00085 // Description: Returns an absolute pathname based on the given 00086 // relative pathname, presumably read from the bam file 00087 // and relative to the bam file. 00088 //////////////////////////////////////////////////////////////////// 00089 Filename FilenameUnifier:: 00090 get_bam_filename(Filename filename) { 00091 if (!filename.empty()) { 00092 filename.make_absolute(_txa_dir); 00093 } 00094 return filename; 00095 } 00096 00097 //////////////////////////////////////////////////////////////////// 00098 // Function: FilenameUnifier::make_egg_filename 00099 // Access: Public, Static 00100 // Description: Returns a new filename that's made relative to the 00101 // rel_directory, suitable for writing out within egg 00102 // files. 00103 //////////////////////////////////////////////////////////////////// 00104 Filename FilenameUnifier:: 00105 make_egg_filename(Filename filename) { 00106 if (!filename.empty()) { 00107 make_canonical(filename); 00108 filename.make_relative_to(_rel_dirname); 00109 } 00110 return filename; 00111 } 00112 00113 //////////////////////////////////////////////////////////////////// 00114 // Function: FilenameUnifier::make_user_filename 00115 // Access: Public, Static 00116 // Description: Returns a new filename that's made relative to the 00117 // current directory, suitable for reporting to the 00118 // user. 00119 //////////////////////////////////////////////////////////////////// 00120 Filename FilenameUnifier:: 00121 make_user_filename(Filename filename) { 00122 if (!filename.empty()) { 00123 make_canonical(filename); 00124 filename.make_relative_to(ExecutionEnvironment::get_cwd()); 00125 } 00126 return filename; 00127 } 00128 00129 //////////////////////////////////////////////////////////////////// 00130 // Function: FilenameUnifier::make_canonical 00131 // Access: Private, Static 00132 // Description: Does the same thing as Filename::make_canonical()--it 00133 // converts the filename to its canonical form--but 00134 // caches the operation so that repeated calls to 00135 // filenames in the same directory will tend to be 00136 // faster. 00137 // 00138 // Also guarantees that the directory containing the 00139 // filename exists by making it if it does not. 00140 //////////////////////////////////////////////////////////////////// 00141 void FilenameUnifier:: 00142 make_canonical(Filename &filename) { 00143 if (filename.empty()) { 00144 return; 00145 } 00146 00147 string dirname = filename.get_dirname(); 00148 00149 CanonicalFilenames::iterator fi; 00150 fi = _canonical_filenames.find(dirname); 00151 if (fi != _canonical_filenames.end()) { 00152 filename.set_dirname((*fi).second); 00153 return; 00154 } 00155 00156 filename.make_dir(); 00157 filename.make_canonical(); 00158 _canonical_filenames.insert(CanonicalFilenames::value_type(dirname, filename.get_dirname())); 00159 }