November 28, 2020, 10:52:54 AM

Author Topic: [bmx] Clone Objects by Azathoth [ 1+ years ago ]  (Read 1431 times)

Offline BlitzBot

  • Jr. Member
  • **
  • Posts: 1
[bmx] Clone Objects by Azathoth [ 1+ years ago ]
« on: June 29, 2017, 12:28:43 AM »
Title : Clone Objects
Author : Azathoth
Posted : 1+ years ago

Description : 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.

Code :
Code: BlitzMax
  1. ' Clones an object and returns the clone.
  2. ' Any fields that references an object only gets the reference copied unless MetaData contains {Clone}
  3. ' which then a copy is also made of the object referenced.
  4. ' {NoClone} prevents the field being copied.
  5. Function CloneObject:Object(obj:Object)
  6.         Local cobj:Object
  8.         If obj=Null Then Return Null
  10.         Local objId:TTypeId=TTypeId.ForObject(obj)
  12.         If objId.ExtendsType(StringTypeId)
  13.                 Return String(obj)
  14.         EndIf
  16.         If objId.ExtendsType(ArrayTypeId)
  17.                 If objId.ArrayLength(obj)>0
  18.                         cobj=objId.NewArray(objId.ArrayLength(obj))
  20.                         If cobj
  21.                                 For Local i=0 Until objId.ArrayLength(obj)
  22.                                         If objId.ElementType().ExtendsType(ArrayTypeId) Or objId.ElementType().ExtendsType(StringTypeId) ..
  23.                                                 Or objId.ElementType().ExtendsType(ObjectTypeId)
  24.                                                 objId.SetArrayElement(cobj,i,CloneObject(objId.GetArrayElement(obj,i)))
  25.                                         Else
  26.                                                 objId.SetArrayElement(cobj,i,objId.GetArrayElement(obj,i))
  27.                                         EndIf
  28.                                 Next
  29.                         EndIf
  30.                 EndIf
  32.                 Return cobj
  33.         EndIf
  35.         cobj=New obj
  37.         For Local fld:TField=EachIn objId.EnumFields()
  38.                 Local fldId:TTypeId=fld.TypeId()
  40.                 If fld.Get(obj)<>Null And fld.MetaData("NoClone")=Null
  41.                         If Not fld.MetaData("Clone")=Null
  42.                                 fld.Set(cobj,CloneObject(fld.Get(obj)))
  43.                         Else
  44.                                 fld.Set(cobj,fld.Get(obj))
  45.                         EndIf
  46.                 EndIf
  47.         Next
  49.         Return cobj
  51. EndFunction

Comments :

altitudems(Posted 1+ years ago)

 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.

GW(Posted 1+ years ago)

 Why would you make clones of particles each frame?

Azathoth(Posted 1+ years ago)

 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.

Hezkore(Posted 1+ years ago)

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

Derron(Posted 1+ years ago)

 I extended that function some time ago and it contains code for working with arrays<a href="" target="_blank">[/url]If this still does not work as expected: post the object to get copied, and explain, which things do not work as expected.byeRon

Azathoth(Posted 1+ years ago)

 Without much more information I don't know what the problem is.This works
Code: [Select]

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

For Local i=0 Until a.length


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


SimplePortal 2.3.6 © 2008-2014, SimplePortal