Just double checking this is right...

Monkey Forums/Monkey Programming/Just double checking this is right...

peterigz(Posted 2012) [#1]
Eachin won't cast for you like in Blitzmax? so for example:

class gameobject
    field children:List<gameobject>
end

class thing extends gameobject
    ..
end

..

for Local t:thing = eachin g.children
    t.update
next


That would work in max but in monkey you have to do:

for Local t:gameobject = eachin g.children
    thing(t).update
next


So basically you have to cast it to "thing" yourself in the for loop? Sorry for very crude example but I hope you see what I mean! Just making sure I'm not missing something :)


Difference(Posted 2012) [#2]
you don't have to typcast, try this:




Gerry Quinn(Posted 2012) [#3]
Eachin seems to do funny things sometimes, especially with collections of primitives such as ints.


Samah(Posted 2012) [#4]
Eachin seems to do funny things sometimes, especially with collections of primitives such as ints.

It also creates an enumerator object every time, which is why I avoid it if I can.


peterigz(Posted 2012) [#5]
Thanks Difference, I'm not sure that covers what I'm trying to do though. How about this example:

Class GameObject

	Field children:List<GameObject> = New List<GameObject>
	
	Method AddChild:Void(child:GameObject)
		children.AddLast(child)
	End
	
End

Class Player Extends GameObject
	
	Field health:Int
	
	Method IncreaseHealth()
		health += 1
	End

End

Class Gun Extends GameObject
	
	Field ammo:Int
	
	Method IncreaseAmmo:Void()
		ammo += 1
	End

End

Function Main()
	Local p:= New Player
	Local g:= New Gun
	
	p.AddChild(g)
	
	For Local g:Gun = EachIn p.children
		g.IncreaseAmmo()
	Next
	
End


That doesn't work because it can't convert from GameObject to Gun so I have to do:

	For Local g:GameObject = EachIn p.children
		Gun(g).IncreaseAmmo()
	Next


Which is fine, I'm just wondering if there's another preferred way or something.


Jesse(Posted 2012) [#6]
Two ways that will work. FIrst:
Class GameObject Abstract '**********************************

	Field children:List<GameObject> = New List<GameObject>
	
	Method AddChild:Void(child:GameObject)
		children.AddLast(child)
	End
	
	Method IncreaseHealth:Void() End '******************************************************
	Method IncreaseAmmo:Void() End '******************************************************
End

Class Player Extends GameObject
	
	Field health:Int
	
	Method IncreaseHealth:Void()
		health += 1
	End

End

Class Gun Extends GameObject
	
	Field ammo:Int
	
	Method IncreaseAmmo:Void()
		ammo += 1
	End

End

Function Main()
	Local p:= New Player
	Local g:= New Gun
	
	p.AddChild(g)
	p.AddChild(p)
	
	For Local o:GameObject = Eachin p.children
		o.IncreaseAmmo()
		o.IncreaseHealth()
	Next
	
End


and the other:

Class GameObject Abstract '************************

	Field children:List<GameObject> = New List<GameObject>
	
	Method AddChild:Void(child:GameObject)
		children.AddLast(child)
	End	
End

Class Player Extends GameObject
	
	Field health:Int
	
	Method IncreaseHealth:Void()
		health += 1
	End

End

Class Gun Extends GameObject
	
	Field ammo:Int
	
	Method IncreaseAmmo:Void()
		ammo += 1
	End

End

Function Main()
	Local p:= New Player
	Local g:= New Gun
	
	p.AddChild(g)
	p.AddChild(p)
	
	For Local o:GameObject = Eachin p.children
		Local g:Gun = Gun(o) '***************************
		If g g.IncreaseAmmo() '***************************
	Next

	
End 


Personally I always use the first one as there is no need to cast.
I could have used abstract on the empty methods in the GameObject class instead of using "End" but then I would have to include a defined method for each of the declared abstract methods in every extended class.


peterigz(Posted 2012) [#7]
Thanks Jesse that's made it clearer. I'll be using method 2 as that suits me more at the moment.