Achso, okay.
Ich hatte da auch mal sowas gemacht. Schon Ewigkeiten her. Ich hab das mal eben umgebaut auf Module:
Code: Alles auswählen
DeclareModule ID
Structure IDList
count.i
List freeIDs.i()
EndStructure
Global NewMap IDs.IDList()
Declare.i newID(type.s)
Declare.i freeID(type.s, id.i)
EndDeclareModule
Module ID
Procedure.i newID(type.s)
Protected *idList.IDList = FindMapElement(IDs(), type)
Protected tmp.i
If (*idList)
If (FirstElement(*idList\freeIDs()))
tmp = *idList\freeIDs()
DeleteElement(*idList\freeIDs())
ProcedureReturn tmp
Else
*idList\count + 1
ProcedureReturn *idList\count - 1
EndIf
Else
*idList = AddMapElement(IDs(), type, #PB_Map_NoElementCheck)
If (Not *idList)
ProcedureReturn -1
EndIf
*idList\count + 1
ProcedureReturn 0
EndIf
EndProcedure
Procedure.i freeID(type.s, id.i)
Protected *idList.IDList = FindMapElement(IDs(), type)
If (Not *idList)
ProcedureReturn #False
EndIf
With *idList
If (id = \count - 1)
\count - 1
Else
If AddElement(\freeIDs())
\freeIDs() = id
SortList(\freeIDs(), #PB_Sort_Ascending)
;Räume die Liste auf
While LastElement(\freeIDs())
If (\freeIDs() = \count - 1)
DeleteElement(\freeIDs())
\count - 1
Else
Break
EndIf
Wend
EndIf
EndIf
EndWith
ProcedureReturn #True
EndProcedure
EndModule
Debug ID::newID("window")
Debug ID::newID("gadget")
Debug ID::newID("gadget")
Debug ID::newID("gadget")
Debug ID::newID("gadget")
ID::freeID("gadget", 2)
ID::freeID("gadget", 1)
Debug ID::newID("gadget")
Debug ID::newID("gadget")
Ich speichere eigentlich einfach nur die wieder frei gegebenen freien IDs und nimm die wieder aus der Liste heraus, wenn man eine neue braucht. Das 'SortList()' kann man mit einem Heap etwas effizienter machen, aber ob sich das lohnt, kommt auf das Einsatzgebiet an.
///Edit:
Hab noch eine kleine Aufräumroutine eingebaut, die sicher stellt, dass die interne 'freeIDs()'-Liste immer so klein wie möglich ist.