HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Attribute System Suggestions

02-25-2009, 01:12 PM#1
emjlr3
was working on updating my attribute system to allow users more flexibility in the form of additional on-the-fly manipulation and unregistering of units - general coding updates were also in order, to increase performance, and once again allow MUI usage.

to the issue:

in the latest version, I use three triggers which fire off order events, leveling and item manipulation - these are any unit events, and are setup once

Collapse JASS:
private function Init_AttributeSystem takes nothing returns nothing
    local trigger level = CreateTrigger() 
    local trigger inven = CreateTrigger() 
    local trigger att = CreateTrigger()     
    
    call TriggerRegisterAnyUnitEventBJ(level, EVENT_PLAYER_HERO_LEVEL )
    call TriggerAddAction( level, function AS_level_Actions )
    
    call TriggerRegisterAnyUnitEventBJ( inven, EVENT_PLAYER_UNIT_ISSUED_ORDER )
    call TriggerRegisterAnyUnitEventBJ( inven, EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER )
    call TriggerRegisterAnyUnitEventBJ( inven, EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER )
    call TriggerAddAction( inven, function AS_inven_Actions )
    
    call TriggerRegisterAnyUnitEventBJ( att, EVENT_PLAYER_UNIT_USE_ITEM )
    call TriggerAddAction( att, function AS_att_Actions )
endfunction  

i decide one way to increase performance would be to only have these fire for units registered with the system

so at init I simply

Collapse JASS:
globals
    private trigger Level = CreateTrigger()
    private trigger Inven = CreateTrigger()
    private trigger Att = CreateTrigger()
endglobals
private function Init takes nothing returns nothing    
    call TriggerAddAction( Level, function Level_Actions )
    call TriggerAddAction( Inven, function Inven_Actions )    
    call TriggerAddAction( Att, function Att_Actions )
endfunction  

set them up, then when a unit is registered, initialize the events for only that unit

Collapse JASS:
    // in register function
    call TriggerRegisterUnitEvent( Level, u, EVENT_HERO_LEVEL )    
    call TriggerRegisterUnitEvent( Inven, u, EVENT_UNIT_ISSUED_ORDER )
    call TriggerRegisterUnitEvent( Inven, u, EVENT_UNIT_ISSUED_TARGET_ORDER )
    call TriggerRegisterUnitEvent( Inven, u, EVENT_UNIT_ISSUED_POINT_ORDER )    
    call TriggerRegisterUnitEvent( Att, u, EVENT_UNIT_USE_ITEM )

this is all fine and dandy, until I try and unregister a unit from the system
currently this is ugly, as far as the triggers are concerned

Collapse JASS:
private function ReRegister takes nothing returns nothing
    set Hero = GetEnumUnit()
    call TriggerRegisterUnitEvent( Level, Hero, EVENT_HERO_LEVEL )    
    call TriggerRegisterUnitEvent( Inven, Hero, EVENT_UNIT_ISSUED_ORDER )
    call TriggerRegisterUnitEvent( Inven, Hero, EVENT_UNIT_ISSUED_TARGET_ORDER )
    call TriggerRegisterUnitEvent( Inven, Hero, EVENT_UNIT_ISSUED_POINT_ORDER )    
    call TriggerRegisterUnitEvent( Att, Hero, EVENT_UNIT_USE_ITEM )
endfunction

    // in unregister function
    call GroupRemoveUnit(Enabled,u)        
    call DisableTrigger(Level)
    call DisableTrigger(Inven)
    call DisableTrigger(Att)
    set Level = CreateTrigger()
    set Inven = CreateTrigger()
    set Att = CreateTrigger()
    call TriggerAddAction( Level, function Level_Actions )
    call TriggerAddAction( Inven, function Inven_Actions )    
    call TriggerAddAction( Att, function Att_Actions )
    call ForGroup(Enabled, function ReRegister)

i have to disable all old triggers (i would have no issues destroying them, but people tend to not like that anymore), and recreate them/register units with them

obviously using any player event triggers removes this need, but you don't get any performance increase through making them specific to registered units/ removing the overhead of running some system specific check each time

also, this leaks triggers (unless they were to be destroyed) , and currently triggeractions (unless i updated it to run through condition functions) - I could use one trigger, and then it would only leak 1 trigger every unregister - but its still dumb

is the performance increase worth the hassle? other thoughts?
02-25-2009, 08:16 PM#2
Ammorth
Use a HandleTable from Vex's table system, and then when you register a unit, set the Table value for that handle to 1. When you de-register, set it to 0.

Collapse JASS:
globals
    private HandleTable isUnitRegistered
endglobals

//in some init functions
set isUnitRegistered = HandleTable.create()

//in your action triggers
if (isUnitRegistered[TriggeringUnit()] == 1) then
    // do actions
endif

//to register
set isUnitRegistered[UnitToRegister] = 1

//to deregister
set isUnitRegistered[UnitToDeregister] = 0
02-26-2009, 01:33 PM#3
emjlr3
i see that as no easier or more effective then adding/removing units from a global group (which is what I do anyway)

and unless I am missing something, this does not address my issue...
02-26-2009, 11:17 PM#4
Ammorth
Quote:
Originally Posted by emjlr3
i decide one way to increase performance would be to only have these fire for units registered with the system

This allows you to have the actions only run for units registered by the system. Even better yet, you can stick the checks into a condition for the functions, if you want.

Quote:
Originally Posted by emjlr3
this is all fine and dandy, until I try and unregister a unit from the system
currently this is ugly, as far as the triggers are concerned
As you stated, unregistering units from the triggers is a bitch.

As well, any performance increasing properties you gain from using specific unit events, you will loose every time you have to de-register a unit.
02-26-2009, 11:52 PM#5
emjlr3
hmm, then i will just stick with player unit events, and run the overhead of checking a condition for effected units

was just hoping there may be another way of approaching this to still enable me to use unit events effectively