1.18 pointers

BlitzMax Forums/BlitzMax Beginners Area/1.18 pointers

anawiki(Posted 2006) [#1]
So I want to upgrade my code to BMX 1.18, but can't work around this:

Type ...
Field img:TImage[24], img2:TImage[24]

method loadImg(imgptr:TImage Ptr)
imgprt[0] = loadimage("...")
...

method blah()
loadImg(img)
loadImg(img2)
...

thanks for help
Roman


Dreamora(Posted 2006) [#2]
BM Objects can't be casted to pointers anymore. As Ptr are only for outside communcation, where your objects can't go.

For inside communication you can go the Byte Ptr way as well but it is not the adviceable way ... it breaks the ideas behind the managed environment.
There is nearly always a way around the usage of pointers which does not really need much exchange.

In your case its:

method loadImg(img:TImage[])
...


H&K(Posted 2006) [#3]
If I wanted an instance (e.g. A Tank) of an object (e.g. TGameObject) to contain a pointer to an extended TPixmap (ETPixmap) instance associated with it.
I would need a pointer to Type ETPixmap wouldn’t I?
If not, would that mean that each TGamePiece needs to contain its own pixmap?

I.e. I want each instance of TGameObject to Point to its Graphic instance, not contain it.


Who was John Galt?(Posted 2006) [#4]
a:ETPixmap=new ETPixmap
b:ETPixmap=a

Now a and b point to the same thing. All types are essentially a pointer to a struct.


H&K(Posted 2006) [#5]
So (for example)

Field A:ETPixmap, A would just be created as a pointer to a ETPixmap?

b:int = A:int Creates a new Int Object, But B:ETPixmap = A:ETPixmap doesnt create a new ETPixmap?


tonyg(Posted 2006) [#6]
That's right.
B:ETPixmap = new ETPixmap
would create a new pixmap object while...
A:ETPixmap=loadpixmap("blah.png")
B:ETPixmap = a
will create 2 pointers to the same 'Blah.png' pixmap.


H&K(Posted 2006) [#7]
But surly ETPixmap:New() (UnOverridden) is called on creation of any ETPixmap?
Does this mean that B:ETPixmap = a , does Create a new ETPixmap, which is then Gcolleceted 'cos its unrefferenced?


tonyg(Posted 2006) [#8]
Graphics 800,600
Local a:tpixmap = LoadPixmap("max.png")
local b:tpixmap = a
DrawPixmap b,100,100
Flip
WaitKey()

When variables a and b are out of scope the pixmap will be gcollected.
<edit>
Using a:tpixmap=new tpixmap probably isn't a good example with tpixmap as it will be created without surface info.


H&K(Posted 2006) [#9]
Thats not intuitive though is it?

If I use the copy allocator (=) I would assume to expect a copy to be created.

Why is it not

Local a:tpixmap ptr = *LoadPixmap("max.png")
local b:tpixmap Ptr = a

I am a bit miffed that Ive just spent Two hours trying to do what it does by default :(


tonyg(Posted 2006) [#10]
Because A and B are variable links (pointers) to the object
already.


H&K(Posted 2006) [#11]
I know that NOW.

It just doesnt seem right. I now know that I need

b:Tpixmap = CopyPixmap:TPixmap( a )

But wouldn't
b:TPixmap = a:TPixMap [same as b:Tpixmap = CopyPixmap:TPixmap( a )]
and
b:TPixmap ptr = a:TPixmap Ptr [To copy pointers]
be more intuitive?

I realise its way to late in Blitzmax Devolopment to change it


Dreamora(Posted 2006) [#12]
It is a very intuitive way:

Objects can NEVER be stored by Value in BlitzMax.
Everytime you do something like a:TPixmap or the like, this is already a reference (managed pointer) to a TPixmap object.

Thus the = will set the reference to the same object (and do some internal stuff needed for the garbage collector).

If you want to do a b = a with a copy of the actual object a, you will have to write your own clone method to do so, that returns a copy.

Pointers are unmanaged reference and because of that reason not adviceable within BM (you will have to manually memfree ANYTHING assigned to Byte Ptr from extern or Cstring!) and there is no real reason to do so (beside a few exceptions where possible work arounds exist).

BM is not a managed environment for some funny reason ;-) It makes many many things easier (like assigning a wrong type will result in compile errors as the interfaces do not match and the like)


H&K(Posted 2006) [#13]
You say its intuitive, BUT I think of INT as an object, which means we have two different rules for Objects
a = b (if a & b are Ints)
is different to
A = B (Where A & B are TPixmaps)


tonyg(Posted 2006) [#14]
Not sure what you want people to say. I find it intuitve but I can also see why you'd be frustrated if you hadn't realised.
Maybe the doc should say 'stores a link to the instance' but...
a) the doc isn't the strongest part of Bmax
b) there are the tutorials which make it clearer.
c) I haven't seen many other people querying it.
<edit>
P.S. I don't think of an int as an object though which, rightly or wrongly, might explain why a:int=b:int and a:TPixmap=B:Tpixmap both seem logical to me.


Dreamora(Posted 2006) [#15]
Numerics are the only exceptions to the whole thing, which is for the simple reason that numerics are NO objects but just values (you can't use them on commands wanting objects as well. You are forced to send it as a string).
thats most likely for pure speed reason.


H&K(Posted 2006) [#16]
a:int=b:int and a:TPixmap=B:TPixmap are logical to me as well. Just that I think that they should do the same thing.

I accept that they dont. I just think that system Types should behave the same as User Types.
(I still think its a copout not being able to extend system types)


Dreamora(Posted 2006) [#17]
System types behave the same as user types.

The problem is :int, :double :float :short :byte :long are not types. This are values.

Everything else like String, TBank, TList, TImage, TPixmap etc etc are handled exactly the same as user types.

I agree that this is not very consistent. But I'm aware as well that typed numerics would have quite an impact on mathematical operations (which are indeed extremely fast as the are done through C compiler code). It isn't an easy task to implement typed numerics that are usable for the amount of Int and Float operations that normally happen in 2D and 3D games ie that have about the same speed as direct C numerics.


H&K(Posted 2006) [#18]
The problem is :int, :double :float :short :byte :long are not types. This are values.



This is from the top of the types page

"Types
All constants, variables, functions and expressions have an associated type. BlitzMax supports the following types:"

Where it then goes on to list byte short int etc.

The are types, so stop saying they are numbers.

Not sure what you want people to say


I dont want you to say anything, I just wanted to point out that there is a difference bettween the two type of types
AND hope Dreamora can see the difference between easy to learn and intuitive

The Current system of pointers etc is intuitive to YOU cos youve already learnt it. It is a two rule system, one for one lot of types and one for the other


Dreamora(Posted 2006) [#19]
The docs are a thing that is often not of many uses.
In this case it extremely bad wording.

Type in this case only refers to the fact, that you can create a variable of this "type".

Numerics are no objects but values only (try it by giving a number to something that wants something of :object like TList.addlast if you trust the docs more than me and others here). The only possibility to get numerics into a TList is make a string out of it and reparse it to an int afterwards ... or like other do, create a Int wrapper object to use it with object based functions.
Another way to proof that is: Create a function that accepts a numeric value and try to modify it. It won't change outside. But it will if you use a true objects. To have this behavior you need to cast it to a reference first (by using variable:int VAR )


This should clearly be stated in the documentation ... but it is one of the significant flaws in the docs at the moment.
Sorry if this made problems to you.


H&K(Posted 2006) [#20]
Dreamora this is a result of Making the two types different. Saying "Look I can only do this with these", doent get away from the fact that they should be the same.

And I should be able to extend these types. I cannot do this because they are handled differently internaly. Not (as you seem to imply) because they are in essence different


H&K(Posted 2006) [#21]
Deleted


Dreamora(Posted 2006) [#22]
They are in essence different.

numerics are not extended from Object, BMs core object from which each other existing object is extended. Only types extended from BBObject ie :Object in BM are true objects ... sad but true :-(


They base on a deeper and indepent structure optimized for fast calculation instead OO. This deeper structure fully depends on the C / C++ generated code for maths, which on its own is highly optimized.

I agree that this is quite bad and not really desirable and unlikely in an OO language that seems to use modern OO design rules in all other aspects.
Seems like this is one of the heritages of BMs C/C++ binding in the background as they are as crap in this situation.

Perhaps this will change at some point, I would really like to see that happen ...

(For a more indepth explanation: All "true" objects base on BBObject, which implements the needed core functionality like the reference counter and needed core methods like .ToString. The numerics exist on this level as well as BBDouble and the like. But these types do not inherit BBObject ... And simply let them inherit would not solve the problem as you would need to write the whole operator handling etc as well ... I don't think this will work without altering the compiler as well)


H&K(Posted 2006) [#23]
Arrays?

When I pass an array, its always a pointer to the array isn't it?

so In NeHe Tut6 (for example)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, TexWidth, TexHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, Checkimage)
(Checkimage is Global Checkimage:Byte[256,256,4])

I am definately sending a pointer to Checkimage?