serialization question
BlitzMax Forums/Brucey's Modules/serialization question
| ||
Can the serialization module keep track of references to other objects within fields? E.g. Type box field owner:character endtype or how about lists of objects within fields? e.g. type box field item_list:tlist endtype how about 2 dimensional arrays? with a list in each cell and where is the download? cant find it here: http://code.google.com/p/maxmods/downloads/list |
| ||
Yes, yes, and no. Any references to other objects in the object that you are serializing will be serialized too. On de-serializing, you will end up with exactly the same structure as you had before you serialized - albeit the object id's will be different. (where the object id is it's memory location). All I can say really is, try it and see ;-) Blitz's Reflection doesn't currently support arrays of more than one dimension, alas - so I'm bound by that too. Oh, and it also handles circular Object references :-) |
| ||
thanks, I looked here for the download but couldnt find it http://brucey.net/programming/blitz/ http://code.google.com/p/maxmods/downloads/list is the google protocol buffers any better? |
| ||
Yeah... it's currently available via SVN... but here's a zip of the latest source : persistence.zip (5.9 kb). There's only one example currently, but it should give you and idea of what it can do. :o) |
| ||
thanks |
| ||
Oh, you will need the libxml module btw... (for the nice xml output to work) :-) |
| ||
i had a look at the example... how would you save and load some characters and their items? e.g. type character field name$ field item_list:tlist endtype type item field name$ endtype |
| ||
This is a small example showing how to serialize the object to a String |
| ||
You can also create a "TStream", and have the object save into the stream instead. The module supports all writeable streams. To use it this way, you need to create a TPersist object, and call the SerializeToStream() method : Local pers:TPersist = New TPersist Local stream:TStream = WriteStream("example.bmo") pers.SerializeToStream(the_object, stream) stream.Close() You can also use SerializeToFile(), which takes a filename as a param. Hopefully that covers most options? :-) |
| ||
yeah I managed to save the game succesfully! this is a good module not sure about loading though EDIT- I serialized each character in my character-list, in the BMO file it says <?xml version="1.0"?> every time there is a character(game character e.g. a person), (15 times) this throws an error when I try to deserialize "there should only be one reference to <?xml version="1.0"?> in the file" EDIT- Im going to try serializing a list instead of individual objects EDIT- Hmm it seems you cant serialize a list What now? > So, to sum it up, how do you save more than 1 character? |
| ||
I put my character list inside an object and it worked! good module man |
| ||
hmm I played my game near the start saved and loaded....and it worked, I played the game a bit further SAVED and LOADED and it threw a lot of errors like this Entity: line 2: parser error : Couldn't find end of Start Tag String line 2 looking at the error and the save game file, it happens when someone writes 'lines' on to a piece of paper in the game. The words on the paper are represented by a list of arrays every line of text on the paper is an array of words this must be where it is messing up. The arrays have only 1 dimension though. I can see the errors: lines that look like this are wrong <field name="_value" ref="33EK1K" type="Object"/> they should have </field>on the end here is the paper object when it is saved: |
| ||
That isn't a whole file is it? What method are you using to save? |
| ||
no its not the whole file, just the code for an item in the game im adding all game items to a list inside a type object then im 'serializing to stream' the object |
| ||
I have trouble believing that it doesn't work for one item in a large list... it would either work... or not - generally. |
| ||
its every time 1d arrays get added to a list |
| ||
If you want, you can mail me a complete xml example that is broken, and I'll try to work out what might be going wrong. |
| ||
I tried to make an example program but it creates a weird error: this is probably related to the problems I am having 'save Import bah.persistence Import bah.libXML Type save_object Field list:TList EndType Function savegame() Local s:save_object=New save_object Local array$[5] s.list=New TList s.list.addlast(array) Local pers:TPersist = New TPersist Local stream:TStream = WriteStream("savedgame1.bmo") pers.SerializeToStream(s, stream) stream.close() EndFunction Function loadgame() Local pers:TPersist = New TPersist Local stream:TStream = ReadStream("savedgame1.bmo") If stream<>Null If pers<>Null Local t:save_object=save_object(pers.DeSerializeFromStream(stream)) EndIf EndIf EndFunction savegame() loadgame() |
| ||
Hokay, I see the problem... leave it with me.<?xml version="1.0"?> <bmo ver="1"> <save_object ref="037KY0"> <field name="list" type="TList"> <TList ref="037KZS"> <field name="_head" type="TLink"> <TLink ref="037L08"> <field name="_value" ref="037L08" type="Object"/> <field name="_succ" type="TLink"> <TLink ref="037L14"> <field name="_value" type="Object"> <String[] ref="037KYG"/> </field> <field name="_succ" ref="037L08" type="TLink"/> <field name="_pred" ref="037L08" type="TLink"/> </TLink> </field> <field name="_pred" ref="037L14" type="TLink"/> </TLink> </field> </TList> </field> </save_object> </bmo> |
| ||
I don't know if this is related, but both Firefox and IE clams [] is not allowed as part of the XML tag name, so String[] should maybe replaced with something else (or encoded in some way) to allow editing/viewing/transforming with common XML tools? [EDIT] Reading up on this, using square brackets in XML *does* seem to be allowed, so maybe it's an encoding problem, and the XML files sould be saved with <?xml version="1.0" encoding="UTF-8"?> or something? But: I tried changing the incodeing in in Notepad++ and adding encoding="UTF-8", but that did not help. |
| ||
I've committed a new version of the persistence module, which now properly supports Array Objects (rather than simply Array Fields). Turns out that the Reflection uses object identifiers such as "String[]" to indicate a string array. My code was (foolishly) just passing that through to the XML, which libxml refuses to parse. It now determines whether the object is an array, and stores it properly, using the tag "_array_". @Peter : "UTF-8" doesn't need to be specified, as it is assumed that the file is in that format unless you specify otherwise - for example "ISO-8859-1". @Jeremy : You need to remember to close your output stream. If you don't it remains open until 1) your app closes, 2) you run out of file handles and your app crashes. ;-) Thanks for the beta testing guys :-) Unless there are any other major outstanding issues, I suppose this module looks about ready to go for Release. |
| ||
Okay it seems to work now, Cool [EDIT] Took out example, testing some more... |
| ||
Interesting.. This is what I get, with TPersist.format = true ...<?xml version="1.0"?> <bmo ver="2"> <save_object ref="2GGQ9K"> <field name="list" type="TList"> <TList ref="2GGQBC"> <field name="_head" type="TLink"> <TLink ref="2GGQBS"> <field name="_value" ref="2GGQBS" type="Object"/> <field name="_succ" type="TLink"> <TLink ref="2GGQCO"> <field name="_value" type="Object"> <_array_ ref="2GGQA0" type="String" size="5"> <val></val> <val></val> <val></val> <val></val> <val></val> </_array_> </field> <field name="_succ" ref="2GGQBS" type="TLink"/> <field name="_pred" ref="2GGQBS" type="TLink"/> </TLink> </field> <field name="_pred" ref="2GGQCO" type="TLink"/> </TLink> </field> </TList> </field> </save_object> </bmo> ...which is what I'd expect. |
| ||
Sorry! It seems to be Notepad++ that is confused. Looking again it seems all good. Should there/is there - an BOM in the beginning of the file even if it is optional? ref: http://www.opentag.com/xfaq_enc.htm? It seems Notepad++ thinks it's an ANSI file. |
| ||
Libxml is kind enough to escape non-ascii characters, so if you were to say, include chinese text somewhere, you would would get encoding like this : <hello>您好彼得</hello> (thanks to the forum for encoding this example for me ;-) The BOM is only useful, I suppose, if you intend having non-ascii characters in the file somewhere. |
| ||
Makes sense. Thanks for taking the time to explain. |
| ||
thanks for the error-fix |