English Amiga Board

English Amiga Board (http://eab.abime.net/index.php)
-   Coders. Blitz Basic (http://eab.abime.net/forumdisplay.php?f=126)
-   -   Blitz2: Copy newtypes? (http://eab.abime.net/showthread.php?t=77553)

idrougge 22 March 2015 17:11

Blitz2: Copy newtypes?
 
It's my understanding that one cannot simply assign one newtype to another, as you would with primitive variables. In other words, x=y would work if x and y are bytes, quicks, strings or words, but not if x and y are newtypes.

How would you go about copying one newtype to another, or am I mistaken?

Cylon 22 March 2015 21:50

Code:

newtype.foo
  a.w
  b.w
  c.w
end newtype

deftype.foo  tsrc, tdest

copymem_ &tsrc.foo,&tdest.foo,SizeOf.foo

Like that.

Beware of strings!
a d.s inside a newtype is just a pointer, so the address (and length) of the string is provided, not the string itself!
Instead, you could use a char array , e.g.
d.b[32].

Make it a nice Statement with proper address checks and so on.

idrougge 23 March 2015 03:07

Thanks, I solved it using some inline assembler, but it's nice to see that there is a system call for doing it as well. And as usual, Blitz's online help is of no help – according to it, CopyMem_ takes arguments in parentheses. Your example is correct – no parens.

I was hoping there was a simpler way than actually copying memory, though.

Cylon 26 March 2015 23:04

Quote:

Originally Posted by idrougge (Post 1011194)
Thanks, I solved it using some inline assembler, but it's nice to see that there is a system call for doing it as well. And as usual, Blitz's online help is of no help – according to it, CopyMem_ takes arguments in parentheses. Your example is correct – no parens.

I was hoping there was a simpler way than actually copying memory, though.

CopyMem_ is a systemcall. Please make sure you add proper checks if you going to use it.

The solution depends on what you want:
Do you really want to COPY the type? If not, you could (but must not!;)) try to bend a pointer temporarily to the src address:

Code:

Newtype.foo
  a.w
  b.w
  c.w
End Newtype

Deftype.foo  tsrc

tsrc\a=10,20,30      ;put in some values

*tdst.foo = tsrc      ;"clone" the struct by taking over the address

if *tdst
  NPrint *tdst        ;should be = &tsrc

  NPrint *tdst\a
  NPrint *tdst\b
  NPrint *tdst\c
;
*tdst=0              ;make sure we are not trying to free that later (GURU)
endif

MouseWait
End


idrougge 27 March 2015 01:11

Quote:

Originally Posted by Cylon (Post 1011982)
CopyMem_ is a systemcall. Please make sure you add proper checks if you going to use it.

What checks?

Quote:

Originally Posted by Cylon (Post 1011982)
Do you really want to COPY the type?

Yes, in fact, I need to copy a whole list of that type.
Quote:

Originally Posted by Cylon (Post 1011982)
Code:

*tdst.foo = tsrc      ;"clone" the struct by taking over the address

Shouldn't this be:
Code:

*tdst.foo = &tsrc

Cylon 28 March 2015 01:37

Quote:

Originally Posted by idrougge (Post 1012006)
What checks?

Of course src>0, dest>0, size>0 and copymem_ succeed (res.l=copymem_()).
Quote:

Yes, in fact, I need to copy a whole list of that type.

Shouldn't this be:
Code:

*tdst.foo = &tsrc

Agree, but Blitz swallows the other one too. Pointers are bitches....

idrougge 28 March 2015 17:04

Hence why I've never come to grips with pointers in Blitz; they seem so ad-hoc.

On a related topic, is it possible to treat a pointer to a list as a list? I have a list consisting of a newtype containing some primitive variables as well as a pointer to an item in a list consisting of another newtype. In other words:

Newtype daughter
x.w, y.w, z.q
End Newtype

Newtype mother
a.w, b.w
*pntr.daughter
End Newtype

Dim List daughters.daughter(20)
AddItem daughters()
daughters()\x=3,4,9.6

Dim List mothers.mother(10)
AddItem mothers()
mothers()\a=1
mothers()\b=2
mothers()\*pntr=&daughters()

This works as far as mothers()\*pntr\y being 4, but is it possible to do a NextItem(mothers\*pntr) ?

Cylon 29 March 2015 00:27

Quote:

Originally Posted by idrougge (Post 1012263)
Hence why I've never come to grips with pointers in Blitz; they seem so ad-hoc.

On a related topic, is it possible to treat a pointer to a list as a list? I have a list consisting of a newtype containing some primitive variables as well as a pointer to an item in a list consisting of another newtype. In other words:

Newtype daughter
x.w, y.w, z.q
End Newtype

Newtype mother
a.w, b.w
*pntr.daughter
End Newtype

Dim List daughters.daughter(20)
AddItem daughters()
daughters()\x=3,4,9.6

Dim List mothers.mother(10)
AddItem mothers()
mothers()\a=1
mothers()\b=2
mothers()\*pntr=&daughters()

This works as far as mothers()\*pntr\y being 4, but is it possible to do a NextItem(mothers\*pntr) ?

Did you try? NextItem() needs a Blitz List object name as parameter, which you donot provide. There are 3rd party libs with extended/lowlevel List support, but why do all that afford?
I wouldn't do those kind of things. First, why using a pointer when you could use a .l as a solid address storage as well?
Why do you use a List of .daughters, instead of
Code:

Newtype mother
  a.w, b.w
  numchilds.b
  daughters.daughter[#maxchilds]
End Newtype

which is much simplier to handle and not as error-magnetic as your way? It depends on your specific situation, certainly. I don't need to know your specific goal, but try to think "inside the box" and not re-invent something in Blitz that might work in C++.
Anyway, you can still use execs linked list way, meaning adding nodes and so on, treating nodes as memory blocks of your own (newtype structs), but why bother? Find a simple way - this is my best hint.:)

idrougge 31 March 2015 18:00

Quote:

Originally Posted by Cylon (Post 1012323)
First, why using a pointer when you could use a .l as a solid address storage as well?

That's right, but if you use a pointer, you can at least access the fields in the item you're pointing at.

Quote:

Originally Posted by Cylon (Post 1012323)
Why do you use a List of .daughters, instead of
Code:

Newtype mother
  a.w, b.w
  numchilds.b
  daughters.daughter[#maxchilds]
End Newtype

which is much simplier to handle and not as error-magnetic as your way?

Well, the answer is the same as why I'd use a list for the mothers. Lists are dynamic, arrays are not. If it's possible to have a list of daughters for each mother, each mother can have one or a thousand daughters without the need to waste memory for a thousand daughters for each mother.

Quote:

Originally Posted by Cylon (Post 1012323)
It depends on your specific situation, certainly. I don't need to know your specific goal, but try to think "inside the box" and not re-invent something in Blitz that might work in C++.

Blitz already has lists, so I don't think it's too far fetched to have lists of lists as well.

My hacky solution is to have a global list of daughters, with each mother containing a pointer to its first daughter and the number of daughter in that list. It works as long as all related daughters come in sequence, which they do. A more safe approach would be to have a unique ID for each mother, and to store that for each daughter in the list.

Daedalus 15 July 2015 17:46

I know this is an old-ish thread, but just thought I'd add a couple of points for completeness...

Quote:

Originally Posted by idrougge (Post 1011194)
Thanks, I solved it using some inline assembler, but it's nice to see that there is a system call for doing it as well. And as usual, Blitz's online help is of no help – according to it, CopyMem_ takes arguments in parentheses. Your example is correct – no parens.

Actually, with system calls in Blitz the parenthesis are optional and are usually included. This makes the function call return a value so you can check for success. Leaving out the parenthesis works, but causes Blitz to discard the returned value so you've no way of checking if the call was successful or not. For the system calls, you need to check the autodocs for the call to see if the return value is relevant or useful, but in this case the Blitz docs - though sparse in places - are correct.

Quote:

I was hoping there was a simpler way than actually copying memory, though.
AmiBlitz has a CopyType command that pretty much does what you want, though I can't quite recall if it was added in AmiBlitz 2 or was in the original Blitz Basic. Give it a source variable, a destination variable and it does the rest. It will only work on the current list item though, but that can be useful for easily copying an item to or from the list, or a simple While...While End loop can be used to copy the entire list.


All times are GMT +2. The time now is 16:13.

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2018, vBulletin Solutions Inc.

Page generated in 0.05906 seconds with 11 queries