Library Redeclared: PUI

Chaos_Knight

New Member
Reaction score
39
When i save my map, it says Library Redeclared: PUI.

Here is the code.
And yes, when i save it, i check the lines above, ifits any unended librarys.

JASS:
//==============================================================================
//  PUI -- Perfect Unit Indexing by Cohadar -- v4.2
//==============================================================================
//
//  PURPOUSE:
//       * Extending UnitUserData()
//       * This is basically perfect hashing algorithm for units
//
//  HOW TO USE:
//       * You have only one function at your disposal GetUnitIndex(unit)
//         It will return a unique index for each unit in range 1..4095
//
//       * What you will do with that index is all up to you
//         Of course using global arrays is the most obvious choice
//         Advanced jassers will think of a couple of more clever ones ofc.
//
//  PROS: 
//       * You can use any number of systems that previously could not work together
//         because they all required exclusive access of UnitUserData()
//
//       * You can also use this to attach spell data structs to casters
//
//       * There are no SetUnitIndex() or ClearUnitIndex() function here
//         Each unit gets assigned one index that cannot be changed
//         That index will be automatically recycled when unit is removed from the game.
//
//  CONS:
//       * This system uses UnitUserData() itself
//         That means that if you have this sys you must recode 
//         any other system that uses UnitUserData() to use this sys instead
//
//       * If you use UnitIndex for arrays of non-native types (timers, effects and similar)
//         you must check if timer on that index already exists before you create a new one.
//         This can happen if GetUnitIndex() assigns a recycled index (index of some dead and removed unit)
//         to the newly created unit for witch you intended to use timer for
//
//       * All in all this is not a sys for newbies, it gives great power,
//         but it requires knowledge and carefull handling
//
//       * You cannot have more than 4095 units on your map with pui assigned index
//         (at the same time)
//
//  DETAILS:
//       * System is using unit array to keep track of all units with an index.
//         Array is periodically checked for removed units,
//         when removed unit is found, index is recycled.
//         Indexes have "decay time" of 3 (three) sec to prevent bugs
//         caused by attaching to "Can't Raise, Does not decay" type units,
//         or by using RemoveUnit() function
//
//  SYSTEM COMMANDS:  (debug mode only, red player only)
//
//       * type -index to display indexes of currently selected units
//
//       * type -topindex to display total number of assigned unit indexes
//
//  HOW TO IMPORT:
//       * Just create a trigger named PUI
//       * convert it to text and replace the whole trigger text with this one
//
//==============================================================================
library PUI initializer Init

globals    
//==============================================================================
// INDEX_DECAY_TIME = INDEX_DECAY_TICKS * SEGMENT_CHECK_PERIOD
// For current constants 12*0.25 = 3 seconds
//
// Every 512 units on map will add 1 more second to index decay time.
// So if you have 1024 units, index decay time will be 3 + 2 = 5 sec
//
// Index decay time starts AFTER unit is decayed/removed from game.
//==============================================================================

    //-----------------------------------------------
    private constant integer INDEX_DECAY_TICKS = 12
    
    //-----------------------------------------------
    private constant integer INDEX_LIMIT = 4096
    private constant integer INDEX_SEGMENT_SIZE = 128
    private constant real    SEGMENT_CHECK_PERIOD = 0.25
    
    //-----------------------------------------------
    private integer TopIndex = 0
    
    private integer array IndexArray
    private integer array IndexDecayTick
    private unit    array UnitArray
    
    private integer RecycleSegment  = 0
endglobals


//==============================================================================
private function RecycleIndex takes nothing returns boolean
    local integer i 
    local integer op_limiter
    local integer temp
    
    set i = RecycleSegment * INDEX_SEGMENT_SIZE + 1
    
    if i > TopIndex then
        set RecycleSegment = 0
        set i = 1 // zero index is not used
    endif
    
    set op_limiter = i + INDEX_SEGMENT_SIZE - 1
    
    loop
        exitwhen i > TopIndex
        exitwhen i > op_limiter
        
        if IndexDecayTick<i> == 0 then
            if (GetUnitUserData(UnitArray<i>)==0) then
                set IndexDecayTick<i> = 1
            endif
        else
            set IndexDecayTick<i> = IndexDecayTick<i> + 1
            if IndexDecayTick<i> &gt;= INDEX_DECAY_TICKS then
                set UnitArray<i> = UnitArray[TopIndex]
                set UnitArray[TopIndex] = null
                set IndexDecayTick<i> = IndexDecayTick[TopIndex]
                set IndexDecayTick[TopIndex] = 0
                set temp = IndexArray<i>
                set IndexArray<i> = IndexArray[TopIndex]
                set IndexArray[TopIndex] = temp
                //debug call BJDebugMsg(&quot;|c0000FF00PUI: Index recycled #&quot; + I2S(IndexArray[TopIndex]))
                set TopIndex = TopIndex - 1
            endif
        endif
        
        set i = i + 1
    endloop
    
    set RecycleSegment = RecycleSegment + 1
    return false
endfunction

//==============================================================================
private function DisplayTopIndex takes nothing returns nothing
    call BJDebugMsg(&quot;TopIndex = &quot; + I2S(TopIndex))
endfunction

//===========================================================================
private function DisplaySelectedEnum takes nothing returns nothing
    call BJDebugMsg( &quot;PUI: index for unit {&quot; + ( GetUnitName(GetEnumUnit()) + ( &quot;} = &quot; + I2S(GetUnitUserData(GetEnumUnit())) ) ) )
endfunction

//===========================================================================
private function DisplaySelected takes nothing returns nothing
    local group g = CreateGroup()
    call SyncSelections()
    call GroupEnumUnitsSelected(g, Player(0), null)
    call ForGroup(g, function DisplaySelectedEnum)
    call DestroyGroup(g)
    set  g = null
endfunction

//==============================================================================
//  Main and only function exported by this library
//  WARNING: this function can return zero, you should always check that.
//==============================================================================
function GetUnitIndex takes unit whichUnit returns integer
    local integer index
    
    if whichUnit == null then
        call BJDebugMsg(&quot;|c00FF0000ERROR: PUI - Index requested for null unit&quot;)
        return 0
    endif
    
    set index = GetUnitUserData(whichUnit)

    if index == 0 then
        set TopIndex = TopIndex + 1
        set index = IndexArray[TopIndex]
        set UnitArray[TopIndex] = whichUnit
       
        call SetUnitUserData(whichUnit, index)
        set index = GetUnitUserData(whichUnit)
       
        // this happens when requesting unit index for removed unit
        if index == 0 then
            call BJDebugMsg(&quot;|c00FFCC00WARNING: PUI - Bad unit handle&quot;)
        endif
        
        //debug call BJDebugMsg(&quot;|c00FFCC00PUI: Index assigned #&quot; + I2S(index))
    endif
    
    return index
endfunction

//==============================================================================
private function Init takes nothing returns nothing
    local integer i
    local trigger trig 
    
    set i = 1
    loop
        exitwhen i &gt;= INDEX_LIMIT
        set IndexArray<i> = i
        set i = i + 1
    endloop
    
    set trig = CreateTrigger()
    call TriggerRegisterTimerEventPeriodic( trig, SEGMENT_CHECK_PERIOD )
    call TriggerAddCondition( trig, Condition(function RecycleIndex) )

    debug set trig = CreateTrigger()
    debug call TriggerRegisterPlayerChatEvent( trig, Player(0), &quot;-index&quot;, true )
    debug call TriggerAddAction( trig, function DisplaySelected )      
    
    debug set trig = CreateTrigger()
    debug call TriggerRegisterPlayerChatEvent( trig, Player(0), &quot;-topindex&quot;, true )
    debug call TriggerAddAction( trig, function DisplayTopIndex )
endfunction

endlibrary
</i></i></i></i></i></i></i></i></i></i></i>


//Chaos_Knight :cool:
 

Darthfett

Aerospace/Cybersecurity Software Engineer
Reaction score
615
AIDS provides the same functionality as PUI. In fact, it has created a library to replace it, if you in fact want PUI functionality, but while using AIDS.

Basically, just use AIDS exactly as you would PUI, using the [ljass]//! runtextmacro PUI()[/ljass] textmacro.
 

Chaos_Knight

New Member
Reaction score
39
So i wont need PUI? Cause i have an improted spell which uses PUI. Can i just delete that, and add AIDS, instead? :p
 

Laiev

Hey Listen!!
Reaction score
188
Yes..

if the spell use a library in requires, just remove it..

example:

JASS:
library test initializer initTrig requires PUI

to
JASS:
library test initializer initTrig

or
JASS:
library test initializer initTrig requires AIDS
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Members online

      No members online now.

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top