Type content copying

Blitz3D Forums/Blitz3D Programming/Type content copying

_33(Posted 2007) [#1]
Just to make sure I'm reading this correctly, and it could be a rookie question.
Type a
   Field b%
   Field c%
End Type

hah.a = New a
heh.a = New a

hah\b = 1
hah\c = 2

heh = hah

Print heh\b
Print heh\c

WaitKey()


Does this mean that assigning a typed content to another typed content really copies the integral data of say "hah" to "heh" from the example above?

If it does, it will save me a bunch of trouble.

EDIT: I've tried to integrate this logic in my project, but it doesn't seem to do as I tought. It might just copy the pointer in one typed variable into the other typed variable. If this doesn't work, then it means I have to enumerate the 50 something elements contained in my type as I copy them one by one... Also, it means that if I change my type, I'll have to make sure I also modify other parts of my code where I handle type content such a copying the whole type. :(


_33(Posted 2007) [#2]
Type a
   Field b%
   Field c%
End Type

hah.a = New a
heh.a = New a

hah\b = 1
hah\c = 2

heh = hah

Print "we seem to have copied the content of hah into heh!"
Print "hah\b :" + hah\b
Print "hah\c ;" + hah\c
Print "heh\b :" + heh\b
Print "heh\c ;" + heh\c
Print "Now, let's modify the content of heh,"
Print "and see what we find..."
heh\b = 3
heh\c = 4
Print "hah\b :" + hah\b
Print "hah\c ;" + hah\c
Print "heh\b :" + heh\b
Print "heh\c ;" + heh\c
Print "Oh noes! heh points to hah :("
WaitKey()


Very sad :(

Oh well, it seemed too good to be true.

Anyone have any tricks to copy a type content???

EDIT: I'll try to implement this --> http://www.blitzbasic.com/codearcs/codearcs.php?code=980
The only thing missing is to figure out the length of a type in bytes, otherwise I have to calculate it, and it' sfairly impossible with strings in there.


Stevie G(Posted 2007) [#3]
Your simply assigning the heh to be pointing to the hah type so logically both have the same values ... This code copies the contents of one to another ..

Type a
   Field b%
   Field c%
End Type

hah.a = New a
hah\b = 1
hah\c = 2

heh.a = CopyType( hah )

Print "we seem to have copied the content of hah into heh!"
Print "hah\b :" + hah\b
Print "hah\c ;" + hah\c
Print "heh\b :" + heh\b
Print "heh\c ;" + heh\c
Print "Now, let's modify the content of heh,"
Print "and see what we find..."
heh\b = 3
heh\c = 4
Print "hah\b :" + hah\b
Print "hah\c ;" + hah\c
Print "heh\b :" + heh\b
Print "heh\c ;" + heh\c
Print "Oh noes! heh points to hah

MouseWait


Function CopyType.a( Source.a )

	target.a = New a
	target\b = Source\b
	target\c = Source\c
	
	Return target
	
End Function



_33(Posted 2007) [#4]
Stevie G, you obviously didn't read the details of my posts. I want to copy the Type (may there be target\b and target\c, or target\b through target\z) in a singular way, without enumerating all the content of the type. I tought I properly explained this.

Looking at the link from my second post, you will see that I found something close to the answer I was looking for.

What I am doing is the following............
kernel32.DECLS:
RtlMoveMemory3%(Destination*, Source*, Length) : "RtlMoveMemory"

and then something like this in my program:
RtlMoveMemory3(dest_type, source_type, type_length)

This will copy the content of one occurence of a type into the dest_type, which is another occurence of the type. type_length is the length in bytes of the type (source and dest are the same) that I calculate by hand. If the type contains 12 INTS, then my type_length will be 12 * 4 bytes.

Note: If your type has stuff like poo[32], poo[32] won't get copied over. Instead, it will copy a pointer to the 32 occurences of poo, which is an int. Same if you have a type in a type, or if you have a string$.


John Blackledge(Posted 2007) [#5]
This is actually really interesting, especially since I have reams of code involved in copying types, but mine are not Blitz but indexed arrays:
heh[1]\a
heh[1]\b$ etc

I would love to know a way to do a single line copy.


b32(Posted 2007) [#6]
I'm not sure if that is possible. A type doesn't return it's memory location. A bank, however, does. That is why you can use RtlMoveMemory on banks.
About the length of strings in bytes, you could use Len(a$) + 1. The extra +1 is for Chr$(0) that ends the line.


Dreamora(Posted 2007) [#7]
There is no copy possibility for type instances.

Either copy it manually or not copy it at all.


_33(Posted 2007) [#8]
b32, when you code in a DECLS, a line as follows:
RtlMoveMemory3%(Destination*, Source*, Length) : "RtlMoveMemory"

Destination* will use the address of the label that you put (with the asterisk), Source* is the same, and then the length which is an absolute value.

So in essence, this way you can use the RtlMoveMemory3 to do the dirty work for you. It works perfectly in my project. But you have to be especially careful of the length that you put in there as you can corrupt the memory easily.

John Blackledge, I have a trick for you: When you declare your type, move everything that can't be copied with RtlMoveMemory to the bottom of your type. This way you'll be able to RtlMoveMemory everything that is possible to copy in one pass, and then, and write the rest of the copy procedure for all the detail stuff. Make sure to properly calculate the length you are moving, and discard what can't be moved from your length. What I do, since I move ints using this method, is I count my type items that I am moving, and use that times 4 and put that as the length. If you have a way to debug your data, or maybe just put a STOP command right after your moves. Consult your type from there with the IDE debug mode and see if it properly moved your data.


b32(Posted 2007) [#9]
Heh .. it works ! That is nice to know.

As for the length .. I would suggest to avoid using Strings in your types. Maybe you could use strings with a fixed length. (ie. 255) However this would mean that you should write your own routines to handle them.
edit:
Or .. you could set them to a length of 255 before copying, then cut them off again after copying.


big10p(Posted 2007) [#10]
Surely strings are just stored as pointers within the type, and so string length shouldn't be an issue?!


_33(Posted 2007) [#11]
The problem is, if you copy your string pointer, then you'll have two type data storages that point to the same single string storage, which in essence means that you only copied the pointer, and not it's content. That is why I said; "put all those in the last bits of your type declaration" to avoid this particular problem.

But I have absolutely no magic solution for copying the strings and the tables that could be defined in types. I do all those one by one. But having RtlMoveMemory3 saved me about 120 lines of code ;) for two particular instances in my project. Not to mention that doing 60 assignments is much much slower than performing a single RtlMoveMemory3. So, I might use this more often.

And, since I often try to go to the edge, I've also put my hands on RtlCopyMemory (also known as MemCpy). But, sadly it is not possible to do a user call to RtlCopyMemory, from what I tried and from reading various posts on the subject. From what I read, RtlCopyMemory is even more speed efficient than RtlMoveMemory, oh well...


John Blackledge(Posted 2007) [#12]
_33 I understand what you're saying. It's like being back in the days of assembler or (heaven help us) C.

Yes, it was too much to hope that someone had a method of copying a variable+string array.

Never mind - I'll carry on as I was.