Store and load objects as a json file according to attributes you put on the members of the class
I use this in one of my projects which uses IronPython so this library takes in account IronPython objects, but as some effort is neccessary (see below)
to implement creation of objects with IronPython, this functionnality is disabled by default. If you want to enable it go into TimelineLoader and TimelineSaver
and uncomment the #define PYTHON
Other than that this same library should work out of the box provided your objects have the right attributes (especially CreateLoadIntance which is neccessary
if your object can't be created with an empty constructor that is public)
See each attributes in the Attributes folder to know what you can do with this system. Each Attribute has an example in the comments above the class. Here is an example anyway:
public class ExamplePoint
{
[SaveMe]
double x;
[SaveMe]
double y;
[SaveMe]
double z;
//since the empty constructor is private we need to create an instance manually
[CreateLoadInstance]
private static ExamplePoint Create(object parent, Type createThis)
{
//we know parent is going to be an ExampleMesh here but if you use this class in other places it could be any type
//that is host this object
//createThis is always going to be typeof(ExamplePoint) here because this class does not have child classes
return new ExamplePoint();
}
private ExamplePoint() { }
public ExamplePoint(double x, double y, double z)
{
this.x = x;
this.y = y;
this.z = z;
}
}
public class ExampleMesh
{
[SaveMe]
public List<int> triangles = new List<int>();
[SaveMe]
public List<ExamplePoint> points = new List<ExamplePoint>();
string secretThing = "I'm a secret!";
bool tmpVar = false;
[OnDoneLoading]
private void DoneLoading()
{
Console.WriteLine("object has been loaded from json!");
}
}
ExampleMesh mesh = new ExampleMesh();
mesh.points.AddRange(new ExamplePoint[]
{
new ExamplePoint(0, 0, 0),
new ExamplePoint(1, 0, 0),
new ExamplePoint(1, 1, 1),
new ExamplePoint(0, 1, 1)
});
mesh.triangles.AddRange(new int[]
{
0, 1, 2,
0, 3, 2
});
TimelineSaver saver = new TimelineSaver(mesh);
saver.Save("exampleMesh.json");
ExampleMesh readMesh = (ExampleMesh)TimelineLoader.Load("exampleMesh.json");
Here is the json file generated by the above code:
{
"triangles": [
0,
1,
2,
0,
3,
2
],
"points": [
{
"x": 0.0,
"y": 0.0,
"z": 0.0,
"type": "Tools.Meshing.ExamplePoint, Tools, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
},
{
"x": 1.0,
"y": 0.0,
"z": 0.0,
"type": "Tools.Meshing.ExamplePoint, Tools, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
},
{
"x": 1.0,
"y": 1.0,
"z": 1.0,
"type": "Tools.Meshing.ExamplePoint, Tools, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
},
{
"x": 0.0,
"y": 1.0,
"z": 1.0,
"type": "Tools.Meshing.ExamplePoint, Tools, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
}
],
"type": "Tools.Meshing.ExampleMesh, Tools, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
}
As you can see only the members with [SaveMe]
have if you look at the console you can see object has been loaded from json!
You can also compare readMesh
with mesh
they will be identical.
Note: Any element that will be part of an array and have a reference to the object storing the array can implement the IHasHost interface. For example if you have :
class Holder{
List<Item> items;
}
class Item{
Holder parent;
}
the Item class can implement ISetParent and the SetParent method will be called uppon loading the items
list with the reference to the instance of Holder
Note 2: If you have a some objects that can't be created/read using the attribute system, you can implement ICreatableProvider and ISavableManager and provide an instance while loading/saving.
This is a module extracted from Water Motion my motion graphics software.