Serializable class
Monkey Forums/Monkey Programming/Serializable class
| ||
| It's first time when I actually need to make a serializable class. I searched the forums but I found just some references to Diddy framework. I would like to use it but I cannot find the download link for the last version :)) can anyone help me with that? |
| ||
| Google Code are dropping the download section very soon, so to get the latest version either use Hg or use the "zip" on the Google Code site: https://code.google.com/p/diddy/source/browse/ |
| ||
I have written a reflection class, maybe that can help you.
Strict
Import reflection
#REFLECTION_FILTER += "framekit.object"
Class ReflectionObject Abstract
Method ClassName:String() Property
CacheClassInfo()
Return SingleClassName(classInfo.Name)
End
Method SuperClassName:String() Property
CacheClassInfo()
Return SingleClassName(classInfo.SuperClass.Name)
End
Method InvokeMethod:Object(name:String, data:Object[] = [])
CacheClassInfo()
Local methods:= classInfo.GetMethods(False)
For Local i:Int = 0 Until methods.Length
Local m:MethodInfo = methods[i]
If m.Name = name
Return m.Invoke(Self, data)
End
Next
Return Null
End
Method SetField:Void(name:String, value:Object)
CacheClassInfo()
Local f:= classInfo.GetField(name, False)
If f
f.SetValue(Self, value)
End
End
Method FieldValue:Object(name:String)
CacheClassInfo()
Local f:= classInfo.GetField(name, False)
If f
Return f.GetValue(Self)
End
Return Null
End
Method FieldType:String(name:String)
CacheClassInfo()
Local f:= classInfo.GetField(name, False)
If f
Return SingleClassName(f.Type.Name)
End
Return ""
End
Method FieldNames:String[]()
CacheClassInfo()
Local fields:FieldInfo[] = classInfo.GetFields(False)
Local fieldNames:String[fields.Length]
For Local i:Int = 0 Until fields.Length
fieldNames[i] = fields[i].Name
End
Return fieldNames
End
Private
Method CacheClassInfo:Void()
If Not classInfo
classInfo = GetClass(Self)
End
End
Field classInfo:ClassInfo
End
'input: a string with dot limited class names, e.g: monkey.lang.Object
'returns: only the last class name after the dot, e.g: Object
Function SingleClassName:String(classSignature:String)
Local signature:String[] = classSignature.Split(".")
Local last:Int = signature.Length - 1
Return signature[last]
End
Obviously you need to extend ReflectionObject. |
| ||
| thanks, but now it's time for stupid questions. I am using Diddy framework. in the example I was you first serialize the object "tcSer", but when you desirializing it you are creating a new class tc2 but still using tcSer: Print "Deserializing" Local tc2:TestClass = TestClass(s.DeserializeObject(tcSer)) tcSer.Dispose() I want to use this to save/load my game data. after I save/serialize it and I quit the game I no longer have that tcSer, so how can I access the savefile in this case? |
| ||
| still need some help here. I am sure it's simple but i cant figure it out and it's frustrating. I have this class:
Class cGameLogic Implements ISerializable
Global numberOfLogicScenes:Int
Global logicScene:cLogicScene[]
Global numberOfLogicMinigames:Int
Global logicMinigame:cLogicScene[]
Global numberOfLogicFlags:Int
Global logicFlag:Int[]
Global numberOfLogicInventoryObjects:Int
Global logicInventoryObject:cLogicInventoryObject[]
Global invSlot:cInventorySlot[]
Global numberOfLogicObjects:Int
Global logicObject:cLogicObject[]
Global objectInHand:Int
Global isPlayingMinigame:Int
Global previousSceneId:Int
Method Serialize:Void(serializer:Serializer)
serializer.Write("numberOfLogicScenes", numberOfLogicScenes)
serializer.Write("numberOfLogicMinigames", numberOfLogicMinigames)
serializer.Write("numberOfLogicFlags", numberOfLogicFlags)
End
Method GetClassName:String()
Return "cGameLogic"
End
Method GetGenericNames:String[]()
Return []
End
'and here my class methods
cant figure it out how exactly to save the file:
If KeyHit(KEY_1)
Local saveSer:XMLElement = s.SerializeObject("savegame", cGlobals.myGameLogic)
Print saveSer.ToString()
EndIf
I assume I need to write the saveSer to a file, right?? |
| ||
| The Diddy serialisation module was written before reflection was added to the language, and is very out of date. I would recommend using a solution like Shinkiro's until such time as I have time to rewrite the Diddy one. |
| ||
| I have no idea what reflection is {shame on me} and no clue how to use Shinkiro1's module :D |
| ||
| I do it the old-fashioned way where every object has a Serialise function which in turn calls Serialise functions for its 'child' objects. Ultimately there are serialisation functions for Int, Bool and String. Store a version number as well if objects might change and you want to be able to load old save files. |
| ||
| in this case I can just save to a txt file all my data like: from line 1 to 60 = inventory items from line 61 to 160 = scene status and so on.. and when I 'load' the game, i just read those variables, but I wanted to make it easier. in blitzmax was much funny |
| ||
| You can also use something like xml and not worry about line numbers. It was easier in BlitzMax? Could you explain what you mean. |
| ||
| @Shinkiro1: "It was easier in BlitzMax? Could you explain what you mean. " well, there is a very smart guy there Brucey (i think we are all using his work), who made a module: persistence. I simply save my class: Local pers:TPersist = New TPersist Local stream:TStream = WriteStream(fileName) pers.SerializeToStream(Globals.gameLogic, stream) stream.close() |