Table des matières

FIXME Cette page n'est pas encore traduite entièrement. Merci de terminer la traduction
(supprimez ce paragraphe une fois la traduction terminée)

Packed sheet

Je ne sais pas si les infos sont déjà sur le wiki (pas sous ce nom en tout cas et rien vu d'approchant dans les titres) et que je pense que ça peut aider je vais le mettre ici et le trad en français.

Et au pire on peux toujours l’enlever si c'est déjà décrit ailleurs.

Osquallo

Text from kervala on the dev.ryzom.com wiki

Un “Packed sheet” est une façon de stocker plusieurs “George sheet” dans un format binaires. Ce qu'un Packed sheet fait c'est charger tous les sheet/forms dans un seul fichier binaires qui peux être sérializer par un “loader” qui peut automatiquement le remplir avec les bonnes données. Il va aussi mettre à jour le “Packed sheet” (si on lui dit de le faire) pour également créer un nouveau sheet (si il n'existe pas déjà) ou ajouter une nouvelle entrée dans un “Packed sheet existant.

Processus de chargement

Pour un ”Packed sheet“, vous devez déclarer une classe qui va être utiliser par le “form paker”:

Créer une class ( ou struct ) qui dis se conformer a l'interface suivante:

struct TMyLoader
 
{
 
     /**
 
      * \brief Ici vous pouvez lire dans le form si nécessaire, les stocker dans les membres de la classe TMyLoader si nécessaire.
 
      */
 
     void readGeorges (const NLMISC::CSmartPtr<NLGEORGES::UForm> &form, const NLMISC::CSheetId &sheetId);
 
 
     /**
 
      * \brief Ici vous écrivez un "Nel serial" standart pour tous les membres de TMyLoader qui doivent être empaquetés.
 
      */
 
     void serial(NLMISC::IStream &f);
 
 
     /**
 
      * \brief Cette méthode renvoi la version du Packed sheet.
 
      * Le codeur dois augmenter ce nombre à chaque fois que le packed sheet change et que la methode de sérialisation 
      * est mise à jour pour que le code supprime les vieux Packed sheets.
 
      * is updated so the code will discard old packed sheets.
 
      *
 
      * \return uint Cela dois toujours renvoyer un entier. Non-signé "unsigned" est probablement le mieux.
 
      */
 
     static uint getVersion();
 
 
     /**
 
      * \brief Ici vous pouvez écrire du code personnalisé pour le moment ou le loader dosi supprime de vieux packed sheets.
 
      * \note Rarement utilisé.
 
      */
 
     void removed();
 
};

Loader Structure/Class Notes

Maintenant que vous avez une classe conforme au prérequis des packer et loader vous devez créer un containeur pour que le “form loader” le remplisse de “sheet”. Cela dois toujours être comme un “map” similaire à celui qui suit.

Now that you have your class that conforms to the requirements of the packer and loader you have to create a conteneur for the form loader to populate with sheets. This must always be like a map similar to the one below.

Déclarer un conteneur pour tous les "sheets" chargés:

std::map<CSheetId, TMyLoader> MySheets;

Habituellement Nevrax déclare cela globalement mais il n'y a aucune contraintes à ce propos. C'est utilisé pour un seul appel à loadForm (décris plus bas) et non pour tous les “sheets” de l'application. Cette méthode charge tous les “sheets” du conteneur.

Appel du "packed sheet loader":

loadForm( "my_extension", "packed_sheet_file_name.packed_sheets", MySheets, true);

Essentielement ce que loadForm fait est d'aller a travers les fichier avec my_extension comme extensionet vérifier si il y en à des plus récent que ceux dans le ”Packed sheet“, ou si certains ont été supprimé et les marquer de façon approprié en mémoire. ensuite elle charge touts les Forms et les met dans la list de cache et supprime les fichiers trouvé manquant dans le ”Packed sheet“. Si il a changé le conteneur (ajouter de nouveau fichier, mis d'autre à jour, ou supprimé les vieux fichiers) il sauvegarde le fichier en retour comme le fichier passé en paramètres, qui est packed_sheet_file_name.packed_sheets dans l'exemple précédent. Dans le processus votre “map” va être remplie soit par la sérialisation (sheets inchangé) soit par la méthode readGeorges (ajout ou mises à jour).

Notes sur le chargement

The packed sheet form loader requires that the file extension be .packed_sheets - however the logic lets you get away with .packed_sheetsbar for example. As a matter of practice though the packed sheet extension should stay with the standard. The above function actually converts “my_extension” into a single-entry std::vector and calls:

void loadForm (const std::vector< std::string > &sheetFilters, const std::string &packedFilename, std::map< NLMISC::CSheetId, T > &container, bool updatePackedSheet=true, bool errorIfPackedSheetNotGood=true)

loadForm is a template function, as seen above it will deduce it's argument from the container paramenter, where you will pass ))MySheets((.

Résumé / Détails

As you have defined you own class to hold packed data, and as you declared you own container to hold them (in fact, the container MUST be a std::map<CSheetId, you_class> ), then it's easy to access the container with a valid sheet id to retreive your data

There is no progress callback for during packing - only a debug log every 10 seconds. But when you only load a packed sheet (without updating it with current sheets data) the loading time is very short.

CSheetId and sheet_id.bin file is a manner to uniquely identify sheet file with a 32 bit integer.

There is a (private) tool that builds the sheet_id.bin from a collection of files. The sheet_id.bin is always apended, never are old sheets removed. This ensures persistent data storage to be efficient and stable.

There is also a tool in the public CVS for retrieving information on sheets called disp_sheet_id.

So, when you program starts, you can init the sheet id system by loading the sheet_id.bin file, than CSheetId instance can be created from file name or from 32 interger and converted to/from the int or filename.

It has to be in your search path, then you call the init method in CSheetId (or somethink near that)

CSheetId::init(false);

Source: Text from kervala on the dev.ryzom.com wiki.