|
-
Jan 21st, 2013, 06:42 AM
#1
Thread Starter
Lively Member
Save and load a class
Hey,
I need a code so I can save this class. The problem is that it cant be done with XML-serialazation because it as initial arrays. [Attribute(50,50), Tile(50,50) etc.)
How will I save/load this class with initial arrays?
Code:
Public Class Map
Public Attribute(50, 50) As AttributeRec
Public Tile(50, 50) As LayerRec
Public Npc(50) As MapNpcRec
Public Item(50) As MapItemRec
Public Structure MapItemRec
Public X As Integer
Public Y As Integer
Public ItemID As Integer
Public ItemAmmount As Integer
End Structure
Public Structure MapNpcRec
Public SpawnX As Integer
Public SpawnY As Integer
Public X As Integer
Public Y As Integer
Public NpcID As Integer
End Structure
Public Structure LayerRec
Public Ground As TileRec
Public Mask As TileRec
Public Mask2 As TileRec
Public Fringe As TileRec
Public Fringe2 As TileRec
End Structure
Public Structure TileRec
Public imgX As Integer
Public imgY As Integer
Public Tileset As Integer
End Structure
Public Structure AttributeRec
Public Attribute As Integer
Public Value As Integer
End Structure
End Class
thanks
-
Jan 21st, 2013, 06:54 AM
#2
Re: Save and load a class
-
Jan 21st, 2013, 07:23 AM
#3
Thread Starter
Lively Member
Re: Save and load a class
I can't get it work, I don't understand it
I've done the following:
Code:
Public objMap(50) As Map
Code:
Private Sub SaveToolStripMenuItem_Click(sender As System.Object, e As System.EventArgs) Handles SaveToolStripMenuItem.Click
objMap(0) = New Map
objMap(0).Name = "Test Map"
objMap(0).Tile(5, 5).Ground.imgX = 5
objMap(0).Tile(5, 5).Ground.imgY = 5
objMap(0).Tile(5, 5).Ground.Tileset = 1
MapSL.SaveMap(0)
MsgBox("SAVED")
End Sub
Code:
Public Shared Sub SaveMap(ByVal Map As Integer)
Dim FF As Integer = FreeFile()
FileOpen(FF, Windows.Forms.Application.StartupPath & "/Maps/1.map", OpenMode.Binary, OpenAccess.Write)
FilePutObject(FF, objMap(0))
FileClose(FF)
End Sub
and if I use FilePut instead of FilePutObject I'll get the next warning:
code
Code:
Public Shared Sub SaveMap(ByVal Map As Integer)
Dim FF As Integer = FreeFile()
FileOpen(FF, Windows.Forms.Application.StartupPath & "/Maps/1.map", OpenMode.Binary, OpenAccess.Write)
FilePut(FF, objMap(0))
FileClose(FF)
End Sub
warning:
Code:
Warning 1 'Public Sub FilePut(FileNumber As Object, Value As Object, [RecordNumber As Object = -1])' is obsolete: 'This member has been deprecated. Please use FilePutObject to write Object types, or coerce FileNumber and RecordNumber to Integer for writing non-Object types. http://go.microsoft.com/fwlink/?linkid=14202'. C:\Users\Jim Paul\Dropbox\Prive\Game Editor 1.0\Game Editor 1.0\Game Editor 1.0\Map Editor\Map.vb 66 9 Game Editor 1.0
-
Jan 21st, 2013, 11:35 AM
#4
Re: Save and load a class
Binary serialization is the solution, and it is far easier than writing to a file like that. However, it creates a binary file, which you won't be able to edit, or even easily view, by hand. Here's one thread of many on the subject:
http://www.vbforums.com/showthread.php?699885
In this thread, I show a pair of methods I use to serialize to a string for storage in My.Settings, but that could just as easily be serialized to a file, as well. There are many more examples if you search on Binary Serialization.
My usual boring signature: Nothing
 
-
Jan 22nd, 2013, 06:12 AM
#5
Thread Starter
Lively Member
Re: Save and load a class
 Originally Posted by Shaggy Hiker
Binary serialization is the solution, and it is far easier than writing to a file like that. However, it creates a binary file, which you won't be able to edit, or even easily view, by hand. Here's one thread of many on the subject:
http://www.vbforums.com/showthread.php?699885
In this thread, I show a pair of methods I use to serialize to a string for storage in My.Settings, but that could just as easily be serialized to a file, as well. There are many more examples if you search on Binary Serialization.
I don't understand the code
Code:
Private Function SerializeTheme() As String
If mConfiguration IsNot Nothing AndAlso mConfiguration.ThemeID <> -1 Then
Try
Dim bf As New System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
Dim mStream As New System.IO.MemoryStream
Dim bReader As New System.IO.BinaryReader(mStream)
bf.Serialize(mStream, mConfiguration)
mStream.Position = 0
Return Convert.ToBase64String(bReader.ReadBytes(CInt(mStream.Length)))
Catch ex As Exception
Windows.Forms.MessageBox.Show("Failed while saving the theme. The default will be used next time. The error message was: " & Environment.NewLine & Environment.NewLine & ex.Message, "Serial Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
Return String.Empty
End Try
Else
Return String.Empty
End If
End Function
Private Shared Function DeSerializeTheme(ByVal themeAsString As String) As ThemeWrapper
Dim bf As New System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
Dim mStream As New System.IO.MemoryStream
Dim bWriter As New System.IO.BinaryWriter(mStream)
If themeAsString = String.Empty Then
Return Nothing
End If
Try
bWriter.Write(Convert.FromBase64String(themeAsString))
mStream.Position = 0
Return DirectCast(bf.Deserialize(mStream), ThemeWrapper)
Catch ex As Exception
Return Nothing
End Try
End Function
But also, you said
Binary serialization is the solution, and it is far easier than writing to a file like that. However, it creates a binary file, which you won't be able to edit, or even easily view, by hand.
The file should be readable by another application. This is because I work with a map editor. The main game should read the map (the file you create) - what you can make with the map editor. I have not build in my map editor in my game. So it wont be handy to save it in my.settings
Isn't there an easy way to save a class with initial arrays?
-
Jan 22nd, 2013, 06:43 AM
#6
Re: Save and load a class
and if I use FilePut instead of FilePutObject I'll get the next warning:
have you tryed putting FilePutObject for the link I suguested instade of fileput as it states in the error.
here something else I found to duno if it's any good.
http://www.programmersheaven.com/mb/...t-into-a-file/
Last edited by BenJones; Jan 22nd, 2013 at 06:49 AM.
-
Jan 22nd, 2013, 10:29 AM
#7
Re: Save and load a class
Readable by a different process certainly does complicate binary serialization, because information about the serialization context is stored into the binary stream. This means that to use it between two different apps, the binary serialization would have to be performed in a dll that both apps referenced. That isn't all that hard to do, since you'd only need two functions in the dll, but it is certainly harder.
Still, you may say that you don't understand the code, but I'm storing an object of any arbitrary complexity using 6 lines of which three are object declarations, so you'd be hard pressed to come up with something that is more versatile and efficient.
There isn't some inherently "easy" way to save an array, nor can there be if you think about it. Your array is an array of objects that contain 2D arrays of objects that, themselves, contain members or structures. If you were to lay that out in memory, what would it look like? Ultimately, it would look like a whole series of bytes, since arrays are stored in order. However, the actual array only need hold the address of the objects that it contains, so storing the bytes that make up the array would be entirely meaningless, since those bytes would be addresses for memory that would immediately go away when the program unloaded, and they wouldn't be restored the same way except by accident. So, how would you expect it to be simple to store such complex data in any simple fashion if the data doesn't even have to exist in contiguous memory blocks in memory?
In some way, you are hoping to have a mechanism that will hide the real difficulty of the layout of the complex data you wish to store. In both approaches, you are looking at storage into a binary file, where all the complexity is hidden behind some magic that you need not understand. So, the answer is: No, there is no simple solution, nor can there be, but binary serialization will work and is simple, even if you don't understand it, and the FilePut method is just an older version (and potentially less effective) of working with binary files.
My usual boring signature: Nothing
 
-
Jan 22nd, 2013, 01:08 PM
#8
Thread Starter
Lively Member
Re: Save and load a class
 Originally Posted by Shaggy Hiker
Readable by a different process certainly does complicate binary serialization, because information about the serialization context is stored into the binary stream. This means that to use it between two different apps, the binary serialization would have to be performed in a dll that both apps referenced. That isn't all that hard to do, since you'd only need two functions in the dll, but it is certainly harder.
Still, you may say that you don't understand the code, but I'm storing an object of any arbitrary complexity using 6 lines of which three are object declarations, so you'd be hard pressed to come up with something that is more versatile and efficient.
There isn't some inherently "easy" way to save an array, nor can there be if you think about it. Your array is an array of objects that contain 2D arrays of objects that, themselves, contain members or structures. If you were to lay that out in memory, what would it look like? Ultimately, it would look like a whole series of bytes, since arrays are stored in order. However, the actual array only need hold the address of the objects that it contains, so storing the bytes that make up the array would be entirely meaningless, since those bytes would be addresses for memory that would immediately go away when the program unloaded, and they wouldn't be restored the same way except by accident. So, how would you expect it to be simple to store such complex data in any simple fashion if the data doesn't even have to exist in contiguous memory blocks in memory?
In some way, you are hoping to have a mechanism that will hide the real difficulty of the layout of the complex data you wish to store. In both approaches, you are looking at storage into a binary file, where all the complexity is hidden behind some magic that you need not understand. So, the answer is: No, there is no simple solution, nor can there be, but binary serialization will work and is simple, even if you don't understand it, and the FilePut method is just an older version (and potentially less effective) of working with binary files.
I got this code from a VB6 Map Editor what works fine.
Code:
' **********
' ** Maps **
' **********
Sub SaveMap(ByVal mapNum As Long)
Dim filename As String
Dim F As Long
Dim x As Long
Dim y As Long
filename = App.Path & "\data\maps\map" & mapNum & ".dat"
F = FreeFile
Open filename For Binary As #F
Put #F, , Map(mapNum).Name
Put #F, , Map(mapNum).Music
Put #F, , Map(mapNum).Revision
Put #F, , Map(mapNum).Moral
Put #F, , Map(mapNum).Up
Put #F, , Map(mapNum).Down
Put #F, , Map(mapNum).Left
Put #F, , Map(mapNum).Right
Put #F, , Map(mapNum).BootMap
Put #F, , Map(mapNum).BootX
Put #F, , Map(mapNum).BootY
Put #F, , Map(mapNum).MaxX
Put #F, , Map(mapNum).MaxY
For x = 0 To Map(mapNum).MaxX
For y = 0 To Map(mapNum).MaxY
Put #F, , Map(mapNum).Tile(x, y)
Next
Next
For x = 1 To MAX_MAP_NPCS
Put #F, , Map(mapNum).Npc(x)
Next
Close #F
DoEvents
End Sub
Sub SaveMaps()
Dim i As Long
For i = 1 To MAX_MAPS
Call SaveMap(i)
Next
End Sub
isn't it just possible to convert this code to vb 2010? This code isn't hard at all. Is this possible or not?
-
Jan 22nd, 2013, 02:50 PM
#9
Re: Save and load a class
Yeah, VB6 had a means to insert things into binary files. There have been a few threads on here talking about that. I think one of them, about a year ago, found a way to do something like that in .NET. However, what they were trying to do was to edit a single item in a binary file that contained many such items. In other words, they wanted to be able to access random items in the file. For a map editor, that's almost certainly a bad idea. It may seem to have some appeal, since you would want to be able to edit points in the map, but it will always be easier to do so to a map in memory rather than a map in a file, so the editor should load the map and edit the map in memory, then write the map back out again. Therefore, editing a single element in the file isn't necessary at all, so the solution from that thread, if there even was a solution (I may be remembering it wrong) doesn't really apply to your situation.
Still, the bottom line is that .NET and VB6 handle binary files in a different fashion, so it may not be possible. I've written a couple different map editors, and since binary serialization does the job so simply, I just use that. I agree that the code you have posted looks pretty simple, but the code I posted was six lines for saving and another six for loading, regardless of the size of the object. What that code you just posted did is impressive when you think about it. What they are doing is taking objects and writing out every single property one after the other. They could just as easily have written to a text file using that technique, as the organization in the file would be simple indeed. If you consider what little you have shown of your maps, you'd have to write a vastly more complex routine to achieve the same end using that code. After all, from what little you posted, consider what you would have to do to save the Tile array alone:
For each tile in the 50x50 array, write out each member. However, since each member is itself an object, you'd have to write out not just the members, but all the members of each member. To read it back in you'd have to create the LayerRec items, then load the values from the file back into them. By my calculation, that's 15 writes for each tile, though the tiles can be written sequentially in a loop, as noted.
If you are willing to do that, why not write to a text file? They wouldn't rely on old VB6 methods that may or may not work quite the same, and the only difference would be that you would be able to edit the textfile in any text editor, such as notepad.
My usual boring signature: Nothing
 
-
Jan 22nd, 2013, 03:24 PM
#10
Thread Starter
Lively Member
Re: Save and load a class
 Originally Posted by Shaggy Hiker
Yeah, VB6 had a means to insert things into binary files. There have been a few threads on here talking about that. I think one of them, about a year ago, found a way to do something like that in .NET. However, what they were trying to do was to edit a single item in a binary file that contained many such items. In other words, they wanted to be able to access random items in the file. For a map editor, that's almost certainly a bad idea. It may seem to have some appeal, since you would want to be able to edit points in the map, but it will always be easier to do so to a map in memory rather than a map in a file, so the editor should load the map and edit the map in memory, then write the map back out again. Therefore, editing a single element in the file isn't necessary at all, so the solution from that thread, if there even was a solution (I may be remembering it wrong) doesn't really apply to your situation.
Still, the bottom line is that .NET and VB6 handle binary files in a different fashion, so it may not be possible. I've written a couple different map editors, and since binary serialization does the job so simply, I just use that. I agree that the code you have posted looks pretty simple, but the code I posted was six lines for saving and another six for loading, regardless of the size of the object. What that code you just posted did is impressive when you think about it. What they are doing is taking objects and writing out every single property one after the other. They could just as easily have written to a text file using that technique, as the organization in the file would be simple indeed. If you consider what little you have shown of your maps, you'd have to write a vastly more complex routine to achieve the same end using that code. After all, from what little you posted, consider what you would have to do to save the Tile array alone:
For each tile in the 50x50 array, write out each member. However, since each member is itself an object, you'd have to write out not just the members, but all the members of each member. To read it back in you'd have to create the LayerRec items, then load the values from the file back into them. By my calculation, that's 15 writes for each tile, though the tiles can be written sequentially in a loop, as noted.
If you are willing to do that, why not write to a text file? They wouldn't rely on old VB6 methods that may or may not work quite the same, and the only difference would be that you would be able to edit the textfile in any text editor, such as notepad.
Oh really.. Thats dumb.. I tough the code to save a map would be easy. I've finished my game editors with save functions except the map editor. This because I can't get it saved as you understand.
my teleport editor, Npc editor, Item Editor, Skill Editor, Shop editor works perfectly with XML-serialization because there are no initial arrays.
Code:
Imports System.IO
Imports System.Xml.Serialization
Public Class Teleport
Public Name As String
Public Map As Integer
Public X As Integer
Public Y As Integer
End Class
Public Class TeleportSL
Public Shared Function LoadTeleport(ByVal fileName As String) As Teleport
Dim ser As New XmlSerializer(GetType(Teleport))
Dim fs As New FileStream(fileName, FileMode.Open)
Dim ret As Teleport
ret = DirectCast(ser.Deserialize(fs), Teleport)
fs.Close()
fs.Dispose()
Return ret
End Function
Public Shared Sub SaveTeleport(ByVal teleport As Teleport, ByVal fileName As String)
Dim ser As New XmlSerializer(GetType(Teleport))
Dim fs As New FileStream(fileName, FileMode.Create)
ser.Serialize(fs, teleport)
fs.Close()
fs.Dispose()
End Sub
End Class
What you say is right, because with the code below (I made before your last post) this saving the map correctly - but it won't load it back. the map name will be "" when I load the file.
Code:
Public Module Map
Public Const MAX_MAPS = 10
Public xMap(0 To MAX_MAPS) As MapRec
Public Structure MapRec
Public Name As String
Public Tile(,) As TileRec
Public MaxX As Integer
Public MaxY As Integer
End Structure
Public Structure TileRec
Public Layer() As TileDataRec
Public Attribute As Integer
End Structure
Public Structure TileDataRec
Public X As Integer
Public Y As Integer
Public Tileset As Integer
End Structure
End Module
Public Class LoadMap
Public Shared Sub LoadMaps()
Dim filename As String
Dim F As Integer = FreeFile()
filename = Application.StartupPath & "/" & 1 & ".dat"
FileOpen(F, filename, OpenMode.Binary, OpenAccess.Read)
FileGet(F, xMap(1).Name)
FileClose(F)
End Sub
End Class
Public Class SaveMap
Public Shared Sub SaveMap(ByVal MapNum As Long)
Dim FileName As String
Dim F As Integer
F = FreeFile()
FileName = Application.StartupPath & "/" & MapNum & ".dat"
FileOpen(F, FileName, OpenMode.Binary, OpenAccess.Write)
FilePut(F, xMap(MapNum).Name)
FileClose(F)
Application.DoEvents()
End Sub
End Class
Can you make me a working save function for my 2D-Map Arrays?
-
Jan 22nd, 2013, 04:01 PM
#11
Re: Save and load a class
You're a whole lot closer than you give yourself credit for. There are some limitations to XML serialization, and this may be one of them, but check that first. An XML serialized file would work a bit more easily than a binary serialized file for what you are trying to do. The nice thing about an XML serialized file is that you can look to see whether it worked, and how it worked, and do so easily enough. Use either Wordpad or Notepad (one works well for this type of file, the other really does not, but I forget which it is) to open the file. XML has plenty of oddities in it, but even if you are not familiar with XML, it should look VERY familiar. In fact, it should show all of your data. However, it may not, because I seem to remember reading that XML serialization didn't work on arrays. I haven't used it, so I have no experience with it, but by opening the file you will probably be able to see whether or not all your data is there. Of course, if it IS all there, it would be very tedious to read, so you won't want to check everything. Basically, I would expect that either you would have barely anything, only one tile, or all of them. If you have all of them, then the problem lies with reading them back in. If you have one of the first two options, then XML serialization failed. You could start a different thread on that if you still wanted to pursue it. You are very close, as it stands, the only real question I have is whether or not XML serialization even works on arrays.
In any case, if you look at the binary serialization and compare it to what you already have, you will see that the two are quite similar. I wrapped things in an exception handler because you can never really trust files, but aside from that, the lines are really quite similar. You have an XMLSerializer, I have a BinaryFormatter. I used a memorystream, you used a file stream, but a stream is a stream, and a filestream is the one you want to be using. I then added in a bit about taking the stream and converting the bytes to a string, but that was just so I could put the data into a My.Settings property. Since you aren't doing that, you don't need any such thing.
Unfortunately, that does leave a couple complications. The first one is utterly trivial, as you need to decorate all structures that you want to serialize with the <Serializable()> attribute. You'd just put that before Public. You can do some goofy stuff with that, but you don't need to. I'm not quite sure what that attribute does, but I suspect it may have to do with how the structure is arranged in memory. In any case, you can't serialize anything that lacks the attribute.
The other complication is as I noted: Binary serialization includes the application that serialized it, and you can't deserialize it with a different application. XMLSerialization, and that binary file thing from VB6 rather finessed the problem because there isn't any type information included in any of that. XMLSerialization is just plain text with a minimal amount of structuring, whereas the VB6 routine was just writing some bytes. An integer probably took four bytes in such a file, and there was no problem with your reading back those four, or reading back only two of them, or reading back the wrong four. If you didn't do the reading exactly the way the data was organized in the file, you'd get something back, but it would be junk. What this meant was that using either of those two types of files, your map editor and your main program didn't have to have the same types at all. Most likely, you would copy the types from one to the other, so they both would have the same, but there would be nothing enforcing that other than your own whim (XML serialization would enforce it to some extent, but only very lightly, and you could circumvent that easily). In the map editor, you could name the structures something different, or the properties, or have fewer properties, or have them be different types (with some limitations). They would be the same only by chance.
Binary serialization doesn't allow that. If you serialize an array of MapRec, then any program that deserializes it has to have access to the MapRec type. It's not enough to just have a type called MapRec in the application, nor is it enough to have the right properties in that type. Instead, the program that deserializes the object must have the same object that was serialized, and therefore it must be the same Assembly. That means that you can't have one program serialize and a different program be able to do anything with that file. I haven't found a way around this, but then again, I haven't really bothered trying. In one case, I was serializing structures and sending them to various programs on various computers using UDP. The solution is really simple, but does take some organization. What I did was to create a dll (which is laughably simple in .NET), put the Serialize and Deserialize methods into that dll as public functions in a module, then I also added the types that would be shared between the programs (all the message structures, but you could do the same with the structures in your map). This isn't just necessary for the binary serialization, you would find it to be kind of convenient for what you are doing even if you weren't doing any serialization. After all, by creating such a dll and referencing the dll from both the program and the map editor, you have the same objects available in each. Otherwise, if you change the design of the object in one, you had better remember to change it in the other. By putting the common structures and classes into a dll, a change to the dll is seen by both projects. And then the problem with binary serialization goes away and the actual code is virtually what you already wrote for XMLSerialization except that it uses a binaryformatter instead of an XMLSerializer.
Of course, it also means that nobody can really write such a thing for you, though they might give you an example, but you barely need an example as you are so close already. Since the dll would be yours, you'd need to write it. If you haven't created one before, it might seem daunting, but you're already way beyond that point, since a dll would just be a new project of type Class Library, but is otherwise just like the other projects you've created.
My usual boring signature: Nothing
 
-
Jan 22nd, 2013, 04:20 PM
#12
Thread Starter
Lively Member
Re: Save and load a class
 Originally Posted by Shaggy Hiker
You're a whole lot closer than you give yourself credit for. There are some limitations to XML serialization, and this may be one of them, but check that first. An XML serialized file would work a bit more easily than a binary serialized file for what you are trying to do. The nice thing about an XML serialized file is that you can look to see whether it worked, and how it worked, and do so easily enough. Use either Wordpad or Notepad (one works well for this type of file, the other really does not, but I forget which it is) to open the file. XML has plenty of oddities in it, but even if you are not familiar with XML, it should look VERY familiar. In fact, it should show all of your data. However, it may not, because I seem to remember reading that XML serialization didn't work on arrays. I haven't used it, so I have no experience with it, but by opening the file you will probably be able to see whether or not all your data is there. Of course, if it IS all there, it would be very tedious to read, so you won't want to check everything. Basically, I would expect that either you would have barely anything, only one tile, or all of them. If you have all of them, then the problem lies with reading them back in. If you have one of the first two options, then XML serialization failed. You could start a different thread on that if you still wanted to pursue it. You are very close, as it stands, the only real question I have is whether or not XML serialization even works on arrays.
In any case, if you look at the binary serialization and compare it to what you already have, you will see that the two are quite similar. I wrapped things in an exception handler because you can never really trust files, but aside from that, the lines are really quite similar. You have an XMLSerializer, I have a BinaryFormatter. I used a memorystream, you used a file stream, but a stream is a stream, and a filestream is the one you want to be using. I then added in a bit about taking the stream and converting the bytes to a string, but that was just so I could put the data into a My.Settings property. Since you aren't doing that, you don't need any such thing.
Unfortunately, that does leave a couple complications. The first one is utterly trivial, as you need to decorate all structures that you want to serialize with the <Serializable()> attribute. You'd just put that before Public. You can do some goofy stuff with that, but you don't need to. I'm not quite sure what that attribute does, but I suspect it may have to do with how the structure is arranged in memory. In any case, you can't serialize anything that lacks the attribute.
The other complication is as I noted: Binary serialization includes the application that serialized it, and you can't deserialize it with a different application. XMLSerialization, and that binary file thing from VB6 rather finessed the problem because there isn't any type information included in any of that. XMLSerialization is just plain text with a minimal amount of structuring, whereas the VB6 routine was just writing some bytes. An integer probably took four bytes in such a file, and there was no problem with your reading back those four, or reading back only two of them, or reading back the wrong four. If you didn't do the reading exactly the way the data was organized in the file, you'd get something back, but it would be junk. What this meant was that using either of those two types of files, your map editor and your main program didn't have to have the same types at all. Most likely, you would copy the types from one to the other, so they both would have the same, but there would be nothing enforcing that other than your own whim (XML serialization would enforce it to some extent, but only very lightly, and you could circumvent that easily). In the map editor, you could name the structures something different, or the properties, or have fewer properties, or have them be different types (with some limitations). They would be the same only by chance.
Binary serialization doesn't allow that. If you serialize an array of MapRec, then any program that deserializes it has to have access to the MapRec type. It's not enough to just have a type called MapRec in the application, nor is it enough to have the right properties in that type. Instead, the program that deserializes the object must have the same object that was serialized, and therefore it must be the same Assembly. That means that you can't have one program serialize and a different program be able to do anything with that file. I haven't found a way around this, but then again, I haven't really bothered trying. In one case, I was serializing structures and sending them to various programs on various computers using UDP. The solution is really simple, but does take some organization. What I did was to create a dll (which is laughably simple in .NET), put the Serialize and Deserialize methods into that dll as public functions in a module, then I also added the types that would be shared between the programs (all the message structures, but you could do the same with the structures in your map). This isn't just necessary for the binary serialization, you would find it to be kind of convenient for what you are doing even if you weren't doing any serialization. After all, by creating such a dll and referencing the dll from both the program and the map editor, you have the same objects available in each. Otherwise, if you change the design of the object in one, you had better remember to change it in the other. By putting the common structures and classes into a dll, a change to the dll is seen by both projects. And then the problem with binary serialization goes away and the actual code is virtually what you already wrote for XMLSerialization except that it uses a binaryformatter instead of an XMLSerializer.
Of course, it also means that nobody can really write such a thing for you, though they might give you an example, but you barely need an example as you are so close already. Since the dll would be yours, you'd need to write it. If you haven't created one before, it might seem daunting, but you're already way beyond that point, since a dll would just be a new project of type Class Library, but is otherwise just like the other projects you've created.
But I wonder, how do everyone make a map editor then? I mean, each map editor should use 2D-arrays because you have a X and a Y
-
Jan 22nd, 2013, 04:26 PM
#13
Re: Save and load a class
My map editor uses the technique I described: The map elements and the serialization routines are all found in a class library project that is referenced by the map editor and the main program.
Oddly, I didn't use a 2D array, either, though I agree with you that most would. For a reason that I have now forgotten, I used a 1D array. All 2D arrays are really 1D arrays in memory, anyways. You first have all the elements of row 0, then all the elements of row 1, and so forth. In memory, they are just laid out in sequence like a 1D array. To access element (x,y), you get element ((y * rowsize) + x). The compiler does all that for you in a 2D array.
I have the code for the serializer I used on a different computer, but I'm not sure that it would help anyways. After all, the serialization code would be the same, but the map elements certainly wouldn't be.
My usual boring signature: Nothing
 
-
Jan 22nd, 2013, 04:30 PM
#14
Thread Starter
Lively Member
Re: Save and load a class
hmm.. interesting.. Indeed it is possible to use 1D arrays and just count the total tiles of the map by MaxX * MaxY. So it could be easily saved in an xml file
-
Jan 22nd, 2013, 06:11 PM
#15
Re: Save and load a class
Yeah, it is possible....but having done it, I'm not so sure that it's a good idea. Referencing a single element in a 2D array is pretty simple: X and Y. Referencing a single element in a 2D array mapped to a 1D array takes an equation: (Y * width) + X. Even though I created it in a class where I could write the method once and it would work, I found that I was always doing some odd things. For instance, I might shift some elements up and left, at which point I'd be trying to figure out how that changed everything. It worked, but I'm not sure it was in any way easier than just using a 2D array.
My usual boring signature: Nothing
 
-
Jan 23rd, 2013, 02:44 AM
#16
Thread Starter
Lively Member
Re: Save and load a class
 Originally Posted by Shaggy Hiker
Yeah, it is possible....but having done it, I'm not so sure that it's a good idea. Referencing a single element in a 2D array is pretty simple: X and Y. Referencing a single element in a 2D array mapped to a 1D array takes an equation: (Y * width) + X. Even though I created it in a class where I could write the method once and it would work, I found that I was always doing some odd things. For instance, I might shift some elements up and left, at which point I'd be trying to figure out how that changed everything. It worked, but I'm not sure it was in any way easier than just using a 2D array.
well it could be easy if you use some functions for it. I might give this a try
Code:
Public Function GetTile(Byval MaxMapX as integer, Byval X as integer, Byval Y as integer) As Integer
Return Math.Floor(width * y + x)
End function
the only problem will be how to get the specific X and Y back what the tile is - I cant figure out what the calculation will be
Code:
Public Function GetX(Byval Tile as integer) As Integer
Return
End Function
Code:
Public Function GetY(Byval Tile as integer) As Integer
Return
End Function
-
Jan 23rd, 2013, 10:30 AM
#17
Re: Save and load a class
I would suggest that it be one method:
Code:
Public Function GetPoint(Tile As integer) As Point 'Found in System.Drawing if this is not defined
Return New Point(Tile Mod width, Tile \ width)
End Function
My usual boring signature: Nothing
 
-
Jan 25th, 2013, 02:25 PM
#18
Thread Starter
Lively Member
Re: Save and load a class
 Originally Posted by Shaggy Hiker
I would suggest that it be one method:
Code:
Public Function GetPoint(Tile As integer) As Point 'Found in System.Drawing if this is not defined
Return New Point(Tile Mod width, Tile \ width)
End Function
thanks, amazing! I'll look what I can do with my map editor now
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|