Definition in file load_form.h.
#include "nel/misc/types_nl.h"
#include <map>
#include <string>
#include <vector>
#include "nel/misc/path.h"
#include "nel/misc/file.h"
#include "nel/misc/sheet_id.h"
#include "nel/georges/u_form_loader.h"
#include "nel/georges/u_form.h"
Go to the source code of this file.
Functions | |
template<class T> void | loadForm (const std::vector< std::string > &sheetFilters, const std::string &packedFilename, std::map< std::string, T > &container, bool updatePackedSheet=true, bool errorIfPackedSheetNotGood=true) |
template<class T> void | loadForm (const std::string &sheetFilter, const std::string &packedFilename, std::map< std::string, T > &container, bool updatePackedSheet=true, bool errorIfPackedSheetNotGood=true) |
template<class T> void | loadForm (const std::vector< std::string > &sheetFilters, const std::string &packedFilename, std::map< NLMISC::CSheetId, T > &container, bool updatePackedSheet=true, bool errorIfPackedSheetNotGood=true) |
template<class T> void | loadForm (const std::string &sheetFilter, const std::string &packedFilename, std::map< NLMISC::CSheetId, T > &container, bool updatePackedSheet=true, bool errorIfPackedSheetNotGood=true) |
Variables | |
const uint32 | PACKED_SHEET_HEADER = 'PKSH' |
Dictionnaley entry for dependency information. | |
const uint32 | PACKED_SHEET_VERSION = 5 |
const uint32 | PACKED_SHEET_VERSION_COMPATIBLE = 0 |
|
This function is used to load values from georges sheet in a quick way.
Definition at line 522 of file load_form.h. References NLMISC::COFile::close(), NLMISC::CIFile::close(), NLGEORGES::UFormLoader::createLoader(), NLMISC::CPath::getFileList(), NLMISC::CFile::getFileModificationDate(), NLMISC::CFile::getFilename(), NLMISC::CTime::getLocalTime(), NLMISC::COFile::getPos(), NLGEORGES::UFormLoader::loadForm(), NLMISC::CPath::lookup(), nlassert, nldebug, nlerror, nlinfo, NLMISC::COFile::open(), NLMISC::CIFile::open(), PACKED_SHEET_HEADER, PACKED_SHEET_VERSION, PACKED_SHEET_VERSION_COMPATIBLE, NLGEORGES::UFormLoader::releaseLoader(), res, NLMISC::COFile::seek(), NLMISC::IStream::serial(), NLMISC::CIFile::serialBuffer(), NLMISC::IStream::serialCheck(), NLMISC::IStream::serialCont(), NLMISC::IStream::serialVersion(), NLMISC::CIFile::setCacheFileOnOpen(), sint, sint32, NLMISC::TTime, uint, and uint32. Referenced by loadForm().
00523 { 00524 std::vector<std::string> dictionnary; 00525 std::map<std::string, uint> dictionnaryIndex; 00526 std::map<std::string, std::vector<uint32> > dependencies; 00527 std::vector<uint32> dependencyDates; 00528 00529 // check the extension (i know that file like "foo.packed_sheetsbar" will be accepted but this check is enough...) 00530 nlassert (packedFilename.find (".packed_sheets") != std::string::npos); 00531 00532 std::string packedFilenamePath = NLMISC::CPath::lookup(packedFilename, false, false); 00533 if (packedFilenamePath.empty()) 00534 { 00535 packedFilenamePath = packedFilename; 00536 } 00537 00538 // make sure the CSheetId singleton has been properly initialised 00539 // NLMISC::CSheetId::init(updatePackedSheet); 00540 00541 // load the packed sheet if exists 00542 try 00543 { 00544 NLMISC::CIFile ifile; 00545 ifile.setCacheFileOnOpen(true); 00546 ifile.open (packedFilenamePath); 00547 // an exception will be launch if the file is not the good version or if the file is not found 00548 00549 nlinfo ("loadForm(): Loading packed file '%s'", packedFilename.c_str()); 00550 00551 // read the header 00552 ifile.serialCheck(PACKED_SHEET_HEADER); 00553 ifile.serialCheck(PACKED_SHEET_VERSION); 00554 sint loadFormVersion= ifile.serialVersion(PACKED_SHEET_VERSION_COMPATIBLE); 00555 00556 // Read depend block size 00557 uint32 dependBlockSize; 00558 ifile.serial(dependBlockSize); 00559 00560 // Read the dependencies only if update packed sheet 00561 if(updatePackedSheet) 00562 { 00563 // read the dictionnary 00564 { 00565 ifile.serialCont(dictionnary); 00566 } 00567 // read the dependency data 00568 { 00569 uint32 depSize; 00570 ifile.serial(depSize); 00571 for (uint i=0; i<depSize; ++i) 00572 { 00573 std::string sheetName; 00574 00575 // Avoid copy, use [] 00576 ifile.serial(sheetName); 00577 ifile.serialCont(dependencies[sheetName]); 00578 } 00579 } 00580 } 00581 // else dummy read one big block => no heavy reallocation / free 00582 else if(dependBlockSize>0) 00583 { 00584 std::vector<uint8> bigBlock; 00585 bigBlock.resize(dependBlockSize); 00586 ifile.serialBuffer(&bigBlock[0], dependBlockSize); 00587 } 00588 00589 // read the packed sheet data 00590 uint32 nbEntries; 00591 uint32 ver; 00592 ifile.serial (nbEntries); 00593 ifile.serial (ver); 00594 if(ver != T::getVersion ()) 00595 throw Exception("The packed sheet version in stream is different of the code"); 00596 ifile.serialCont (container); 00597 ifile.close (); 00598 } 00599 catch (NLMISC::Exception &e) 00600 { 00601 // clear the container because it can contains partially loaded sheet so we must clean it before continue 00602 container.clear (); 00603 if (!updatePackedSheet) 00604 { 00605 if (errorIfPackedSheetNotGood) 00606 nlerror ("loadForm(): Exception during reading the packed file and can't reconstruct them (%s)", e.what()); 00607 else 00608 nlinfo ("loadForm(): Exception during reading the packed file and can't reconstruct them (%s)", e.what()); 00609 00610 return; 00611 } 00612 else 00613 { 00614 nlinfo ("loadForm(): Exception during reading the packed file, I'll reconstruct it (%s)", e.what()); 00615 } 00616 } 00617 00618 // if we don't want to update packed sheet, we nothing more to do 00619 if (!updatePackedSheet) 00620 { 00621 nlinfo ("Don't update the packed sheet with real sheet"); 00622 return; 00623 } 00624 00625 // retreive the date of all dependency file 00626 { 00627 for (uint i=0; i<dictionnary.size(); ++i) 00628 { 00629 std::string p = NLMISC::CPath::lookup (dictionnary[i], false, false); 00630 if (!p.empty()) 00631 { 00632 uint32 d = NLMISC::CFile::getFileModificationDate(p); 00633 dependencyDates.push_back(d); 00634 } 00635 else 00636 { 00637 // file not found ! 00638 // write a future date to invalidate any file dependent on it 00639 nldebug("Can't find dependent file %s !", dictionnary[i].c_str()); 00640 dependencyDates.push_back(0xffffffff); 00641 } 00642 } 00643 } 00644 00645 // build a vector of the sheetFilters sheet ids (ie: "item") 00646 std::vector<std::string> sheetNames; 00647 { 00648 std::vector<std::string>::const_iterator first(sheetFilters.begin()), last(sheetFilters.end()); 00649 for (; first != last; ++first) 00650 NLMISC::CPath::getFileList(*first, sheetNames); 00651 00652 } 00653 00654 // if there s no file, nothing to do 00655 if (sheetNames.empty()) 00656 return; 00657 00658 // set up the current sheet in container to remove sheet that are in the container and not in the directory anymore 00659 std::map<std::string, bool> sheetToRemove; 00660 { 00661 typename std::map<std::string, T>::iterator first(container.begin()), last(container.end()); 00662 for(; first != last; ++first) 00663 sheetToRemove.insert (make_pair(first->first, true)); 00664 } 00665 00666 // check if we need to create a new .pitems or just read it 00667 uint32 packedFiledate = NLMISC::CFile::getFileModificationDate(packedFilenamePath); 00668 00669 bool containerChanged = false; 00670 00671 NLGEORGES::UFormLoader *formLoader = NULL; 00672 00673 std::vector<uint> NeededToRecompute; 00674 00675 for (uint k = 0; k < sheetNames.size(); k++) 00676 { 00677 std::string p = NLMISC::CPath::lookup (sheetNames[k], false, false); 00678 if (p.empty()) 00679 { 00680 continue; 00681 } 00682 uint32 d = NLMISC::CFile::getFileModificationDate(p); 00683 00684 // no need to remove this sheet 00685 sheetToRemove[sheetNames[k]] = false; 00686 00687 if( d > packedFiledate || container.find (sheetNames[k]) == container.end()) 00688 { 00689 NeededToRecompute.push_back(k); 00690 } 00691 else 00692 { 00693 // check the date of each parent 00694 nlassert(dependencies.find(sheetNames[k]) != dependencies.end()); 00695 std::vector<uint32> &depends = dependencies[sheetNames[k]]; 00696 00697 for (uint i=0; i<depends.size(); ++i) 00698 { 00699 if (dependencyDates[depends[i]] > packedFiledate) 00700 { 00701 nldebug("Dependancy on %s for %s not up to date !", 00702 dictionnary[depends[i]].c_str(), sheetNames[k].c_str()); 00703 NeededToRecompute.push_back(k); 00704 break; 00705 } 00706 } 00707 } 00708 } 00709 00710 nlinfo ("%d sheets checked, %d need to be recomputed", sheetNames.size(), NeededToRecompute.size()); 00711 00712 NLMISC::TTime lastTime = NLMISC::CTime::getLocalTime (); 00713 NLMISC::TTime start = NLMISC::CTime::getLocalTime (); 00714 00715 NLMISC::CSmartPtr<NLGEORGES::UForm> form; 00716 00717 for (uint j = 0; j < NeededToRecompute.size(); j++) 00718 { 00719 if(NLMISC::CTime::getLocalTime () > lastTime + 5000) 00720 { 00721 lastTime = NLMISC::CTime::getLocalTime (); 00722 if(j>0) 00723 nlinfo ("%.0f%% completed (%d/%d), %d seconds remaining", (float)j*100.0/NeededToRecompute.size(),j,NeededToRecompute.size(), (NeededToRecompute.size()-j)*(lastTime-start)/j/1000); 00724 } 00725 00726 // create the georges loader if necessary 00727 if (formLoader == NULL) 00728 { 00729 NLMISC::WarningLog->addNegativeFilter("CFormLoader: Can't open the form file"); 00730 formLoader = NLGEORGES::UFormLoader::createLoader (); 00731 } 00732 00733 // Load the form with given sheet id 00734 form = formLoader->loadForm (sheetNames[NeededToRecompute[j]].c_str ()); 00735 if (form) 00736 { 00737 // build the dependency data 00738 { 00739 std::vector<uint32> depends; 00740 std::set<std::string> dependFiles; 00741 form->getDependencies (dependFiles); 00742 nlassert(dependFiles.find(sheetNames[NeededToRecompute[j]]) != dependFiles.end()); 00743 // remove the sheet itself from the container 00744 dependFiles.erase(sheetNames[NeededToRecompute[j]]); 00745 00746 std::set<std::string>::iterator first(dependFiles.begin()), last(dependFiles.end()); 00747 for (; first != last; ++first) 00748 { 00749 std::string p = NLMISC::CPath::lookup (*first, false, false); 00750 if (!p.empty()) 00751 { 00752 uint32 date = NLMISC::CFile::getFileModificationDate(p); 00753 00754 uint dicIndex; 00755 std::string filename = NLMISC::CFile::getFilename(p); 00756 00757 if (dictionnaryIndex.find(filename) == dictionnaryIndex.end()) 00758 { 00759 // add a new dictionnary entry 00760 dicIndex = dictionnary.size(); 00761 dictionnaryIndex.insert(std::make_pair(filename, dictionnary.size())); 00762 dictionnary.push_back(filename); 00763 } 00764 else 00765 { 00766 dicIndex = dictionnaryIndex.find(filename)->second; 00767 } 00768 00769 // add the dependecy index 00770 depends.push_back(dicIndex); 00771 } 00772 } 00773 // store the dependency list with the sheet ID 00774 dependencies[sheetNames[NeededToRecompute[j]]] = depends; 00775 } 00776 00777 // add the new creature, it could be already loaded by the packed sheets but will be overwrite with the new one 00778 typedef typename std::map<std::string, T>::iterator TType1; 00779 typedef typename std::pair<TType1, bool> TType2; 00780 TType2 res = container.insert(std::make_pair(sheetNames[NeededToRecompute[j]],T())); 00781 00782 (*res.first).second.readGeorges (form, sheetNames[NeededToRecompute[j]]); 00783 containerChanged = true; 00784 } 00785 } 00786 00787 nlinfo ("%d seconds to recompute %d sheets", (uint32)(NLMISC::CTime::getLocalTime()-start)/1000, NeededToRecompute.size()); 00788 00789 // free the georges loader if necessary 00790 if (formLoader != NULL) 00791 { 00792 NLGEORGES::UFormLoader::releaseLoader (formLoader); 00793 NLMISC::WarningLog->removeFilter ("CFormLoader: Can't open the form file"); 00794 } 00795 00796 // we have now to remove sheet that are in the container and not exist anymore in the sheet directories 00797 for (std::map<std::string, bool>::iterator it2 = sheetToRemove.begin(); it2 != sheetToRemove.end(); it2++) 00798 { 00799 if(it2->second) 00800 { 00801 // informe the contained object that it is no more needed. 00802 container.find(it2->first)->second.removed(); 00803 container.erase(it2->first); 00804 containerChanged = true; 00805 dependencies.erase((*it2).first); 00806 } 00807 } 00808 00809 // now, save the new container in the packedfile 00810 try 00811 { 00812 if(containerChanged) 00813 { 00814 NLMISC::COFile ofile; 00815 ofile.open(packedFilenamePath); 00816 00817 // write the header. 00818 ofile.serialCheck(PACKED_SHEET_HEADER); 00819 ofile.serialCheck(PACKED_SHEET_VERSION); 00820 ofile.serialVersion(PACKED_SHEET_VERSION_COMPATIBLE); 00821 00822 // Write a dummy block size for now 00823 sint32 posBlockSize= ofile.getPos(); 00824 uint32 dependBlockSize= 0; 00825 ofile.serial(dependBlockSize); 00826 00827 // write the dictionnary 00828 ofile.serialCont(dictionnary); 00829 00830 // write the dependencies data 00831 uint32 depSize = dependencies.size(); 00832 ofile.serial(depSize); 00833 std::map<std::string, std::vector<uint32> >::iterator first(dependencies.begin()), last(dependencies.end()); 00834 for (; first != last; ++first) 00835 { 00836 std::string sheetName = first->first; 00837 ofile.serial(sheetName); 00838 ofile.serialCont(first->second); 00839 } 00840 00841 // Then get the dicionary + dependencies size, and write it back to posBlockSize 00842 sint32 endBlockSize= ofile.getPos(); 00843 dependBlockSize= (endBlockSize - posBlockSize) - 4; 00844 ofile.seek(posBlockSize, NLMISC::IStream::begin); 00845 ofile.serial(dependBlockSize); 00846 ofile.seek(endBlockSize, NLMISC::IStream::begin); 00847 00848 // write the sheet data 00849 uint32 nbEntries = sheetNames.size(); 00850 uint32 ver = T::getVersion (); 00851 ofile.serial (nbEntries); 00852 ofile.serial (ver); 00853 ofile.serialCont(container); 00854 ofile.close (); 00855 } 00856 } 00857 catch (NLMISC::Exception &e) 00858 { 00859 nlinfo ("loadForm(): Exception during saving the packed file, it will be recreated next launch (%s)", e.what()); 00860 } 00861 00862 // housekeeping 00863 sheetNames.clear (); 00864 } |
|
This function is used to load values from georges sheet in a quick way.
Definition at line 508 of file load_form.h. References loadForm().
00509 { 00510 std::vector<std::string> vs; 00511 vs.push_back(sheetFilter); 00512 loadForm(vs, packedFilename, container, updatePackedSheet, errorIfPackedSheetNotGood); 00513 } |
|
This function is used to load values from georges sheet in a quick way.
Definition at line 145 of file load_form.h. References NLMISC::CSheetId::buildIdVector(), NLMISC::COFile::close(), NLMISC::CIFile::close(), NLGEORGES::UFormLoader::createLoader(), NLMISC::CFile::getFileModificationDate(), NLMISC::CFile::getFilename(), NLMISC::CTime::getLocalTime(), NLMISC::COFile::getPos(), NLMISC::CSheetId::init(), NLGEORGES::UFormLoader::loadForm(), NLMISC::CPath::lookup(), nlassert, nldebug, nlerror, nlinfo, NLMISC::COFile::open(), NLMISC::CIFile::open(), PACKED_SHEET_HEADER, PACKED_SHEET_VERSION, PACKED_SHEET_VERSION_COMPATIBLE, NLGEORGES::UFormLoader::releaseLoader(), res, NLMISC::COFile::seek(), NLMISC::IStream::serial(), NLMISC::CIFile::serialBuffer(), NLMISC::IStream::serialCheck(), NLMISC::IStream::serialCont(), NLMISC::IStream::serialVersion(), NLMISC::CIFile::setCacheFileOnOpen(), sint, sint32, NLMISC::TTime, uint, and uint32.
00146 { 00147 std::vector<std::string> dictionnary; 00148 std::map<std::string, uint> dictionnaryIndex; 00149 std::map<NLMISC::CSheetId, std::vector<uint32> > dependencies; 00150 std::vector<uint32> dependencyDates; 00151 00152 // check the extension (i know that file like "foo.packed_sheetsbar" will be accepted but this check is enough...) 00153 nlassert (packedFilename.find (".packed_sheets") != std::string::npos); 00154 00155 std::string packedFilenamePath = NLMISC::CPath::lookup(NLMISC::CFile::getFilename(packedFilename), false, false); 00156 if (packedFilenamePath.empty()) 00157 { 00158 packedFilenamePath = packedFilename; 00159 } 00160 00161 // make sure the CSheetId singleton has been properly initialised 00162 NLMISC::CSheetId::init(updatePackedSheet); 00163 00164 // load the packed sheet if exists 00165 try 00166 { 00167 NLMISC::CIFile ifile; 00168 ifile.setCacheFileOnOpen(true); 00169 if (!ifile.open (packedFilenamePath)) 00170 { 00171 throw NLMISC::Exception("can't open PackedSheet %s", packedFilenamePath.c_str()); 00172 } 00173 // an exception will be launch if the file is not the good version or if the file is not found 00174 00175 nlinfo ("loadForm(): Loading packed file '%s'", packedFilename.c_str()); 00176 00177 // read the header 00178 ifile.serialCheck(PACKED_SHEET_HEADER); 00179 ifile.serialCheck(PACKED_SHEET_VERSION); 00180 sint loadFormVersion= ifile.serialVersion(PACKED_SHEET_VERSION_COMPATIBLE); 00181 00182 // Read depend block size 00183 uint32 dependBlockSize; 00184 ifile.serial(dependBlockSize); 00185 00186 // Read the dependencies only if update packed sheet 00187 if(updatePackedSheet) 00188 { 00189 // read the dictionnary 00190 { 00191 ifile.serialCont(dictionnary); 00192 } 00193 // read the dependency data 00194 { 00195 uint32 depSize; 00196 ifile.serial(depSize); 00197 for (uint i=0; i<depSize; ++i) 00198 { 00199 NLMISC::CSheetId sheetId; 00200 00201 // Avoid copy, use [] 00202 ifile.serial(sheetId); 00203 ifile.serialCont(dependencies[sheetId]); 00204 } 00205 } 00206 } 00207 // else dummy read one big block => no heavy reallocation / free 00208 else if(dependBlockSize>0) 00209 { 00210 std::vector<uint8> bigBlock; 00211 bigBlock.resize(dependBlockSize); 00212 ifile.serialBuffer(&bigBlock[0], dependBlockSize); 00213 } 00214 00215 // read the packed sheet data 00216 uint32 nbEntries; 00217 uint32 ver; 00218 ifile.serial (nbEntries); 00219 ifile.serial (ver); 00220 if(ver != T::getVersion ()) 00221 throw NLMISC::Exception("The packed sheet version in stream is different of the code"); 00222 ifile.serialCont (container); 00223 ifile.close (); 00224 } 00225 catch (NLMISC::Exception &e) 00226 { 00227 // clear the container because it can contains partially loaded sheet so we must clean it before continue 00228 container.clear (); 00229 if (!updatePackedSheet) 00230 { 00231 if (errorIfPackedSheetNotGood) 00232 nlerror ("loadForm(): Exception during reading the packed file and can't reconstruct them (%s)", e.what()); 00233 else 00234 nlinfo ("loadForm(): Exception during reading the packed file and can't reconstruct them (%s)", e.what()); 00235 00236 return; 00237 } 00238 else 00239 { 00240 nlinfo ("loadForm(): Exception during reading the packed file, I'll reconstruct it (%s)", e.what()); 00241 } 00242 } 00243 00244 // if we don't want to update packed sheet, we nothing more to do 00245 if (!updatePackedSheet) 00246 { 00247 nlinfo ("Don't update the packed sheet with real sheet"); 00248 return; 00249 } 00250 00251 // retreive the date of all dependency file 00252 { 00253 for (uint i=0; i<dictionnary.size(); ++i) 00254 { 00255 std::string p = NLMISC::CPath::lookup (dictionnary[i], false, false); 00256 if (!p.empty()) 00257 { 00258 uint32 d = NLMISC::CFile::getFileModificationDate(p); 00259 dependencyDates.push_back(d); 00260 } 00261 else 00262 { 00263 // file not found ! 00264 // write a future date to invalidate any file dependent on it 00265 nldebug("Can't find dependent file %s !", dictionnary[i].c_str()); 00266 dependencyDates.push_back(0xffffffff); 00267 } 00268 } 00269 } 00270 00271 // build a vector of the sheetFilters sheet ids (ie: "item") 00272 std::vector<NLMISC::CSheetId> sheetIds; 00273 std::vector<std::string> filenames; 00274 for (uint i = 0; i < sheetFilters.size(); i++) 00275 NLMISC::CSheetId::buildIdVector(sheetIds, filenames, sheetFilters[i]); 00276 00277 // if there s no file, nothing to do 00278 if (sheetIds.empty()) 00279 return; 00280 00281 // set up the current sheet in container to remove sheet that are in the container and not in the directory anymore 00282 std::map<NLMISC::CSheetId, bool> sheetToRemove; 00283 for (typename std::map<NLMISC::CSheetId, T>::iterator it = container.begin(); it != container.end(); it++) 00284 { 00285 sheetToRemove.insert (std::make_pair((*it).first, true)); 00286 } 00287 00288 // check if we need to create a new .pitems or just read it 00289 uint32 packedFiledate = NLMISC::CFile::getFileModificationDate(packedFilenamePath); 00290 00291 bool containerChanged = false; 00292 00293 NLGEORGES::UFormLoader *formLoader = NULL; 00294 00295 std::vector<uint> NeededToRecompute; 00296 00297 for (uint k = 0; k < filenames.size(); k++) 00298 { 00299 std::string p = NLMISC::CPath::lookup (filenames[k], false, false); 00300 if (p.empty()) continue; 00301 uint32 d = NLMISC::CFile::getFileModificationDate(p); 00302 00303 // no need to remove this sheet 00304 sheetToRemove[sheetIds[k]] = false; 00305 00306 if( d > packedFiledate || container.find (sheetIds[k]) == container.end()) 00307 { 00308 NeededToRecompute.push_back(k); 00309 } 00310 else 00311 { 00312 // check the date of each parent 00313 nlassert(dependencies.find(sheetIds[k]) != dependencies.end()); 00314 std::vector<uint32> &depends = dependencies[sheetIds[k]]; 00315 00316 for (uint i=0; i<depends.size(); ++i) 00317 { 00318 if (dependencyDates[depends[i]] > packedFiledate) 00319 { 00320 nldebug("Dependancy on %s for %s not up to date !", 00321 dictionnary[depends[i]].c_str(), sheetIds[k].toString().c_str()); 00322 NeededToRecompute.push_back(k); 00323 break; 00324 } 00325 } 00326 } 00327 } 00328 00329 nlinfo ("%d sheets checked, %d need to be recomputed", filenames.size(), NeededToRecompute.size()); 00330 00331 NLMISC::TTime last = NLMISC::CTime::getLocalTime (); 00332 NLMISC::TTime start = NLMISC::CTime::getLocalTime (); 00333 00334 NLMISC::CSmartPtr<NLGEORGES::UForm> form; 00335 std::vector<NLMISC::CSmartPtr<NLGEORGES::UForm> > cacheFormList; 00336 00337 for (uint j = 0; j < NeededToRecompute.size(); j++) 00338 { 00339 if(NLMISC::CTime::getLocalTime () > last + 5000) 00340 { 00341 last = NLMISC::CTime::getLocalTime (); 00342 if(j>0) 00343 nlinfo ("%.0f%% completed (%d/%d), %d seconds remaining", (float)j*100.0/NeededToRecompute.size(),j,NeededToRecompute.size(), (NeededToRecompute.size()-j)*(last-start)/j/1000); 00344 } 00345 00346 // create the georges loader if necessary 00347 if (formLoader == NULL) 00348 { 00349 NLMISC::WarningLog->addNegativeFilter("CFormLoader: Can't open the form file"); 00350 formLoader = NLGEORGES::UFormLoader::createLoader (); 00351 } 00352 00353 // cache used to retain information (to optimize time). 00354 if (form) 00355 cacheFormList.push_back (form); 00356 00357 // Load the form with given sheet id 00358 form = formLoader->loadForm (sheetIds[NeededToRecompute[j]].toString().c_str ()); 00359 if (form) 00360 { 00361 // build the dependency data 00362 { 00363 std::vector<uint32> depends; 00364 std::set<std::string> dependFiles; 00365 form->getDependencies (dependFiles); 00366 nlassert(dependFiles.find(sheetIds[NeededToRecompute[j]].toString()) != dependFiles.end()); 00367 // remove the sheet itself from the container 00368 dependFiles.erase(sheetIds[NeededToRecompute[j]].toString()); 00369 00370 std::set<std::string>::iterator first(dependFiles.begin()), last(dependFiles.end()); 00371 for (; first != last; ++first) 00372 { 00373 const std::string filename = NLMISC::CFile::getFilename(*first); 00374 std::map<std::string,uint>::iterator findDicIt=dictionnaryIndex.find(filename); 00375 00376 if (findDicIt!=dictionnaryIndex.end()) 00377 { 00378 depends.push_back(findDicIt->second); 00379 continue; 00380 } 00381 00382 std::string p = NLMISC::CPath::lookup (*first, false, false); 00383 if (!p.empty()) 00384 { 00385 // uint32 date = NLMISC::CFile::getFileModificationDate(p); 00386 00387 uint dicIndex; 00388 // std::string filename = NLMISC::CFile::getFilename(p); 00389 00390 // if (dictionnaryIndex.find(filename) == dictionnaryIndex.end()) 00391 // { 00392 // add a new dictionnary entry 00393 dicIndex = dictionnary.size(); 00394 dictionnaryIndex.insert(std::make_pair(filename, dictionnary.size())); 00395 dictionnary.push_back(filename); 00396 // } 00397 // else 00398 // { 00399 // dicIndex = dictionnaryIndex.find(filename)->second; 00400 // } 00401 00402 // add the dependecy index 00403 depends.push_back(dicIndex); 00404 } 00405 } 00406 // store the dependency list with the sheet ID 00407 dependencies[sheetIds[NeededToRecompute[j]]] = depends; 00408 } 00409 00410 // add the new creature, it could be already loaded by the packed sheets but will be overwrite with the new one 00411 typedef typename std::map<NLMISC::CSheetId, T>::iterator TType1; 00412 typedef typename std::pair<TType1, bool> TType2; 00413 TType2 res = container.insert(std::make_pair(sheetIds[NeededToRecompute[j]],T())); 00414 00415 (*res.first).second.readGeorges (form, sheetIds[NeededToRecompute[j]]); 00416 containerChanged = true; 00417 } 00418 } 00419 00420 if(NeededToRecompute.size() > 0) 00421 nlinfo ("%d seconds to recompute %d sheets", (uint32)(NLMISC::CTime::getLocalTime()-start)/1000, NeededToRecompute.size()); 00422 00423 // free the georges loader if necessary 00424 if (formLoader != NULL) 00425 { 00426 NLGEORGES::UFormLoader::releaseLoader (formLoader); 00427 NLMISC::WarningLog->removeFilter ("CFormLoader: Can't open the form file"); 00428 } 00429 00430 // we have now to remove sheet that are in the container and not exist anymore in the sheet directories 00431 for (std::map<NLMISC::CSheetId, bool>::iterator it2 = sheetToRemove.begin(); it2 != sheetToRemove.end(); it2++) 00432 { 00433 if((*it2).second) 00434 { 00435 nlinfo ("the sheet '%s' is not in the directory, remove it from container", (*it2).first.toString().c_str()); 00436 container.find((*it2).first)->second.removed(); 00437 container.erase((*it2).first); 00438 containerChanged = true; 00439 dependencies.erase((*it2).first); 00440 } 00441 } 00442 00443 // now, save the new container in the packedfile 00444 try 00445 { 00446 if(containerChanged) 00447 { 00448 NLMISC::COFile ofile; 00449 ofile.open(packedFilenamePath); 00450 00451 // write the header. 00452 ofile.serialCheck(PACKED_SHEET_HEADER); 00453 ofile.serialCheck(PACKED_SHEET_VERSION); 00454 ofile.serialVersion(PACKED_SHEET_VERSION_COMPATIBLE); 00455 00456 // Write a dummy block size for now 00457 sint32 posBlockSize= ofile.getPos(); 00458 uint32 dependBlockSize= 0; 00459 ofile.serial(dependBlockSize); 00460 00461 // write the dictionnary 00462 ofile.serialCont(dictionnary); 00463 00464 // write the dependencies data 00465 uint32 depSize = dependencies.size(); 00466 ofile.serial(depSize); 00467 std::map<NLMISC::CSheetId, std::vector<uint32> >::iterator first(dependencies.begin()), last(dependencies.end()); 00468 for (; first != last; ++first) 00469 { 00470 NLMISC::CSheetId si = first->first; 00471 ofile.serial(si); 00472 ofile.serialCont(first->second); 00473 } 00474 00475 // Then get the dicionary + dependencies size, and write it back to posBlockSize 00476 sint32 endBlockSize= ofile.getPos(); 00477 dependBlockSize= (endBlockSize - posBlockSize) - 4; 00478 ofile.seek(posBlockSize, NLMISC::IStream::begin); 00479 ofile.serial(dependBlockSize); 00480 ofile.seek(endBlockSize, NLMISC::IStream::begin); 00481 00482 // write the sheet data 00483 uint32 nbEntries = sheetIds.size(); 00484 uint32 ver = T::getVersion (); 00485 ofile.serial (nbEntries); 00486 ofile.serial (ver); 00487 ofile.serialCont(container); 00488 ofile.close (); 00489 } 00490 } 00491 catch (NLMISC::Exception &e) 00492 { 00493 nlinfo ("loadForm(): Exception during saving the packed file, it will be recreated next launch (%s)", e.what()); 00494 } 00495 00496 // housekeeping 00497 sheetIds.clear (); 00498 filenames.clear (); 00499 } |
|
This function is used to load values from georges sheet in a quick way.
Definition at line 132 of file load_form.h. References loadForm().
00133 { 00134 std::vector<std::string> vs; 00135 vs.push_back(sheetFilter); 00136 loadForm(vs, packedFilename, container, updatePackedSheet, errorIfPackedSheetNotGood); 00137 } |
|
Dictionnaley entry for dependency information. This function is used to load values from georges sheet in a quick way. The first time it loads the sheet and parse it with the readGeorges function provided by the user to read the value he wants. It'll generate a packed file that contains this values (using serialCont). The next launch, the function will only load the packed file and if some sheet have changed, it'll automatically regenerate the packed file. To use the loadForm(), you first have to create a class that will contains values for one sheet. This class must also implements 2 functions (readGeorges() and serial()) and 1 static functions (getVersion()) Extension file name for the packedFilename must be ".packed_sheets" Classical use (copy/paste this in your code): For each sheet in the packed sheet, an instance of this class is created and stored into an stl container. This class must be default and copy constructable. class CContainerEntry { public: CContainerEntry () : WalkSpeed(1.3f), RunSpeed(6.0f) {} float WalkSpeed, RunSpeed; load the values using the george sheet void readGeorges (const NLMISC::CSmartPtr<NLGEORGES::UForm> &form, const NLMISC::CSheetId &sheetId) { the form was found so read the true values from George form->getRootNode ().getValueByName (WalkSpeed, "Basics.MovementSpeeds.WalkSpeed"); form->getRootNode ().getValueByName (RunSpeed, "Basics.MovementSpeeds.RunSpeed"); } load/save the values using the serial system void serial (NLMISC::IStream &s) { s.serial (WalkSpeed, RunSpeed); } Event to implement any action when the sheet is no longeur existent. This method is call when a sheet have been read from the packed sheet and the associated sheet file no more exist in the directories. void removed() { any action that is needed if the sheet no more exist. } return the version of this class, increments this value when the content hof this class changed static uint getVersion () { return 1; } }; this structure is fill by the loadForm() function and will contain all you need std::map<NLMISC::CSheetId,CContainerEntry> Container; void init () { load the values using the george sheet or packed file and fill the container loadForm(".creature", "test.packed_sheets", Container); } Now you can access the Container (using the CSheedId) to know the WalkSpeed and RunSpeed of all creatures. Definition at line 120 of file load_form.h. Referenced by loadForm(). |
|
Definition at line 121 of file load_form.h. Referenced by loadForm(). |
|
Definition at line 123 of file load_form.h. Referenced by loadForm(). |