From 0ea5fc66924303d1bf73ba283a383e2aadee02f2 Mon Sep 17 00:00:00 2001 From: neodarz Date: Sat, 11 Aug 2018 20:21:34 +0200 Subject: Initial commit --- docs/doxygen/nel/a04503.html | 1146 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1146 insertions(+) create mode 100644 docs/doxygen/nel/a04503.html (limited to 'docs/doxygen/nel/a04503.html') diff --git a/docs/doxygen/nel/a04503.html b/docs/doxygen/nel/a04503.html new file mode 100644 index 00000000..28fc0713 --- /dev/null +++ b/docs/doxygen/nel/a04503.html @@ -0,0 +1,1146 @@ + + +NeL: load_form.h File Reference + + + +
+

load_form.h File Reference


Detailed Description

+quick load of values from georges sheet (using a fast load with compacted file)

+

Id
load_form.h,v 1.31 2003/11/04 09:25:09 distrib Exp
+ +

+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
+


Function Documentation

+

+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+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
+
+ + + + + +
+   + + +

+This function is used to load values from georges sheet in a quick way.

Parameters:
+ + + + +
sheetFilter a vector of string to filter the sheet in the case you need more than one filter
packedFilename the name of the file that this function will generate (extension must be "packed_sheets")
container the map that will be filled by this function
+
+ +

+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 }
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+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
+
+ + + + + +
+   + + +

+This function is used to load values from georges sheet in a quick way.

Parameters:
+ + + + +
sheetFilter a string to filter the sheet (ie: ".item")
packedFilename the name of the file that this function will generate (extension must be "packed_sheets")
container the map that will be filled by this function
+
+ +

+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 }
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+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
+
+ + + + + +
+   + + +

+This function is used to load values from georges sheet in a quick way.

Parameters:
+ + + + +
sheetFilter a vector of string to filter the sheet in the case you need more than one filter
packedFilename the name of the file that this function will generate (extension must be "packed_sheets")
container the map that will be filled by this function
+
+ +

+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 }
+
+

+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+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
+
+ + + + + +
+   + + +

+This function is used to load values from georges sheet in a quick way.

Parameters:
+ + + + +
sheetFilter a string to filter the sheet (ie: ".item")
packedFilename the name of the file that this function will generate (extension must be "packed_sheets")
container the map that will be filled by this function
+
+ +

+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 }
+
+


Variable Documentation

+

+ + + + +
+ + +
const uint32 PACKED_SHEET_HEADER = 'PKSH' +
+
+ + + + + +
+   + + +

+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().

+

+ + + + +
+ + +
const uint32 PACKED_SHEET_VERSION = 5 +
+
+ + + + + +
+   + + +

+ +

+Definition at line 121 of file load_form.h. +

+Referenced by loadForm().

+

+ + + + +
+ + +
const uint32 PACKED_SHEET_VERSION_COMPATIBLE = 0 +
+
+ + + + + +
+   + + +

+ +

+Definition at line 123 of file load_form.h. +

+Referenced by loadForm().

+


Generated on Tue Mar 16 06:42:53 2004 for NeL by + +doxygen +1.3.6
+ + -- cgit v1.2.1