- Joined
- Nov 4, 2007
- Messages
- 337
It's not good for warcraft.
I have already proven, that my system is safer and faster.
I have already proven, that my system is safer and faster.
// ________________________
// | How does this work? |
// |________________________|
// - If you call NewIndex(handle), an integer for the Index is increased by 1.
// If you call ReleaseIndex(handle) then, the integer is decreased by 1.
// If the Integer is 0, the Index is released.
// - Handles you create Indexes for are stored in an array and removed until you release the Index.
// - When there is no unique Index left, it loops through the Handle Array, and the Indexes of destroyed handles are released.
// - When the Handle ID of your Handle goes over MAX_HANDLE_ID, it will create an Index, that may cause Overlay.
// It will swap to a Modulo Hash
// - The system counts, how many times it has been used, how often any Limits were reached and.. A lot of stuff.
// If you write -indexstats ingame, the system will give you a lot of information.
// If you appear bugs and think, the bugs are the fault of HandleIndexing, you should write that.
// The system will output bugs.
// **************************************************
//! * H A N D L E I N D E X I N G *
// **************************************************
//| ----------------------------------------------- |
//| | ############################# |
//| HandleIndexing | #### [ Diamond Flavour ] #### |
//| | ############################# |
//| ----------------------------------------------- |
//
// Actually, normal HandleIndexing is the better choice.
// But this is the safest HandleIndexing.
// Actually, you can't do anything wrong.
// But: This needs a lot more memory, and a lot more CPU.
// If you don't call this periodically every 0.01 seconds or wahtever, you won't even
// notice that.
//
// Differences:
// ________________
// | Differences |
// |________________|
// - You dont have to be careful when you Flush an Index with this Flavour.
// - Instead of calling Index(handle) to create AND get an Index, you have to
// call GetIndex(handle) to return the Index of the unit and
// call NewIndex(handle) to create an Index for the unit.
// - This is much slower than the Normal Handle Indexing.
// ________________________
// | How does this work? |
// |________________________|
// - If you call NewIndex(handle), an integer for the Index is increased by 1.
// If you call ReleaseIndex(handle) then, the integer is decreased by 1.
// If the Integer is 0, the Index is released.
// - Handles you create Indexes for are stored in an array and removed until you release the Index.
// - When there is no unique Index left, it loops through the Handle Array, and the Indexes of destroyed handles are released.
// - When the Handle ID of your Handle goes over MAX_HANDLE_ID, it will create an Index, that may cause Overlay.
// It will swap to a Modulo Hash
// - The system counts, how many times it has been used, how often any Limits were reached and.. A lot of stuff.
// If you write -indexstats ingame, the system will give you a lot of information.
// If you appear bugs and think, the bugs are the fault of HandleIndexing, you should write that.
// The system will output bugs.
// ______________________________
// | Speed |
// |______________________________|
// | 18% slower |
// | (than normal HandleIndexing) |
// |______________________________|
library SystemAffector
globals
integer array Affeted
endglobals
function Affect takes integer index returns nothing
set Affeted[index] = Affeted[index] + 1
endfunction
function DeAffect takes integer index returns boolean
set Affeted[index] = Affeted[index] - 1
if (Affeted[index] <= 0 ) then
return true
endif
return false
endfunction
endlibrary
library HandleIndexingDiamond initializer Init requires SystemAffector
globals
private constant integer MAX_HANDLE_ID = 300000
private constant integer tosub = 0x100000
private integer array StoredIDs[MAX_HANDLE_ID]
private integer IDs = 0
private integer gaps = 0
private integer array Gaps
private integer Usages = 0
private integer HIT = 0
private integer HitMAX = 0
private handle array HandleData
private trigger trig
endglobals
private function h2i takes handle h returns integer
return h
return 0
endfunction
function ReleaseIndex takes integer index returns nothing
set gaps = gaps + 1
set Gaps[gaps] = index
endfunction
function FlushIndex takes handle h returns integer
local integer num = h2i(h)-tosub
local integer re = 0
local integer GetExtendedArrayOnce = StoredIDs[num] // INDEX of the handle. Range between 0 and 8190.
if ( num > MAX_HANDLE_ID ) then
set HitMAX = HitMAX + 1
debug call BJDebugMsg("HandleIndexing: Increase MAX_HANDLE_ID!")
set re = ModuloInteger(num-MAX_HANDLE_ID,8191)
set HandleData[re] = null
return re
endif
if ( DeAffect(GetExtendedArrayOnce) ) then
call ReleaseIndex(GetExtendedArrayOnce)
set re = GetExtendedArrayOnce
set StoredIDs[num] = 0
set HandleData[GetExtendedArrayOnce] = null
endif
return re
endfunction
private function FixIndexIssue takes nothing returns nothing
local integer i = 0
loop
set i = i + 1
exitwhen i > 8190
if ( HandleData[i] == null ) then
call ReleaseIndex(i)
endif
endloop
endfunction
function CreateIndex takes integer num returns integer
//! Recycle Indexes
if ( gaps > 0 ) then
set StoredIDs[num] = Gaps[gaps]
set gaps = gaps - 1
return Gaps[gaps+1]
else
//! Create new Index
set IDs = IDs + 1
set StoredIDs[num] = IDs
if IDs > 8190 then
call BJDebugMsg("Handle Indexing; Created too many Indexes! Don't forget to call ReleaseIndex(handle). Trying to fix Issue.")
call FixIndexIssue()
set HIT = HIT + 1
endif
return IDs
endif
endfunction
function GetIndex takes handle h returns integer
local integer hashnum = h2i(h)-tosub
set Usages = Usages + 1
if ( hashnum > MAX_HANDLE_ID ) then
set HitMAX = HitMAX + 1
debug call BJDebugMsg("HandleIndexing: Increase MAX_HANDLE_ID!")
return ModuloInteger(hashnum-MAX_HANDLE_ID,8191)
endif
return StoredIDs[hashnum]
endfunction
function NewIndex takes handle h returns integer
local integer hashnum = h2i(h)-tosub
local integer Return = 0
set Usages = Usages + 1
if ( hashnum > MAX_HANDLE_ID ) then
debug call BJDebugMsg("HandleIndexing: Increase MAX_HANDLE_ID!")
set Return = ModuloInteger(hashnum-MAX_HANDLE_ID,8191)
set HandleData[Return] = h
return Return
endif
if ( StoredIDs[hashnum] == 0 ) then
set Return = CreateIndex(hashnum)
else
set Return = StoredIDs[hashnum]
endif
set HandleData[Return] = h
call Affect(Return)
return Return
endfunction
function DebugIndexing takes nothing returns nothing
call BJDebugMsg("=======================")
call BJDebugMsg(" ---Handle Indexing---")
call BJDebugMsg("=======================")
call BJDebugMsg("Recycler: "+I2S(gaps)+" Indexes that can be recycled.")
call BJDebugMsg("Highest Index was: "+I2S(IDs))
call BJDebugMsg("Indexes in use: "+I2S(IDs-gaps))
call BJDebugMsg("HandleIndexing was used: "+I2S(Usages)+ " times")
call BJDebugMsg("Hit Index Limit: "+I2S(HIT) + " times")
call BJDebugMsg("Hit MAX_HANDLE_ID Limit: "+I2S(HitMAX) + " times")
call BJDebugMsg("=======================")
endfunction
private function Init takes nothing returns nothing
set trig = CreateTrigger()
call TriggerRegisterPlayerChatEvent( trig, Player(0), "-indexstats", true )
call TriggerAddAction( trig, function DebugIndexing )
endfunction
endlibrary
// ===================================================================================================
// --- Handle Struct Attachment ---
// ===================================================================================================
// Handle Struct Attachment based on HandleIndexing(Steel)
// --- IMPORTANT:
// If you want to use it, you have to call RemoveHandleInt and SetHandleInt for
// the same amount of times!
// So every time, you attach an integer, you have to Remove it afterwards!
// Otherwise the System will be destroyed.
//! textmacro HSA takes NAME, TYPE
library HSA$NAME$ requires HandleIndexingSteel
globals
private TYPE array $NAME$Data
endglobals
function SetHandleData$NAME$ takes handle h, $TYPE$ i returns nothing
set $NAME$Data[NewIndex(h)] = i
endfunction
function GetHandleData$NAME$ takes handle h returns $TYPE$
return $NAME$Data[GetIndex(h)]
endfunction
function RemoveHandleData$NAME$ takes handle h returns nothing
set $NAME$Data[FlushIndex(h)] = 0
endfunction
endlibrary
//! endtextmacro
//! runtextmacro HSA("","integer")
// ===================================================================================================
// --- END OF Handle Struct Attachment ---
// ===================================================================================================
//| --------------------------------------------- |
//| | ########################### |
//| HandleIndexing | #### [ Gold Style ] #### |
//| | ########################### |
//| --------------------------------------------- |
// By Mr.Malte
library SystemAffector
// Just making this prettier, but the functions are inlined.
globals
public integer array Affeted
endglobals
function Affect takes integer index returns nothing
set Affeted[index] = Affeted[index] + 1
endfunction
function DeAffect takes integer index returns nothing
set Affeted[index] = Affeted[index] - 1
endfunction
endlibrary
library HandleIndexingGold initializer Init requires SystemAffector
globals
private constant integer MAX_HANDLE_ID = 8191
private constant integer MIN_HANDLE_ID = 0x100000
private integer array StoredIDs[MAX_HANDLE_ID]
private integer IDs = 0
private integer gapcount = 0
private integer array Gaps
private trigger trig
endglobals
private function h2i takes handle h returns integer
return h
return 0
endfunction
private function CreateIndex takes integer num returns integer
// Test was started in NewIndex, but is ended here, since we don't want to cause open threads :-)
//! Recycle Indexes
if gapcount > 0 then
set StoredIDs[num] = Gaps[gapcount]
call Affect(Gaps[gapcount])
set gapcount = gapcount - 1
return Gaps[gapcount+1]
else
//! Create new Index
set IDs = IDs + 1
set StoredIDs[num] = IDs
debug if IDs > 8190 then
debug call BJDebugMsg("Handle Indexing; Created too many Indexes! Don't forget to call ReleaseIndex(handle). Trying to fix Issue. May cause Errors or bugs!")
debug call BJDebugMsg("Swapping to non-injective HASH.")
debug return ModuloInteger(num-MAX_HANDLE_ID,8191)
debug endif
call Affect(IDs)
return IDs
endif
endfunction
function GetIndex takes handle h returns integer
debug if h == null then
debug call BJDebugMsg("HandleIndexing | New Index: Made Index for null handle.")
debug endif
return StoredIDs[h2i(h)-MIN_HANDLE_ID]
endfunction
function NewIndex takes handle h returns integer
local integer hashnum = h2i(h)-MIN_HANDLE_ID
local integer Index = StoredIDs[hashnum]
debug if h == null then
debug call BJDebugMsg("HandleIndexing | New Index: Made Index for null handle.")
debug endif
if Index == 0 then
return CreateIndex(hashnum)
else
call Affect(Index)
return Index
endif
return 0
endfunction
function FlushIndex takes handle h returns integer
local integer num = h2i(h)-MIN_HANDLE_ID
local integer Index = StoredIDs[num]
local integer re = 0
call DeAffect(Index)
if SystemAffector_Affeted[Index] <= 0 then
set gapcount = gapcount + 1
set Gaps[gapcount] = Index
set re = Index
// set StoredIDs[num] = 0 // I dont know, if this is necessary...
endif
return re
endfunction
public function DebugIndexing takes nothing returns nothing
call BJDebugMsg("=======================")
call BJDebugMsg(" ---Handle Indexing---")
call BJDebugMsg("=======================")
call BJDebugMsg("Recycler: "+I2S(gapcount)+" Indexes that can be recycled.")
call BJDebugMsg("Highest Index was: "+I2S(IDs))
call BJDebugMsg("Indexes in use: "+I2S(IDs-gapcount))
call BJDebugMsg("=======================")
endfunction
private function Init takes nothing returns nothing
local trigger t = CreateTrigger()
set trig = CreateTrigger()
call TriggerRegisterPlayerChatEvent( trig, Player(0), "-indexstats", true )
call TriggerAddAction( trig, function DebugIndexing )
call TriggerRegisterPlayerChatEvent( trig, Player(0), "-Test", true )
endfunction
endlibrary
library HelpErrorHI requires HandleIndexingGold
globals
private constant boolean DEBUG = false
System array UnitSystem
endglobals
struct System
string name
handle indexed
integer index
static method GetFrom takes handle h returns System
local System s = UnitSystem[GetIndex(h)]
if h == null then
call BJDebugMsg("HandleIndexing | System.GetFrom used on null handle.")
return
endif
if s == 0 then
call BJDebugMsg("HandleIndexing | System.GetFrom used on handle without system attached.")
return
endif
if DEBUG then
call BJDebugMsg("Got "+s.name+" properly.")
endif
return s
endmethod
method Flush takes nothing returns integer
call .destroy()
return FlushIndex(.indexed)
endmethod
static method create takes handle toIndex, string name returns System
local System s = System.allocate()
set s.indexed = toIndex
set s.index = NewIndex(toIndex)
set s.name = name
set UnitSystem[s.index] = s
return s
endmethod
endstruct
endlibrary