Title: le serialize/deserialize (Traduction du tutorial d
Description: sauver et loader les objets
Sna - June 24, 2003 07:39 AM (GMT)
le serialize/deserialize (Traduction du tutorial de Krrios)
http://www.runuo.com/discussion/viewtopic.php?t=371Pour sauver et loader le monde, RunUO utilise la serialisation. Chaque item ou mobile que vous scriptez doit obligatoirement avoir 3 methodes differentes associees a ca.
La premiere est tres simple, c'est un constructeur de serialisation appele losque l'objet est charge a partir d'un save. en general on peut se contenter d'un simple prototype.
Exemple:
| CODE |
public MyClassName( Serial serial ) : base( serial ) { }
|
Tout ce que ce code fait est appeler le constructeur de votre classe.
les 2 methodes suivantes sont utilisees pour serializer/deserializer (sauver et loader) ces methodes on un parametre chacunes, un GenericWriter et un GenericReader. ils offrent des methodes pour lire et ecrire les donnees que vous avez dans le savefile
Code:
| CODE |
public override void Serialize( GenericWriter writer )
{ base.Serialize( writer );
writer.Write( (int) 0 ); // version }
public override void Deserialize( GenericReader reader ) { base.Deserialize( reader );
int version = reader.ReadInt(); }
|
Pour les scripts simples, ou tous les champs sont serializes, c'est tout ce dont vous avez besoin.
vous pouvez remarquer un numero de "version", c'est pour la compatibilite ascendante. si vous modifiez les champs dans votre script votre save fonctionnera toujours
voici un exemple pour 2 champs, une string et un nombre int
Code:
| CODE |
public override void Serialize( GenericWriter writer )
{ base.Serialize( writer );
writer.Write( (int) 0 ); // version
writer.Write( m_StringField ); writer.Write( m_NumberField ); }
public override void Deserialize( GenericReader reader ) { base.Deserialize( reader );
int version = reader.ReadInt();
switch ( version ) { case 0: { m_StringField = reader.ReadString(); m_NumberField = reader.ReadInt();
break; } } }
|
Le "switch ( version )" vous permet de gerer ces versions, il vous permet d'ajouter par exemple un champ sans que l'objet ne sois efface pour cause d'erreur de lecture du fichier
voici comment faire pour ajouter un champ a un objet
Code:
| CODE |
public override void Serialize( GenericWriter writer )
{ base.Serialize( writer );
writer.Write( (int) 1 ); // version
writer.Write( m_StringField2 );
writer.Write( m_StringField ); writer.Write( m_NumberField ); }
public override void Deserialize( GenericReader reader ) { base.Deserialize( reader );
int version = reader.ReadInt();
switch ( version ) { case 1: { m_StringField2 = reader.ReadString();
goto case 0; } case 0: { m_StringField = reader.ReadString(); m_NumberField = reader.ReadInt();
break; } } }
|
Le numero de version est change de 0 a 1 et le champ a ete ajoute a la methode Serialize. Si ce script charge un ancien WorldFile (avec la version 0) il n'essayera pas de lire quelque chose pour "m_StringField2"
il existe aussi un autre moyen pour par exemple convertir les PlayerMobiles lors d'une upgrade, il suffit de prendre le script du nouveau PlayerMobile, et remplacer le Serialize existant par celui qu on utilisait avant, adapter le Serialize pour avoir l'integralite des donnees a sauver
on lance le serveur, on fait un SaveWorld on coupe le serveur
et la il ne suffit plus que de reconstruire le Deserialize du PlayerMobile pour qu il puisse enfin lire l'integralite des donnees
crystal - June 24, 2003 10:07 AM (GMT)
Merci pour ta contribution :)
Satch - June 25, 2003 01:31 PM (GMT)
J'ajouterai juste une chose a ces explications tres completes et parfaites.
Il est important de faire le serialize dans le meme ordre que le deserialize.
Dihel - September 10, 2004 10:57 AM (GMT)
humm ... quand la valeur a sauvegardée est d'un type qui n'est pas dans runuo, mais d'un type que l'on a créé... comment on fait ?
ou si ca vien d'un enum... ?
si j'ai
| CODE |
public enum races { Hummain, Nain, Orc, } |
que j'ai dans mon playermobile par exemple
| CODE |
... private races m_race; ...
|
comment je serialize cette variable ?
slade15 - September 10, 2004 01:03 PM (GMT)
un enum aucun probleme car un enum est en realité un int donc
m_race= (races) reader.ReadInt();
writer.Write ( (int) m_race);
pour les type qu'on crée faut que je verifier mais je pense que c'est object
Hughlander - September 23, 2004 08:52 PM (GMT)
Et si on veut sauver un item ou un objet quelconque on fait comment ?
Dihel - September 23, 2004 09:44 PM (GMT)
humm ...
c pas pareil ... ? dans le serialize deserialize de l'objet ?
slade15 - September 23, 2004 10:45 PM (GMT)
tu veux serial/deserial une variable contenat objet quel conque ou creer une rubrique serial/deserial dans le code de ce objet?
pour sauver une variable contenat un item c'est pareil
writer.Write ( (Item) item);
item = reader.ReadItem();
pour conaitre tout les type de variable qu'on peut serial/deserial allez voir dans la doc sur
GenericWriter.html
et
GenericReader.html
Hughlander - September 24, 2004 10:11 AM (GMT)
Ah oui en effet ya du monde merci