: StorageDemo Reloaded :
: XML I/O :
[Ok, I click Start Debugging(F5) and suddenly am 5000 years in the future. I have no idea if there is a name for the portal I had just gone through. Hopefully there is, so I can find my way back. My brain is still sizzling, and so I write.]
Seriously, the long and short of it is, in searching for a way to load and save files using the XMLSerializer on the Xbox 360, I have found that there are always more questions than answers out there. I set to some best guess ideas and followed the gist of what others have expressed either in passing or with a more directed focus.
This list is the short of it, really, a short list of a, more than likely an exceedingly, long list.
This has, Download StorageDemo_Sample.zip, to get you started. In the MSDN Library, click on "Other Versions" to get to the XNA Game Studio 4.0 documentation.
- Saving Data to a Save Game File.
- What Is Storage?
- Getting a StorageDevice Asynchronously.
- Using an AsyncCallback Delegate to End an Asynchronous Operation.
- Reading and Writing Data Files.
- Pumping the Guide.
- The State of Things.
and of course a Bing/Google search using the phrase ... The Three Pillars of Object-Oriented Programming.
"... Get On With It! ...". Right then.
I ran the Win PC project solution of StorageDemo and watched the folder contents change, being able to open and view them in ...'My Documents\SavedGames\StorageDemo'... folder. Some how I got the Xbox 360 Copy of StorageDemo to load and run on the Xbox 360. It was one of those, work till exhaustion then wake up and say, "I guess it did work.", moments. So at least it loaded onto the console. But I couldn't view the contents of the savegame.sav files on the console. From the sound of the disk of the console when either the 'A' or 'B' button were pressed, I had to assume that the files were being written to the disk. This didn't change the fact that even if the files were written, the contents would not still be the same as the initialized values.
I needed to change a value and the most direct way would be to use the ShowKeyboard set. After allot of reading and "Does this work?" attempts I got the Keyboard UI to return a string value back to "data", an instance of SaveGameData, and change the PlayerName. I still didn't know if the saved game data was actually saved. I didn't know how to load it back into the game. Yup, more reading and "Sorry, that's not a technically valid construct." malaise. I decided that the best way to view the instance of SaveGameData was to have its members drawn .ToString() in Draw(GameTime gameTime) to the screen. I had that set of data but it still needed to be passed through "void GetDevice(IAsyncResult result)" and "if ((GameSaveRequested) && (result.IsCompleted))" in protected override void Update(GameTime gameTime), to be saved and loaded. This last bit reminded me of an old MS saying, "Let go and let Com+.", whatever that means. I had changed the struct to a class, commented out all of the Do...(whatevers) and left only DoSaveGame(device); DoLoadGame(device); in the Update and DoLoadGame(device); in GetDevice. At this point I was in a wing and a prayer phase, so somehow I connected "HData = new HostRequest(data);" from inside GetDevice. It had already been declared in void Initialize() along with result = null; and data = new SaveGameData();.
This last part is what brings about that portal I spoke of earlier.
I can run StorageDemo on the Xbox 360. The 'A' button saves, the 'B' button loads and the "Start" button brings up the keyboard UI. I have two blocks of code in the Draw method. One to draw the "data" instance and the other draws the "HData.IOData" instance, both of the class SaveGameData. From all that I can gather they are seemingly identical but data is directly manipulated while HData.IOData is perpetually updated, not through the Update method but through HData = new HostRequest(data); and that instance is only called in initialize or when DoLoadGame is called by GetDevice where from there its connection can be reinstantiated. Beyond that all connectivity disappears. All I can say is that it reminds me of something like adding a GameComponent to the "this.Components.Add(Item);" and then just letting that component run from base.Do(what you do so well);. It's a mystery to me.
So like any good programmer I thought, if it isn't broke and it's still doing something, maybe this won't break it either. I added a TimeSpan to the SaveGameData to see how that would play out, and yes, HData.IOData follows data in step. The draws of the two class instances to the screen are synchronized, at least visually at 0.0166667th of a second. Maybe there is a thread there, I have no idea what a thread actually is, clueless. Be that as it may, when I press 'A' there is a brief halt, where the game hiccups so I'd guess that that means there has been a write to the disk. The two TimeSpan instances of the public TimeSpan PlayerTimeSpan = new TimeSpan; "(method/property)?" are not saved as is. I don't know why. So I save them singularly in their string format.
I exit the game, exit XNA Game Studio Connect and find StorageDemo in games, My Games. I run StorageDemo, press the Start button and the keyboard pops up. I input a different name and select done. "data" and thusly "HData.IOData" have the new name drawn to the screen. The two timers continued to tick away underneath the keyboard UI, so the thread(?) was not impeded by the keyboard. If that's a good thing or a bad thing, I don't know. So anyway, the PlayerName has been updated from the keyboard UI input. Pressing the 'A' button produces that, "Time Gash", (An idea from the game Cosmic Encounters where all game time is stopped and hoarded by one player.), where the TimeSpan counters halt then continue in data but not HData.IOData which has stopped. During the save operation, the connection to HData.IOData was lost. Going to the Start button and the resultant UI, I change the PlayerName again. Only the data instance is updated, HData.IOData is unreceptive. Pressing Back I return to the Xbox 360 interface. Then going back to Play Now, from StorageDemo, and pressing the 'B' button, the previously saved PlayerName is loaded into SaveGameData data instance and is also updated in HData.IOData, where both continue to run concurrently.
Hmmm, It works, still I don't get it.
But there is more to get, and much to refine. I think I'm back, although tired. And on that note, enough stated, to this first research intro, off you go.