Code archives/Miscellaneous/Clone Objects

This code has been declared by its author to be Public Domain code.

Download source code

Clone Objects by Azathoth2007
This function should be able to clone any Blitzmax object, by default it shallow copies to prevent infinite loops with cyclic references.
{Clone} in the metadata of a field will also clone the object being referenced, this is deep copying.
{NoClone} in the metadata of a field will prevent the copying of the value or reference.
' Clones an object and returns the clone.
' Any fields that references an object only gets the reference copied unless MetaData contains {Clone}
' which then a copy is also made of the object referenced.
' {NoClone} prevents the field being copied.
Function CloneObject:Object(obj:Object)
	Local cobj:Object
	
	If obj=Null Then Return Null
	
	Local objId:TTypeId=TTypeId.ForObject(obj)
	
	If objId.ExtendsType(StringTypeId)
		Return String(obj)
	EndIf
	
	If objId.ExtendsType(ArrayTypeId)
		If objId.ArrayLength(obj)>0
			cobj=objId.NewArray(objId.ArrayLength(obj))
			
			If cobj
				For Local i=0 Until objId.ArrayLength(obj)
					If objId.ElementType().ExtendsType(ArrayTypeId) Or objId.ElementType().ExtendsType(StringTypeId) ..
						Or objId.ElementType().ExtendsType(ObjectTypeId)
						objId.SetArrayElement(cobj,i,CloneObject(objId.GetArrayElement(obj,i)))
					Else
						objId.SetArrayElement(cobj,i,objId.GetArrayElement(obj,i))
					EndIf
				Next
			EndIf
		EndIf
		
		Return cobj
	EndIf
	
	cobj=New obj
	
	For Local fld:TField=EachIn objId.EnumFields()
		Local fldId:TTypeId=fld.TypeId()
		
		If fld.Get(obj)<>Null And fld.MetaData("NoClone")=Null
			If Not fld.MetaData("Clone")=Null
				fld.Set(cobj,CloneObject(fld.Get(obj)))
			Else
				fld.Set(cobj,fld.Get(obj))
			EndIf
		EndIf
	Next
	
	Return cobj
	
EndFunction

Comments

altitudems2008
Wow, very nice. Though my guess would be that one should avoid this kind of cloning for realtime. For example: Cloning 100's of particles each frame could be slow.


GW2008
Why would you make clones of particles each frame?


Azathoth2008
I made this as more for generic cloning and a way to teach myself about reflection. Reflection isn't that fast anyway and probably be something you'd use more in apps than games.
For speed you'd want to make your own clone method/function for the specific Type.


Hezkore2015
Nice, but it seems that arrays don't work correctly.


Derron2015
I extended that function some time ago and it contains code for working with arrays
https://github.com/GWRon/Dig/blob/master/base.util.helper.bmx

If this still does not work as expected: post the object to get copied, and explain, which things do not work as expected.


bye
Ron


Azathoth2015
Without much more information I don't know what the problem is.

This works
Strict

Global a:Int[10], b:Int[10]

For Local i=0 Until a.length
	a[i]=i
Next

b=Int[](CloneObject(a))

For Local i=0 Until b.length
	Print b[i]
Next



Code Archives Forum