library UnitListModule requires AutoIndex
//===========================================================================
// Information:
//==============
//
// This library provides the UnitList module, which allows you to easily
// create a linked list of struct instances associated with a particular unit.
// There is no faster method to associate a list of structs with a unit or to
// iterate through that list than the method this module uses. Whenever a unit
// leaves the game, all of the struct instances associated with that unit will
// be automatically destroyed. Aside from the fact that this module offers the
// best-possible peformance for this type of task, it is also able to greatly
// simplify the code of any system or spell that needs to associate multiple
// struct instances with a single unit.
//
//===========================================================================
// How to use the UnitList module:
//=================================
//
// Using the UnitList module is pretty simple. First, implement it in your
// struct (preferably at the top to avoid unnecessary TriggerEvaluate calls).
// In the struct's create method, you must call unitListAdd(u). The unit passed
// to this method will become the "owner" of that instance. (An instance may not
// be in more than one unit's list.) In the onDestroy method, you must also call
// unitListRemove(). An example is shown below:
//
/*
struct Example
implement UnitList
static method create takes unit u returns Example
local Example this = allocate()
call unitListAdd(u) //This instance has been added to this unit's list.
return this
endmethod
method onDestroy takes nothing returns nothing
call unitListRemove() //This instance has been removed from the unit's list.
endmethod
endstruct
*/
// The requirement to call unitListAdd() and unitListRemove() will be done
// away with once JassHelper supports module onDestroy and module onCreate, but
// for now, it is not too much of a burden.
//
// Once this is done, your struct will gain all of the methods detailed
// in the API section. Below is an example of how to iterate through the list
// of structs associated with a specific unit:
/*
function IterationExample takes unit u returns nothing
local Example e = Example.unitFirst(u)
loop
exitwhen e == 0
//Do something with e here.
call BJDebugMsg(GetUnitName(e.me))
//"me" refers to the unit that "owns" each struct instance.
set e = e.unitNext
endloop
//Use .unitLast(u) and .unitPrev instead to iterate backwards.
endmethod
*/
//
//===========================================================================
// UnitList module API:
//======================
//
// (static) unitCount(u) -> integer
// This method returns the number of structs of thistype associated with
// the specified unit.
//
// (static) unitFirst(u) -> thistype
// This method returns the first instance of thistype in the list of the
// specified unit.
//
// (static) unitLast(u) -> thistype
// This method returns the last instance of thistype in the list of the
// specified unit.
//
// unitNext -> thistype
// This member contains the next instance of thistype in the list of the
// "owner" this instance.
//
// unitPrev -> thistype
// This member contains the previous instance of thistype in the list of
// the "owner" this instance.
//
// unitListAdd(u)
// This method adds this instance to the list of structs of thistype for
// the specified unit. The unit passed to this method will become the
// "owner" of this struct instance. You may call it again to change the
// "owner".
//
// unitListRemove()
// This method removes this instance from the list of structs of thistype
// for the "owner" of this instance. This should usually be called in the
// onDestroy method of the implementing struct.
//
// (static) unitListDestroy(u)
// This method destroys all instances of thistype in the list of the spec-
// ified unit. This is called automatically on units as they leave the game.
//
// me -> unit
// This member contains the "owner" of this instance, as assigned by the
// unitListAdd(u) method. Contains null if no unit owns the instance.
//
//===========================================================================
readonly thistype unitNext
readonly thistype unitPrev
readonly unit me
static method unitCount takes unit u returns integer
return count[GetUnitId(u)]
endmethod
static method unitFirst takes unit u returns thistype
return first[GetUnitId(u)]
endmethod
static method unitLast takes unit u returns thistype
return last[GetUnitId(u)]
endmethod
method unitListRemove takes nothing returns nothing
local integer id = GetUnitId(me)
if me == null then
return
endif
set me = null
if first[id] == this then
set first[id] = unitNext
endif
if last[id] == this then
set last[id] = unitPrev
endif
set unitPrev.unitNext = unitNext
set unitNext.unitPrev = unitPrev
set count[id] = count[id] - 1
endmethod
method unitListAdd takes unit u returns nothing
local integer id = GetUnitId(u)
if destroying[id] then
return
endif
if me != null then
call unitListRemove()
endif
set me = u
if first[id] == 0 then
set first[id] = this
else
set last[id].unitNext = this
set unitPrev = last[id]
endif
set last[id] = this
set count[id] = count[id] + 1
endmethod
static method unitListDestroy takes unit u returns nothing
local integer id = GetUnitId40;u)
local thistype this = last[id]
set destroying[id] = true
loop
exitwhen this == 0
call destroy40;)
set this = unitPrev
endloop
set destroying[id] = false
endmethod
function interface UnitListDestroyer takes unit u returns nothing
globals
public UnitListDestroyer array destroyers
public integer destroyers_n = -1
endglobals
public function AddUnitList takes UnitListDestroyer destroyer returns nothing
set destroyers_n = destroyers_n + 1
set destroyers[destroyers_n] = destroyer
endfunction
//! textmacro DestroyUnitLists
set n = UnitListModule_destroyers_n
loop
exitwhen n < 0
call UnitListModule_destroyers[n].evaluate(u)
set n = n - 1
endloop
//! endtextmacro
Page 1 sur 1 La question posée dans ce topic a été résolue !
Vous ne pouvez pas poster de nouveaux sujets dans ce forum Vous ne pouvez pas répondre aux sujets dans ce forum Vous ne pouvez pas éditer vos messages dans ce forum Vous ne pouvez pas supprimer vos messages dans ce forum Vous ne pouvez pas voter dans les sondages de ce forum