How to save derived classes

Easy Save 2 has been replaced by Easy Save 3, so is no longer supported.
Locked
Lordinarius
Posts: 8
Joined: Tue Jun 14, 2016 2:30 pm

How to save derived classes

Post by Lordinarius »

Hello

I am trying to save derived classes but couldn't find a proper solution yet.

Base > Derived

I have a Base class list and generating this list on runtime randomly. So i don't know what derived class does it contain.

I found a temporary solution but it is a bad workaround i think. I am just giving id to every derived class and generating them while reading base class.
Is there any proper way to achieve this ?

Code: Select all

public override object Read(ES2Reader reader)
	{
		Basec data = new Basec();
		data.id = reader.Read<System.Int32>();
		switch (data.id) {
		case 1:
			data = new AdvancedOne ();
			break;
		case 2:
			data = new AdvancedTwo ();
			break;
		case 3:
			data = new AdvancedThree ();
			break;
		default:
			break;
		}
		Read(reader, data);
		return data;
	}

	public override void Read(ES2Reader reader, object c)
	{
		Basec data = (Basec)c;
		// Add your reader.Read calls here to read the data into the object.

		switch (data.id) {
		case 1:
			((AdvancedOne)c).advancedOneIntager = reader.Read<System.Int32>();
			((AdvancedOne)c).advancedOneString = reader.Read<System.String>();
			((AdvancedOne)c).baseIntagerOne = reader.Read<System.Int32>();
			((AdvancedOne)c).baseStringOne = reader.Read<System.String>();
			break;
		case 2:
			((AdvancedTwo)c).advancedTwoInt = reader.Read<System.Int32> ();
			((AdvancedTwo)c).baseIntagerOne = reader.Read<System.Int32>();
			((AdvancedTwo)c).baseStringOne = reader.Read<System.String>();
			break;
		case 3:
			((AdvancedThree)c).advancedThreeIntager = reader.Read<System.Int32>();
			((AdvancedThree)c).advancedTwoInt = reader.Read<System.Int32>();
			((AdvancedThree)c).baseIntagerOne = reader.Read<System.Int32>();
			((AdvancedThree)c).baseStringOne = reader.Read<System.String>();
			break;
		default:
			data.baseIntagerOne = reader.Read<System.Int32>();
			data.baseStringOne = reader.Read<System.String>();
		break;
		}
User avatar
Joel
Moodkie Staff
Posts: 4849
Joined: Wed Nov 07, 2012 10:32 pm

Re: How to save derived classes

Post by Joel »

Hi there,

There was actual a similar question asked recently here, and I suggested the same as you're doing at the moment.

The reason we don't automatically handle polymorphism is partly for the same reason that Unity's Editor serialiser doesn't support polymorphism: because both performance and format-size would take a hit, as we would have to store and marshal type data with each Collection item that we save.

Thankfully unlike Unity, you can just create an ES2Type to handle it manually as you have done.

All the best,
Joel
Joel @ Moodkie Interactive
Purchase Easy Save | Contact | Guides | Docs | Getting started
Lordinarius
Posts: 8
Joined: Tue Jun 14, 2016 2:30 pm

Re: How to save derived classes

Post by Lordinarius »

Thanks. At least, type depended control is better than giving id.
Lordinarius
Posts: 8
Joined: Tue Jun 14, 2016 2:30 pm

Re: How to save derived classes

Post by Lordinarius »

Hello again, i did some improvements with the code. Didn't try on mobile yet but it should work on it. You need parameterless constructor for each derived classes.

This is my ES2 Type for base class

Code: Select all

public override void Write(object obj, ES2Writer writer)
	{
		Basec data = (Basec)obj;
		Type type = data.GetType();
		writer.Write(type.AssemblyQualifiedName);
		data.Write (writer);

	}

	public override object Read(ES2Reader reader)
	{
		string st = reader.Read<string> ();
		Type type = Type.GetType(st);
		Basec data = Typedispatcher.Create (type);
		data.Read (reader);
		return data;
	}
and i have Read and Write virtual methods on my base class and on derived classes as well.

like that

Code: Select all

using UnityEngine;
using System.Collections;

[System.Serializable]
public class AdvancedOne : Basec {

	public int advancedOneIntager;
	public string advancedOneString;


	public AdvancedOne (int baseIntagerOne, string baseStringOne, int advancedOneIntager, string advancedOneString) : base (baseIntagerOne, baseStringOne)
	{
		id = 1;
		this.advancedOneIntager = advancedOneIntager;
		this.advancedOneString = advancedOneString;
	}
	public AdvancedOne ()
	{
		id = 1;
		this.advancedOneIntager = 0;
		this.advancedOneString = "advancedOneString";
	}
	public override void Write(ES2Writer writer)
	{
		// Add your writer.Write calls here.
		writer.Write(this.id);
		writer.Write(this.advancedOneIntager);
		writer.Write(this.advancedOneString);
		writer.Write(this.baseIntagerOne);
		writer.Write(this.baseStringOne);

	}

	public override void Read(ES2Reader reader)
	{
		// Add your reader.Read calls here to read the data into the object.
		this.id = reader.Read<System.Int32>();
		this.advancedOneIntager = reader.Read<System.Int32>();
		this.advancedOneString = reader.Read<System.String>();
		this.baseIntagerOne = reader.Read<System.Int32>();
		this.baseStringOne = reader.Read<System.String>();

	}
}
Here Typedispatcher.Create

Code: Select all

	public static Basec Create(Type ty)
	{
		Basec mtye = (Basec)Activator.CreateInstance (ty);
		return mtye;
	}
Locked