Custom Types (Direct access)

Blitz3D Forums/Blitz3D Programming/Custom Types (Direct access)

prefim(Posted 2010) [#1]
Hi Guys,

I steered away from custom types for months (using dims etc). but I finally got my head around them and rewrote a huge chunk of my code using them. it works fine but I have one question (that I couldnt find a direct answer to in all the posts).

Right now a create new objects in the usual way. If I want to query them I have to do a

for X.X = each object
if.....
next

Is there a way to query it like a variable where I say (for my specific example I'm trying to find the x and y position of a particular objects target). I've added an ID number to each object so object 1's target might be object 3 and so on.

For body.body = Each body
For target.body= Each body
If body\target = target\ID
target_x=target\x
target_y=target\y
End If
Next
ship_x=body\x
ship_y=body\y
EndIf
Next

which is a little time consuming. but what I'd liek to do is something like:-

target_x=body\x (body\target)

like calling an array location.

possible (not like that I know) but at all?

Cheers,


Warner(Posted 2010) [#2]
You can make one of the fields a 'body'
type body
  field target.body
end type

b.body = new body
c.body = new body

c\target = b


Or you can make an array of 'bodies'
type body
  field x, y
end type

dim body_array.body(100)
body_array(0) = new body
body_array(1) = new body
body_array(2) = new body



_PJ_(Posted 2010) [#3]


You can make one of the fields a 'body'

type body
  field target.body
end type

b.body = new body
c.body = new body

c\target = b




I recommend this approach. Further, you don't even need the field to be an Instance of 'body' Type, but if you feel confident enough, you can just use the 'Handle' of the instance.

type body
 Field Target
 Field X,Y
end type

b.body = new body
c.body = new body

c\target = Handle(b.Body)


To retrieve the actual Instance from the handle, just use Object:
[code]
ThisInstance.Body=Object.Body(TargetHandle)

; Or rather:

ThisBody.Body=Object.Body(MyInstance\Target)


Sake906(Posted 2010) [#4]
"Object" and "Handle" (which are obscure, undocumented but highly useful commands) are what you need to directly save and retrieve a specific type handle without having to loop through all of them.

Malice already showed how, but here I can give my own bit of an example:


Type mytype
	Field A,B,C
End Type



Function Create_a_Mytype(A,B,C)
	
	Local this.mytype
	
	this.mytype=New mytype
	
	this\A=A
	this\B=B
	this\C=C
	
	
	Return Handle(this);  we tell the function to return the handle for this type, so we can store it somewhere for later use
	
End Function




Function Edit_ThisMyType(savedhandle,A,B,C)
	
	Local this.mytype
	
	If Object.mytype(savedhandle)<>Null
		
		this.mytype=Object.mytype(savedhandle) ;  type handle exists, so we can use it
		
		this\A=A
		this\B=B
		this\C=C  ; then we edit it
		
	Else
		
		RuntimeError "Type handle specified does not point to any existing one"
		
	EndIf
	
End Function



Last edited 2010


Warner(Posted 2010) [#5]
You can also directly specify the function's type:

You could use Object and Handle if you wanted for example to store your type in a Bank.
What could be interesting is to look what the value of "handle" is when creating types:


Last edited 2010


Zethrax(Posted 2010) [#6]
You can also create an array of type pointers, and use that to access your type list.

eg.
Type T_mytype
Field a#
Field b#
Field c#
End Type

Dim mytype_array.T_mytype( 100 )

Global G_mytype.T_mytype

; >>> Create type objects and add their pointers to the array here.

G_mytype = mytype_array( 50 )



_PJ_(Posted 2010) [#7]
Hey Bill, that's a good idea. I often find that it gets a little 'tedious' having to Object every Handle I pass to a function after I've just iterated theough the objecvts to obtain that handle. By using the array (Or maybe even, a Type of Type Handles? :D ) it keeps things much more organised!


Zethrax(Posted 2010) [#8]
I don't know why Mark didn't just allow the type pointers themselves to be accessed as an integer number - the way he did with entity handles. It would have made Object/Handle redundant, and everyone's life a hell of a lot simpler.

Sometimes compiler developers need to just back away from the hand-holding, and let the programmers using their compilers get on with their jobs without tripping over training wheels that they don't need.

Last edited 2010


Warner(Posted 2010) [#9]
You can pass Types directly to functions as well:



xtremegamr(Posted 2010) [#10]

I don't know why Mark didn't just allow the type pointers themselves to be accessed as an integer number - the way he did with entity handles. It would have made Object/Handle redundant, and everyone's life a hell of a lot simpler.



You can do this with the FastPointer userlib, like so:

Type foo
 Field anInteger
End Type

Bar.foo=new foo
pBar=TypePointer(Bar)


My favorite part about this feature is that you can treat the type pointer like a bank using the memory functions provided in the lib (MemoryPokeByte, MemoryPeekByte, etc.)


Yasha(Posted 2010) [#11]
I don't know why Mark didn't just allow the type pointers themselves to be accessed as an integer number - the way he did with entity handles. It would have made Object/Handle redundant, and everyone's life a hell of a lot simpler.


Object/Handle is type-safe: if you call Object with a Handle generated from an instance of another type, or a Handle generated from a now-deleted instance, it returns Null rather than a pointer to something inappropriate. Allowing arbitrary conversion from any pointer to an integer would lose this safety. An UnsafeObject/UnsafeHandle command would have been nice for performance, but nightmarish for less advanced users.

There's also the issue that in order for the Type List system to work, the variables used in your B3D code are actually double pointers (the first one is dereferenced implicitly when you pass the variable to a DLL or get the pointer via TypePointer, and points to the struct containing the First/Last/Deleted info). Your int is therefore either a pointer to the first struct, which is all very well but a bit annoying to use, or to the object itself, which causes problems if it was deleted, and doesn't give you any obvious way to actually get the "variable pointer" back (maybe it does, I haven't investigated this thoroughly).