I hit a little stumbling block in my quest to implement object cloning in my game engine. My goal is to have a cloning system that I donβt need to maintain in a class by class, unless the class needs special treatment.
My game engine setup revolves around the Object2D base class, which contains some image data in the form of Texture2D. Well, the long story is that it has a DisplayObject that contains Sprite, which contains Texture2D. Naturally, other classes, for example. "Player", "Enemy", "Projectile", etc. Produced from the base class Object2D.
Unfortunately, I found that the XNA Texture2D class is not serializable. This makes sense, since we would not want to duplicate the texture data in memory all willingly.
This creates a dilemma for me. I used cloning methods to clone objects, but since it is not serializable, I can no longer do this. I tried just to mark Texture2D [NonSerializable], but this causes problems when trying to draw, since the texture of the clone is zero. I was unable to find any hidden trick that allows me to assign it after cloning (sort of like the onClone () method).
So I decided that I would do it. For objects that cannot be deeply cloned as a whole, I implement the "SpecialClone" interface, which allows me to specify the clone () method.
However, since a class that cannot be completely cloned as a whole is a base class, I will go back to where I started: writing the clone method for a class by class.
public static T clone<T>(T obj) { if (obj == null) return default(T); if (!typeof(T).IsSerializable) { if (obj is SpecialClone) { object obj2 = ((SpecialClone)obj).clone(); return (T)obj2; } else { throw new ArgumentException("Object type is not serializable.", "obj type: " + Type.GetTypeHandle(obj)); } } else { return deepClone(obj); } } public static T deepClone<T>(T obj) { if (obj == null) return default(T); if (typeof(T).IsSerializable) { try { BinaryFormatter bf = new BinaryFormatter(); MemoryStream ms = new MemoryStream(); bf.Serialize(ms, obj); ms.Seek(0, SeekOrigin.Begin); T obj2 = (T)bf.Deserialize(ms); ms.Dispose(); return obj2; } catch (Exception e) { Console.WriteLine(e); return default(T); } } else { Console.WriteLine(typeof(T) + " is not marked as serializable!"); return default(T); } }
I'm still not the best with C #, so I'm not sure if I am missing any trick I can use, or, if that is the case, I will have to deal with this problem. The main purpose of this cloning is for Object2D types, so it would be a real pain to write cloning methods for every new subclass I make.
Is there any way to avoid this?