type pointer workaround?

BlitzMax Forums/BlitzMax Beginners Area/type pointer workaround?

kimgar(Posted 2007) [#1]
hi,

i'm trying to implement ageia physX in my application using blitzmax/irrlicht/rubux. the first test are working very well, but i am pretty new to blitzmax and i am stuck now at some casting problem(i think) regarding setting a userdata struct to a physX body.
the code i'm trying to get to work:
Type TPXData
    Field data1:Int = 123
    Field data2:Int = 456
End Type
Local data:TPXData = New TPXData
pxBodySetBodyUserData(pxBody, data)

the problem is that
pxBodySetBodyUserData(pxBody, data)

expects data to be an int, so i thought i'd make an int pointer to my data type and pass that, but apparently such code does no longer work in the later versions of blitzMax.

i realize that the type pointer issue has been discussed before, and i am sorry to bring this up again, but i have failed to find a solution for my case in earlier posts, so i was hoping that someone could help me shed some light on this issue, maybe a workaround or some clever way to pull this off...

for what its worth, this is the code from physX sdk that i am trying to achieve in blitzmax:
struct MyData
{
    int shapeColor;
    bool dangerous;
};

NxShape * myShape = ...;
MyData * data = new MyData;
data->shapeColor = 3;
data->dangerous = true;

myShape->userData = data;

//then you can define:
bool isShapeDangerous(NxShape & s)
{
    return ((MyData *)s.userData)->dangerous;
}



Dreamora(Posted 2007) [#2]
handlefromobject
handletoobject

but be aware that those commands will have a serious performance impact.

you better find a way around that casting by storing the handle in the entity class you are using instead of dynamic casting it!


kimgar(Posted 2007) [#3]
ah great! thanks! i had a look in the docs for handlefromobject, and that sounds like just the thing i am looking for, but of course:

those commands will have a serious performance impact.


ouch, i don't like the sound of that...hmmm, forgive the newbieness, but i am a bit unclear on how to achieve the most efficient workaround.

i need the userdata to get some data from the object i have collided with, and the only output i can get from a collision body from physX is the physX body object itself, it's name and it's userdata.
all entities are currently stored in a list, i guess i could loop through the list until a matching body is found, but this also smells like performance impact, maybe create a map/array and give unique names/userdata number as a key/index is better? what would be best, or is there any more clever ways to handle this?


kimgar(Posted 2007) [#4]
hmmm, just to clarify and eliminate any syntax errors on my side; this code will never work, will it?
Local data:TPXData = New TPXData
Local dataPtr:Byte Ptr = Varptr(data)

Local rcv:Int = Int(dataPtr)
Print rcv 'prints mem address ok
Print TPXData Ptr(rcv).data1 'illegal pointer type!



Paposo(Posted 2007) [#5]
hello

The code:
TPXData Ptr(rcv)
Make a pointer to TPXData. Not TPXData

You must unreference this pointer for access member data.

This probabily is functional:
local tmp:TPXData PTR=TPXData PTR(rcv)
print tmp[0].data

Bye,
Paposo


kimgar(Posted 2007) [#6]
local tmp:TPXData PTR=TPXData PTR(rcv)

umm, Paposo you have lost me...this line still returns 'illegal pointer type' ?


Paposo(Posted 2007) [#7]
mmm
Sorry kimgar, you are right!

writting:

local tmp:TPXData ptr=TPXData ptr(varptr(data))

return same message

I not understand!!

I try:
Type TPXData
Field data1:Byte=100
Field data2:Byte=50
EndType

Local data:TPXData=New TPXData

Local dataPtr:Byte Ptr=Varptr(data)

For Local nn:Int=0 To 20
Print dataptr[nn]
Next

the values 100 and 50 not are in!!!!!!

Fail varptr in objects???


tonyg(Posted 2007) [#8]
Have you actually tried using Handlefromobject/handletoobject?
Perhaps
those commands will have a serious performance impact.

doesn't match your opinion on 'serious performance impact'. Maybe it is quick enough for your needs.
Personally, I would get it working and then worry about it later. Maybe the time it takes on this step can be saved somewhere else.
<edit> Done a quick test :

which suggests the performance impact is not too severe.


kimgar(Posted 2007) [#9]
touché, tonyG :)

my problem is that i easily get carried away when faced with issues like this.
i just can't leave it until it's solved or a 'can't be done' is confirmed, especially where speed issues are concerned...

your test is really appreciated, handleFromObject approximately doubles processing time, but increasing the loops to a million, it takes only 83ms, which really is acceptable...i guess i can move on now :)

...but still, it would be nice to know if object varptr can be done or not :)


tonyg(Posted 2007) [#10]

1.18 Release
************
...
The compiler no longer allows you to create a pointer to an object via VarPtr (this was always supposed to be the case, but somehow it got overlooked!). Therefore, 'Object Ptr' (or ' Ptr' etc) is no longer accepted. This is because there is not any safe way to write to such a pointer without massively confusing garbage collection/detection. It is still legal to convert an object reference to a 'Byte Ptr', but you should be aware the pointer will only be valid while the object remains 'in scope'.


so...
Type TPXData
Field data1:Byte=100
Field data2:Byte=50 
EndType

Local data:TPXData=New TPXData

Local dataPtr:Byte Ptr=Byte Ptr(data)

For Local nn:Int=0 To 20
Print dataptr[nn]
Next

but converting them back is a problem


kimgar(Posted 2007) [#11]
aaah, great find tonyG, it doesn't get much clearer than that.

so only bytes can be used, hmm, guess i can live with that, but the scope issue is a little worrying.

so in the end object varptr's sounds too fishy for me, handleFromObject must be a much safer bet.

thanks a lot for clearing that up tony!


Dreamora(Posted 2007) [#12]
Both has the same problem in the end:

If the BM object isn't there anymore and you try to access it, it will bomb.

So the only thing you need to take care of is that the delete method of your class TPXData cleans "itself" in the external module / library correctly.

Then it shouldn't be a problem.


Paposo(Posted 2007) [#13]
Hello.

Any workaround is the use of bank functions.
createBank()
pokeInt()
lockBank()
Call external function with bankBuf()
unlockBank()
peekInt()

Bye,
Paposo