Find a unique type in a TList

BlitzMax Forums/BlitzMax Beginners Area/Find a unique type in a TList

Is there a way of finding an unique Type in a list of different types?

I have a global list of TElements containing all kind of child types of TElement (like TPlayer, TEnemy and TDetails). I know there could be one object in that list of type TDetails and I need to verify if that object still exists.

Below you see an example of a 'not so efficient'code. I think there must be a better solution.

Function hasDetails:Byte()
	Local n = 0
	For Local e:TDetails = EachIn gElements
		n:+1
	Next
	Return n>0
End Function


Off the top of my head, I can already improve your code with this:
Function hasDetails:Byte()
	Local n = 0
	For Local e:TDetails = EachIn gElements
		Return True
	Next
	Return False
End Function

This way, the loop ends the moment you have a match.

Store in your Type the TLINK to the list. If TLINK<>NULL the item still exists in the list.

Do you one to find out if there is at least one of that type, or one and only one?

degac: I don't undrstand your suggestion. Could you give an example?

Czar Flavius: I only need to check if there is an (one) entity of type TDetails. Maybe for an other occasion I want to address the type as well, but then I just need to store the type in a (global) variable.

My question is quite simple: Instead of going through the whole list with a for-next routine isn't there something elegant like:
Print gElements.contains(TDetails)

or something?

Nothing that elegant that I know of, but you might be able to implement a reference count to check for. Something like this maybe?
Global gElements:TList = CreateList()

Type TPlayer
   Global RefCount:Int = 0

   Method AddToList()
      gElements.AddLast(Self)
      RefCount :+ 1
   End Method

   Method RemoveFromList()
      If gElements.Contains(Self) 'Make sure object is actually in list
         gElements.Remove(Self)
         RefCount :- 1
      End If
   End Method

   Function InList()
      Return RefCount
   End Function
End Type

Type TEnemy
   Global RefCount:Int = 0

   Method AddToList()
      gElements.AddLast(Self)
      RefCount :+ 1
   End Method

   Method RemoveFromList()
      If gElements.Contains(Self) 'Make sure object is actually in list
         gElements.Remove(Self)
         RefCount :- 1
      End If
   End Method

   Function InList()
      Return RefCount
   End Function
End Type

Type TDetails
   Global RefCount:Int = 0

   Method AddToList()
      gElements.AddLast(Self)
      RefCount :+ 1
   End Method

   Method RemoveFromList()
      If gElements.Contains(Self) 'Make sure object is actually in list
         gElements.Remove(Self)
         RefCount :- 1
      End If
   End Method

   Function InList()
      Return RefCount
   End Function
End Type

Local Player:TPlayer = New TPlayer
Player.AddToList()
Local Details:TDetails = New TDetails
Details.AddToList()

If TPlayer.InList()
   Print "TPlayer in List"
Else 
	Print "TPlayer Not in List"
End If

If TEnemy.InList()
	Print "TEnemy in List"
Else
	Print "TEnemy not in list"
End If

If TDetails.InList()
	Print "TDetails in list"
Else
	Print "TDetails Not in list"
End If


Oh - maybe I have misunderstood what you want..

TomToad: That's interesting. You ask the Type itself if it exists in the list. You do not have to make an instance of it (like you did with TEnemy in the example).
I don't understand the global RefCount. Why is it global and why is the value different within the three types?

A way extending TList to track type counts....
SuperStrict

Type MySpecialList Extends TList

	Field lookup:Int[] = New Int[10]

	Method AddLast:TLink( value:Object )
		If TCountable(value) Then
			lookup[TCountable(value).getType()]:+ 1
		End If
		
		Return Super.AddLast(value)
	End Method
	
	Method Remove:Int( value:Object )
		If Super.Remove(value) Then
			If TCountable(value) Then
				lookup[TCountable(value).getType()]:- 1
			End If
		End If
	End Method

	Method exists:Int(kind:Int)
		Return lookup[kind]
	End Method
	
End Type


Type TCountable
	Function getType:Int() Abstract
End Type

Type TPlayer Extends TCountable
	Function getType:Int()
		Return 1
	End Function
End Type

Type TOther Extends TCountable
	Function getType:Int()
		Return 2
	End Function
End Type


' 
Local list:MySpecialList = New MySpecialList

Local p:TPlayer = New TPlayer
list.AddLast(p)

' contains any players?
Print list.exists(TPlayer.getType())

' contains any Others?
Print list.exists(TOther.getType())

list.remove(p)

' contains any players?
Print list.exists(TPlayer.getType())

' contains any Others?
Print list.exists(TOther.getType())


Allows you to add any old crap to the list, but will only count TCountable types...

Quite simple.
Every time you create a type (player) and use the AddtoList method, an internal counter will be increased.
While every time you use RemoveFromList the counter will be decreased by 1 unit.
In this way you have to check if tplayer.refcount>0 to know if a tplayer exists or not.

Thank you, everyone.
Very inspiring example codes. Not as simple as gElements.contains(TDetails) ;-) but nevertheless very useful. And, from a programming point of view, nicer than the for-next loop solution.

TomToad: That's interesting. You ask the Type itself if it exists in the list. You do not have to make an instance of it (like you did with TEnemy in the example).
I don't understand the global RefCount. Why is it global and why is the value different within the three types?

Globals within a Type are treated differently from Globals in the main program. Type Globals mean that you are applying that value to all instances of that type instead of just one.
So if you add 10 TEnemies to the list, then RefCount will equal 10 in all TEnemies.