Function that returns a type

Blitz3D Forums/Blitz3D Programming/Function that returns a type

_33(Posted 2008) [#1]
Anyone ever managed to make a function that returned a type in Blitz3D? Just wondering if that is possible?


GfK(Posted 2008) [#2]
I haven't used Blitz3D for ages so I'm being a little vague here, but I *think* its done something like this:
Function myFunction.myType()
  Local m.myType ; = New myType???  (can't remember!)
  Return m
End Type

Type myType
  Field x%
  Field y%
End Type

In other words, you must declare the function as the type you want returned. I know that's how you do it if you want to return a string or float instead of the default Integer.


_33(Posted 2008) [#3]
Yea I tried the following, and it seems to work :)
Type coo
	Field a
	Field b
End Type

test.coo = New coo
test = jack(1,2)
Print test\a
Print test\b
WaitKey()
End

Function jack.coo (aa, bb)
	Local pff.coo = New coo
	pff\a = aa
	pff\b = bb
	Return pff
End Function


Thanks


GfK(Posted 2008) [#4]
:)


GIB3D(Posted 2008) [#5]
I do it somewhat like that, I don't see why you would put the Local part though

Mine.Typ = CreateType()

While Not KeyDown(1)
	
	UpdateType()
	UpdateWorld
	RenderWorld

	Flip
Wend
End

Type Typ
	Field model
End Type

Function CreateType.Typ()
	a.Typ = New Typ
		a\model = CreateCube()
	Return a
End Function

Function UpdateType()
	For a.Typ = Each Typ
		MoveEntity a\model,0,0,1
	Next
End Function



Warner(Posted 2008) [#6]
Local is assumed when a variable is created inside a function.


_33(Posted 2008) [#7]
But, I'm absolutely not convinced that the data in the "local" type will get deleted when returning from that function. Maybe I could be wrong on this, but I suspect this will create a memory hole. I'll have to do some testing on this logic.


Gabriel(Posted 2008) [#8]
But, I'm absolutely not convinced that the data in the "local" type will get deleted when returning from that function.

I should certainly hope not or the object you just return'ed will be invalid before you actually do anything with it. You've only created one type, you don't want it deleted immediately.


Dreamora(Posted 2008) [#9]
local is used on everything not declared as global. Everything else is "lazyness" :)

B3D does not have a BM like scope cleaning, especially it does not delete anything on its own. Remember _33, delete ;-)


GfK(Posted 2008) [#10]
I did state that I don't use Blitz3D any more. I use Blitzmax.

Blitzmax requires (in Strict mode at least) that all variables be declared before they can be used, hence the 'Local'.


Dreamora(Posted 2008) [#11]
as Ideal user you do it on Blitz3D as well to have its "strict" option active that checks for you against misstyped variable names.


_33(Posted 2008) [#12]
especially it does not delete anything on its own. Remember _33, delete ;-)

What are you trying to say exactly? Delete a Local type?


lo-tekk(Posted 2008) [#13]
Types are always global and will freed only with the delete command. I use the local statement only for the sake of IDEALs strict feature.


Ross C(Posted 2008) [#14]
Types are Global, but the custom variable isn't. <<< [EDITED]


"p.parcel" in side a function, will have no assignment outside a function

"global p.parcel" will mean the varaible p always will hold a type handle unless deleted.


_33(Posted 2008) [#15]
Ross C, so from my example code "pff\a" and "pff\b" will not exist outside the function ? If so, that example will not create some sort of memmory leak?

I'm thinking, the best way to test this is to try to delete all the occurences of the type after the call.


Stevie G(Posted 2008) [#16]
There will be no memory leak. The variable pff which references the instance will be lost outside the function. By creating a new coo instance you are effectively adding this to a global type list, regardless of whether it's inside or outside the function.

So, in your example you are actually creating 2 x instances, one outside the function and one inside. This is the correct way to do it ...

Type coo
	Field a
	Field b
End Type

test.coo = jack(1,2)
Print test\a
Print test\b
WaitKey()
End



_33(Posted 2008) [#17]
Thanks Stevie G, I knew there was something I had to consider when creating a Type inside a function like so. I loosely used the term "memory leak" to say that it's content that the programmer didn't think it would fall out of the logic.


PowerPC603(Posted 2008) [#18]
Code from above:
Type coo
	Field a
	Field b
End Type

test.coo = New coo
test = jack(1,2)
Print test\a
Print test\b
WaitKey()
End

Function jack.coo (aa, bb)
	Local pff.coo = New coo
	pff\a = aa
	pff\b = bb
	Return pff
End Function


In this Jack-function the variable pff is created locally, this means that if you want to access pff outside this function, it won't hold any value.
It also doesn't matter if you specifically declare it to be local, it's just for readability's sake.
If you see that line, then you know you aren't accessing a global variable, but you're creating a temporary variable that's needed only inside that function.
Also, if you use a variable name that doesn't exist yet, Blitz automatically creates it for you as a local one.
So, if you use
Local test% = 5

or
test% = 5

The result will be the same.
In both cases Blitz creates a local variable called test (integer-type) and stores the value 5 in it.


BUT, you return pff to the calling function (or the main program).
The newly created .coo object (or instance) is added to a global typelist and won't be deleted when you exit the function.
The memory-location of that instance is held in the variable pff, and when you exit the function, the .coo instance still exists (as you haven't specifically deleted it) and you return the memory-location to the calling function.
test.coo = jack(1,2)


This line creates a local (default) variable in the main program called "test" and will accept a reference (memory-location) to a .coo object.
You call the function Jack, which:
- creates a .coo object and store the memory-location of that object in a temporary local variable called "pff"
- sets some values in the fields of that new .coo object
- returns the memory-location to that new .coo object
- store the returned memory-location of the new .coo object in the variable "test"

After exiting the function Jack, the variable "pff" won't hold anything anymore. In fact, the memory-location where the contents of the variable pff was stored, is returned to the system, so it's lost.
If you want to access pff again outside the function, Blitz automatically creates a new variable pff as it doesn't exist in the main program.


_33(Posted 2008) [#19]
Bottom line, with the example I posted, I will still have two occurences of the type coo, remote from the fact that pff is local and that the type content is allocated in a function.

*EDITED*


Gabriel(Posted 2008) [#20]
Bottom line, with the example I posted, I will still have two occurences of the type coo, remote to the fact that pff is local and that the type content is allocated in a function.

I have no idea what you mean by "remote to the fact" but it's completely unrelated to the fact that pff is local and that it's allocated in a function, if that's what you mean. You have two instances because you created two. Initially I assumed that you wanted two, but apparently not. Where they are created is entirely immaterial.


Subirenihil(Posted 2008) [#21]
The reason that you have two instances is that you created two.
Type coo
	Field a
	Field b
End Type

test.coo = New coo ;<--- First instance created here, delete this line
test = jack(1,2);<------ Second instance created here, should be "test.coo = jack(1,2)"
Print test\a
Print test\b
WaitKey()
End

Function jack.coo (aa, bb)
	Local pff.coo = New coo
	pff\a = aa
	pff\b = bb
	Return pff
End Function

test is merely a pointer to one "coo" (yes, blitz uses pointers. Handle(test) returns the actual pointer instead of the object to which it points. Object.coo(<pointer>) will return the object that the <pointer> is pointing to.)
All custom type objects are global. What is confusing you and making you create a second object is that test and pff are both locals, they are pointers to objects that are global. You are creating an object and pointing test to it but then creating another object in a function, pointing another variable to it, then the function returns and changes where test is point so test is now pointing to the second object instead of the first.

Here is a silly illustration of what I mean:
Put a fork on my plate.
Put a piece of cake on my plate.
Aim my fork at the piece of cake. (test.coo = New coo)
Put another piece of cake on my plate. 
Put another fork on my plate and aim it at the second piece of cake. (pff.coo = New coo)
Move my first fork so it is aimed at the same cake as my second fork. (return pff)
Remove the second fork. (pff is deleted when the function closes because it is a local)
I now have 2 pieces of cake (coo objects) but only one fork aimed at the second one (test).


_33(Posted 2008) [#22]
should be "test.coo = jack(1,2)"


Excellent, thanks :)


Stevie G(Posted 2008) [#23]
I'm confused, did I not already say this 2 days ago?


Sake906(Posted 2008) [#24]
just use the "handle()" function to return the handle of the type. EG:

ty.mytype

savedtypevariable=handle(ty)



Later when you need to access it, you go like this:

if object.mytype(savedtypevariable)<>null
ty.mytype=object.mytype(savedtypevariable)
endif



_33(Posted 2008) [#25]
ty.mytype=object.mytype(savedtypevariable)

Didn't know you could do stuff like that with type referencing from a handle. Thanks!


Gabriel(Posted 2008) [#26]
I'm confused, did I not already say this 2 days ago?


You certainly did, but I see no evidence that it was understood. I'm still not entirely sure.


Mortiis(Posted 2008) [#27]
Read this great tutorial.

http://www.hpquest.com/techlord/apps/AOBPwB3D/


Rroff(Posted 2008) [#28]
I always use object/handle now when passing types...

you can also use a single type to build some very powerful linked lists which are very quick to deal with and allow you to store a list of child entities, etc. much more efficently than using a dim array.


Bobysait(Posted 2008) [#29]
Lot of wrong things said on this topic...

Types are not local at all, but can't be considered as global. Types are not a way to declare variables.

Only things local in your codes are the variables used to point to the type.
The types themself still remain somewhere in the memory.
And "this is not a memory holl, this is a feature " ( Bill Gates )


Type TType Field v End Type

; Making list of instances
For n = 1 To 10
	NewTType(n)
Next

; Access the last TType => Of course, as theirs I made come from behind a function, they are locally, so Last TType=null.
t.TType=Last TType
Print t\v
; Now, we can say one thing...
; => Types are not like a simple local.
WaitKey
End


; return nothing !
Function NewTType(val)
 Local t.ttype=New ttype
 t\v=val
; Oooo it is a local, so as it is said on BlitzBasic.com, i assume it will be deleted ... mmmm....
End Function



this second code show you can access any type everywhere you want.
+> absolutely no local
Type TType Field v End Type
For n = 1 To 10 NewTType(n) Next
PrintFirst()
WaitKey:End
Function NewTType(val):Local t.ttype=New ttype:t\v=val:End Function
Function PrintFirst() :t.ttype=First ttype:Print t\v:End Function




I always use object/handle now when passing types...


I do the same, but, i only do it for librarys functions => just for external user that will prefer deal with integer variable rather than with types
For private function, I prefer do it with full type declaration
+> It's faster and there is less to check to be sure the specified object exists.


Stevie G(Posted 2008) [#30]

Types are not local at all, but can't be considered as global.



If they can be accessed from anywhere in your code ( inside or outside functions ) then they are Global by definition.


Bobysait(Posted 2008) [#31]

If they can be accessed from anywhere in your code ( inside or outside functions ) then they are Global by definition.



So a function is a global ...
Your definition come with variable.
Types are other kind of variables, but more like any entity or image/textures etc... in Blitz3D; you need variable to point to them.. so we can't really compare types to variables.
You have to think about they are not variables, and there, you'll can imagine "Why" they are so special ^^ ... sometimes local, sometimes global... sometimes both, and sometines any -_-' ... types are not globals .


Jasu(Posted 2008) [#32]
Well in a way the type object isn't global, but the internal object list is.
Personally I think it's better to call type objects global, since it describes their behavior better than anything else.


Bobysait(Posted 2008) [#33]
Local Mesh=CreateMesh()
Local Piv=CreatePivot()
Local Sprite=CreateSprite()
Global Cam=CreateCamera()


Mesh,Piv, and Sprite are Local Variables, while CreateMesh(), CreatePivot() and CreateSprite() return Memory pointer ( that are ... Global using your definition ? ). Cam is a global variable !

If we leave the function where they are created, Sprite,Mesh and Pivot are "0", but entitys created will remain.

i=12


Here "i" is a local variable, and if we leave the function where it was created, i is released, and "12" ... "12" is just a number, what happens to it when we leave the function ? :)

Dim Entitys(3)
Entitys(0)=Mesh
Entitys(1)=Piv
Entitys(2)=Sprite


Array can be accessed anywhere +> Here, it's the list of my variables ( LOCAL Variable ). Now, I can access any Entitys, anywhere in my code. So, as the list is global, Mesh,Sprite and Piv become global ???

types are just types !
you can point them with global or local variable, but the instance of the type you create is neither local or global.
We can use For/Each to access them later, as we can use an array to store locals entitys ^^.
t.MyType=New MyType

t is the variable, and t is local, and the instance created is global.
but if we leave the function, t can be used again, and can become a Int, or a Float or whatever. so "t" is a Local variable !

We can't say Memory pointers are global, they are just pointer, and nothing else.
Variables used to remember thoose pointers (Sprite,Mesh Pivot, and Cam AND "t") can be global or local.


If they can be accessed from anywhere in your code ( inside or outside functions ) then they are Global by definition.


As they are stored in memory and not released at end of functions, we can say they are globals, so any entitys in blitz3d are globals, and Images, Textures and Buffers too.

There is not only Globals and Locals . There is functions, pointers and else. Don't forget it, it 's just not the same thing.
"CreateCamera()" is not a variable, like "New MyType".
If you Include a source file to your project, then you can access it. So an included source file is global. That has no sense


Stevie G(Posted 2008) [#34]
Are you trying to covince yourself or is all that directed towards someone in particular?


Bobysait(Posted 2008) [#35]
Are you trying to covince yourself or is all that directed towards someone in particular?

It seems very sarcastic...
Whatever it was just in answer to Jasu's post, and a part to you ^^.

Convince myself ... hum ...
I don't need to convince myself what a Type is, but I don't like naming a cat, a dog. So types are types, no local, no global, juste Types !
You want call something Global or Local ? Speak about their implentation, but not about their behavior.

I see lot of people having troubles using types, and I don't think this kind of post will help them to understand, if we talk about visibility of variables.


Stevie G(Posted 2008) [#36]
I think your posts only serve to confuse.

I personally consider types to be a global collection of objects. The variable which points to an instance in this collection can be local or global.

I honestly couldn't care less whether you agree or not so lets leave it at that.


Gabriel(Posted 2008) [#37]
I think your posts only serve to confuse.

I concur. The whole root problem of this entire thread is because of the kind of confusion that Bobysait is repeating there.


Jasu(Posted 2008) [#38]
I don't need to convince myself what a Type is, but I don't like naming a cat, a dog.

You could have a cat, who's name is dog. So would it be wrong to call it a cat if he's called dog? Or calling it dog, even though he's actually a cat? What would you call it?

I would call him Zeke, just to confuse people. And correct anyone who would try to call it cat or dog. Or Zeke.

The word global is an adjective, so you can use it to describe things. I don't think it has been misused here.


Bobysait(Posted 2008) [#39]
Then call what you want as you like... I don't care ^^