• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[JASS] HSAS (Handle Struct Attachment System)

Level 3
Joined
Sep 4, 2007
Messages
49
[vJASS] HSAS (Handle Struct Attachment System)

HSAS (Handle Struct Attachment System)
Current Version: 3.60

Requires
- Decent JASS Knowledge (especially about structs)
- JassNewGen v5.a

Credits
- Vexorian/Cohadar with his help on the code
- Bob666 for benchmark system

HSAS (Handle Struct Attachment System) is a system similar to the original CSData system that directly attaches handles to arrays. However there have been modifications, HSAS uses the vJASS sized arrays to store handles, before going to Game Cache, it even allows you to create different databases for struct storage if you want to attach multiple structs to the same handle

The system just uses conventional arrays to store data. The maximum possible number of handles that can be used by the system is specified by a limit per database, however the actual maximum value can be lower, and it decreases as the map time increases (the bigger the gap between the handle indexes the lower the amount of structs you can store). It is however almost IMPOSSIBLE to go through all 3 arrays as long as
1. You are not being stupid
2. MOST CRUCIALLY remember to set your handles to null when you are finished with them. This recycles the index which makes a huge differences in the amount of data the system an store. If you set your handles to null most of the time then you will most likely never reach the limit
3. Someone enjoys playing your map for over a day straight

What is so good about the system, its the fastest way to attach structs to timers,proven by the benchmark system created by Bob666

Changelog

v3.60
- Typos with HSAS debug mode and a bug with interger division has been fixed (thanks Themerion)

v3.50
- With the addition of sized arrays in JassNewGen 5.a,you can now specify the limit for static libraries instead of having the fixed limit of 24570. You can also specify the limit for dynamic libraries. Please read the Usage trigger on information on how to deal with the changes

v3.40
- Fixed an issue with HSAS not compiling due to a change in the PJASS syntax editor (for JassNewGen v4.x)
- Added scope compatibility for HSAS to make it easier for HSAS to be used in libraries for external maps, please read the Usage trigger for more information
- Added a compatibility trigger for ABC v5.1
- Updated Cohadar's ABC to v5.1
- Using Cohadars spell layout (thanks heaps) the HSAS trigger now has more information regarding the system, as well as a comparison between HSAS and ABC
- Debug statements have been added to HSAS to notify users of current positions in indexes, as well as warning when upper limits are reached (means you are not nulling local/struct handles, naughty you)
- Update bob666 benchmarking system to v1.10 (should give much more accurate results)

v3.30
- The structure for static and dynamic databases has changed, please refer to the readme for more info

v3.20
- Fixed a big bug, the firstindex was not always the firstindex so In some cases the data was
lost when storing

v3.10
- Removed the unnecessary decleration of some global arrays

v3.00
- First release that has had no problems :)
- Issues with the system not using gamecache properly when limit was exceeded is now fixed
- Slight increase with efficiency
- Another issue solved with conflict in gamecache storage with dynamic and static databases

v2.30
- Problem with Dynamic struct attachment (fixed now) and the storage data tests now work
properly
- Dynamic Storage Test Added

v2.20
- An extra test that fills up the system with values and retrieves them (to test stability).
Thx again Cohadar

v2.10
- The system now uses constants instead of arithmetic for further efficiency (thx Cohadar)

v2.00
- Fixed dynamic methods of databasing for HSAS
- Fixed loading screen and map description
- All of the BenchMark globals (created by Bob666) transferred vJASS globals to remove udg's
- A demo featuring the 'Crazy Ass Jumping Taurens'
- You can now check between different tests
- Added another test which uses array of handles (supposed to be a more accurate representation)

v1.00
- Initial release

Code

JASS:
//==============================================================================
//  HSAS -- HANDLE -> STRUCT ATTACHMENT SYSTEM -- v3.6
//==============================================================================
//
//  PURPOUSE:
//       * Attaching multiple structs to any pointer-type handle (timers,units,triggers etc)
//       * Uses GameCache as backup
//       * Similar in design to the old CSData
//
//  HOW TO USE:
//       * Check the usage trigger in the map
//
//  PROS: 
//       * Proven to be the fastest way possible to attach structs to handles, a hell of a lot faster then gamecache
//         and still much faster then ABC
//
//       * Can attach structs to any type of pointer handle, not just Timers/Units/Triggers etc
//         
//       * Can create multiple static instances of the System, i.e. AttachStruct1, AttachStruct2
//
//       * As of HSAS v3.50 you can specify the amount of Data that Static/Dynamic libraries 
//       can hold. This means if you specify a very high upper value, it will most likely
//       never resort to gamecache even if you do leak
//         
//       * Also has the option of Dynamic Instances using Dynamic Arrays i.e. AttachStructDynamic(handle,key)
//
//       * System reports once indexes reach a dangerously high level as well as the current index position
//        (Debug Mode)
//
//       * No need to clear up any struct attachments once your done with them, recycling index's takes 
//         care of that
//
//       * As long as you null local handles when your finished with them, no problems will occur
//
//       * You can scope HSAS by making it global, private or public for both static/dynamic databases
//        giving you more flexibility in the system and making implementation in other external maps
//        that already use the system (you don't need to modify the HSAS trigger to customize, create
//        HSAS databases, it can be done from outside the trigger)
//
// CONS:
//
//       * Like Cohadars PUI, this system is not for Newbies. YOU MUST REMEMBER 
//         TO NULL VARIABLES. Not doing so can make the system resort to gamecache in
//         extreme circumstances (above the amount of index's you chose to store)
//
//       * For the reason above if you use HSAS in systems that you have made, you must
//         mention to users of the system to null local variables as well. Even though your
//         system itself may not leak, if other sections in the map will leak it will effect the system
//
//  ABC VS HSAS:
//       * Since there are two different systems for attaching structs to handles, I will outline the main
//         differences between ABC and HSAS
//
//       * HSAS is as fast as you will ever get when it comes to struct attachment, it is ludicrously simple,
//         (just subtracts 0x100000 from the H2I index and stores in multiple arrays depending on size)
//
//       * You can screw ABC like a donkey and nothing would happen to it. Since it uses hashtables
//         it is as newb friendly as you can get. Even if you never null handles it will work without problems
//
//       * On the other hand with ABC you are required to clear the memory of Attaching Structs which
//         does not need to be done with HSAS. Although this can be thought of evening the scales with
//         nulling local handles (HSAS) and clearing struct attachment (ABC) the effect is much greater on
//         HSAS. This is because ALL and I mean ALL handles throughout your map must be nulled, not just
//         the handles that HSAS uses.
//         NOTE: As of HSAS v3.50 you can actually specify the limit, this means that you can
//         use a really high limit (i.e. 100000) for the static libraries and even with
//         leaks its unlikely that you will surpass that limit
//
//       * Further reitorating with what was said above, only PROS should use this system. If you are making
//         a system of your own, unless you actually need the speed (HSAS should only really be used for
//         memory straining systems such as projectile/physics etc where very fast periodic timers/triggers
//         are used) I would recommend using ABC. Saying this again, if you do choose to use HSAS with a
//         system you are making, make sure to mention that users must null local handles as it will effect
//         the system
//
//        * On the other hand, this system is handle attaching friendly. Cohadars latest ABC system (v5.1)
//         requires seperate functions for the 3 main handle types, with HSAS its the same generic function
//         for all handles
//
//        * If the maximum upper limit is reached in HSAS (for both static and dynamic) then it will resort
//        to using the old fashioned gamecache where as ABC will keep on going unless you forget to clear
//        struct attachments
//
//        * Forgot to mention that if you are using structs/interfaces, you also need to null any handles
//         that are members of that struct/interface. Use the onDestroy() method to do this
//
//  SPECIAL THANKS TO: 
//       * Vexorian - Noticing bloated code in earlier version
//       * Cohadar - for the competition -_- and improvments on the system and for the nice layout as
//         well as the extended arrays system
//         he uses for his systems
//       * Bob666 (from Wc3jass.com) for his uber benchmarking system in testing speed of scripts
//       * PurplePoot - pointing out improvments in the system with dynamic arrays
//         Thank you guys.
//
//  HOW TO IMPORT:
//       * Just create a trigger named HSAS
//       * convert it to text and replace the whole trigger text with this one
//
//==============================================================================
library HSAS
globals
    public constant integer firstindex = 0x100000
    public gamecache cache
    public boolean CacheInitialized = true
    public boolean DebugMap = true
endglobals

public function InitCache takes nothing  returns nothing
    call FlushGameCache(InitGameCache("HSAS_cache"))
    set HSAS_cache=InitGameCache("HSAS_cache")
    set HSAS_CacheInitialized = false
endfunction

public function H2I takes handle h returns integer
    return h
    return 0
endfunction
endlibrary

//! textmacro HSAS_Dynamic takes LIMIT1, INSTANCE, LIMIT2, SCOPE
$SCOPE$ type array_1 extends integer array[$LIMIT1$,$INSTANCE$]
$SCOPE$ type array_2 extends array_1 array[$LIMIT2$]

globals
$SCOPE$ array_2 a_2
endglobals

$SCOPE$ function HSAS_Initialize takes nothing returns nothing
local integer counter = 1
set a_2 = array_2.create()

loop
    exitwhen counter >= $LIMIT2$
    set a_2[counter] = array_1.create()
    set counter = counter + 1
endloop
endfunction 

$SCOPE$ function GetAttachedStructDynamic takes handle h, integer database returns integer
local integer index = HSAS_H2I(h)
local integer position = index - HSAS_firstindex
if position < $LIMIT1$ then
    return a_2[position][database]
else
    return GetStoredInteger(HSAS_cache,I2S(database),"D"+I2S(index))
endif
return 0
endfunction

$SCOPE$ function AttachStructDynamic takes handle h, integer database, integer structid returns nothing
local integer index = HSAS_H2I(h)
local integer position = index - HSAS_firstindex //<- The first handle created will always have the index 1048666
if position < $LIMIT1$ then
    set a_2[position][database] = structid
else
    if HSAS_CacheInitialized then
        call HSAS_InitCache()
    endif
    call StoreInteger(HSAS_cache,I2S(database),"D"+I2S(index),structid)
endif
endfunction

//! endtextmacro

//! textmacro HSAS_Static takes IDENTIFIER, ARRAYSIZE, SCOPE

globals
$SCOPE$ integer array HSAS_index_$IDENTIFIER$ [$ARRAYSIZE$]
endglobals

$SCOPE$ function GetAttachedStruct$IDENTIFIER$ takes handle h returns integer
local integer index = HSAS_H2I(h)
local integer position = index - HSAS_firstindex
if position < $ARRAYSIZE$ then
    return HSAS_index_$IDENTIFIER$[position]
else
    return GetStoredInteger(HSAS_cache,"S"+"$IDENTIFIER$",I2S(index))
endif
return 0
endfunction

$SCOPE$ function AttachStruct$IDENTIFIER$ takes handle h, integer structid returns nothing
local integer index = HSAS_H2I(h)
local integer position = index - HSAS_firstindex //<- The first handle created will always have the index 1048666
debug if HSAS_DebugMap then    
    debug call BJDebugMsg("|CFF00FF00" + "HSAS: Current Index Position #" + I2S(position))
debug endif
if position < $ARRAYSIZE$ then
    set HSAS_index_$IDENTIFIER$[position] = structid
else
    call StoreInteger(HSAS_cache,"S"+"$IDENTIFIER$",I2S(index),structid)
endif
debug if position > ($ARRAYSIZE$/3) then
    debug call BJDebugMsg("|CFFFF8A00" + "HSAS: Warning! Gone Through "+ R2S($ARRAYSIZE$) + " Indexes")
debug elseif position > ($ARRAYSIZE$*2/3) then
    debug call BJDebugMsg("|CFFED1C24" + "HSAS: Warning! Gone Through "+ R2S($ARRAYSIZE$*2/3) + " Indexes")
debug elseif position > $ARRAYSIZE$ then
    debug call BJDebugMsg("|CFF32004B" + "HSAS: Warning! Gone Through $ARRAYSIZE$ Indexes, Now using GameCache")
debug endif
    
    
endfunction
//! endtextmacro

//===========================================================================
function InitTrig_HSAS takes nothing returns nothing
    set gg_trg_HSAS = CreateTrigger(  )
endfunction

Usage
Static VS Dynamic? What is the difference
Simply put when using static databases you can only specify the identifier with functions. Identifiers cannot be linked with variables and cannot be changed during the map course i.e. to store using a static database you would do call AttachStruct<IDENTIFIER>, however that identifier has to be entered in the actual map code and you cannot enter in there a variable (for obvious reasons)

Whats the advantage for static?
Well its a lot faster then dynamic (and the fastest possible way to attach structs to handles), for most spells static will be more then enough as the IDENTIFIER will never change and you will not need to create a new one during the map course. If you need to attach more then one struct to a handle then you can create multiple static databases (since this will not change during the map course as well)

Dynamic databases work similar to gamecache, unlike in static databases you can specify the identifier through an integer variable and you can change the amount of dynamic databases during map course. You can even make dynamic databases of databases and keep on going. They are slower then Static since they use dual arrays, and the amount of data they can store is a lot lower however they are more versatile

Whats the advantage for dynamic?
Dynamic databases are much more suited to storing data relating to handles in the form of structs. You can for example do AttacStructDynamic(handle, SpellId, struct) and you can make a specific database of spell id's.

**********************************************
* *
* CREATING STATIC HANDLE - STRUCT DATABASES *
* *
**********************************************

From v3.40 you can create static databases anywhere with any kind of scope. This can be really handy if you're releasing systems that will use HSAS. You can create local, public or global static databases depending on how you want to use them

This is the format for the textmacro that creates the Static Database

//! textmacro HSAS_Static takes IDENTIFIER, ARRAYSIZE, SCOPE

What the textmacro requires is an identifier, array size and a scope

The IDENTIFIER is used to refer to a specific struct, the IDENTIFIER can be any string that is not already a vJASS definined keyword (i.e. 1, ef, 234, a, ag are all valid identifiers). You can create as many different identifiers you want, and the purpouse for creating multiple static databases is if you want to attack more then ONE struct to a SINGLE handle (i.e. if you want to attach
2 structs to a single unit, you would need to create 2 static databases and use one database for one struct and another database for the other struct)
NOTE: MAKE SURE THE IDENTIFIER ISNT "Dynamic" and THERE ARE NO WHITESPACES (i.e. " " will cause errors, please use underscores instead of spaces)

The array size determines the size of the static database. In pre 3.50 versions of HSAS, the size was fixed at 24570, now you can specify any limit you want to. It is recommended you only use values from 30000-100000 depending on the size of the map and how much data the system is going to be storing. As with every other version of HSAS, if you go over this limit it will resort to gamecache (except that now you can specify the limit). This
means that the system can now sustain more abuse then before, so you don't have to be so pedantic about handle leaks.
NOTE: The maximum size is 409550, you should never ever have to have such
a high array size

The SCOPE determines the availability of the static database. For global static databases, that can be accessed anywhere use "" in your SCOPE prefix e.g. //! runtextmacro HSAS("1","32760",""). Note that global static databases don't have to declared in a library/scope where as public/private has to be declared in a library/scope. You can also create private static databases that can only be accessed inside the scope/library they are declared, in this case you use private" (i.e. //! runtextmacro HSAS("1","32760","private"). Finally you can create a public static database (e.g. //! runtextmacro HSAS("1","32760","public"), which like global can be accessed anywhere in the map, but in order to access the static database from OUTSIDE the scope/library you need to use the scope/library prefix followed by an underscore and then the function (this will be explained later)

Note that if you create a global static database outside of a library don't expect it to be able to be accessed from anything thats compiled before that instance. You should always create global static databases inside a library

The example this system uses does //! runtextmacro HSAS_Static("1","32760","") (as can be seen in the example)

Then when you want to store/retrieve data you would do this (using the example of 1)

call AttachStruct1(handle,struct)

and

call GetAttachedStruct1(handle)

if you did 2 as your example you would do

call AttachStruct2(handle,struct)

and

call GetAttachedStruct2(handle)

Now if you created public static database and you are trying to access it from outside the library/scope that it was declared you need to use the library/scope name that the static database is created in as a prefix, followed by an underscore and then finally either the AttachStruct or GetStruct function e.g. assume that you created a public static database in a library called bob using //! runtextmacro HSAS("1","32760","public"). If you want to access the static database from inside the library bob then you would just use call AttachStruct1(handle,struct), but if you want to access static library from OUTSIDE the library bob, you would need to do call bob_AttachStruct1(handle,struct)

Thats it, there is no limit to the number of struct databases you can create, however dont go crazy, You should never need more then 2 or 3

***********************************************
* *
* CREATING DYNAMIC HANDLE - STRUCT DATABASES *
* *
***********************************************

This is the format for the textmacro that creates the Dynaimc Database

//! textmacro HSAS_Dynamic takes LIMIT1, INSTANCE, LIMIT2, SCOPE

You need to specify limits for both the amount of handles you will attach and the number of databases for each handle as well as the scope of the function. The maximum limit is 1000, maximum instance is 409550 and the maximum for limit 2 is 1000. The first limit is the number of handles and the second is the number of databases. When you have decided the limits, put. If your limit is too high however due to the nature of dynamic arrays there will be problems with multi-instancability (refer to vJASS manual)

As mentioned you also need to specify the scope of the dynamic database, this works in the exact same way as static databases so if you need help then just refer to the static databases section



NOTE: You only need do this ONCE, as you can see in the System trigger it is already there so when you copy it into your map you only need to change the limits (if you wish to do so)

Now to attach a handle to a struct you would do

call AttachStructDynamic(handle, integer database, struct)

and to retrieve the struct you would do

call GetAttachedStructDynamic(handle, integer database)

The integer database can be any integer, it is used similar to gamecache

***********************************************
* *
* CLEANING UP HANDLE INDEXES *
* *
***********************************************

I thought I would include this since the system is reliant on the handle index stack. As mentioned so many times before, it is absolutely that you, as much as is feasible, that you clean up handle index leaks.

This is done by simply setting LOCAL handles to null when you are done using them, for example if we have a look at the Crazy Ass Jump spell included in the map, you will notice in this function

JASS:
function Trig_Crazy_Ass_Jump_Actions takes nothing returns nothing
local jump j = jump.create()
local timer t = CreateTimer()
local location point = GetSpellTargetLoc()
local real x
local real y
set j.u = GetTriggerUnit()
set j.x = GetUnitX(j.u)
set j.y = GetUnitY(j.u)
set j.targetx = GetLocationX(point)
set j.targety = GetLocationY(point)
set x = (j.targetx - j.x)
set y = (j.targety - j.y)
set j.maxdistance = (SquareRoot(x*x + y*y))
set j.angle = bj_RADTODEG * Atan2(j.targety - j.y, j.targetx - j.x)
set j.increment = j.maxdistance * 0.025 * 1.55
call RemoveLocation(point)
set point = null    
call AttachStruct1(t,j)
call TimerStart(t,0.025,true, function TaurenMove)
set t = null
endfunction
Have a look at how on the second last line we set t= null, this needs to be done for every local handle that is created, you must null them once you are finished using them (convention is that this is done at the end of the function). You also need to do this with structs that contain any members that are handles using the onDestroy method. Yet again if we have a look at the same Crazy Ass Jump trigger in the jump struct

JASS:
struct jump
unit u
real x
real y
real z
real targetx
real targety
real maxdistance
real distance
real angle
real increment
real height
integer i = 0

method onDestroy takes nothing returns nothing
    set this.u = null
endmethod

endstruct
You will notice there is a method onDestroy which sets this.u to null (this.u refers to the current instance of the unit u). This is also quite important, because people also don't realise that each created struct leaks as many index's as you have members that are handles and if you dont clean them up it all adds up. You can also clean up multiple handles in the onDestroy if your struct has more then one handle for members

Note that you don't have to get fanatic and make 100% sure that EVERY handle index is cleaned up (in most cases this is not possible in more complicated maps). Now that you can specify the limit for both static and dynamic databases, you most likely will never go over the limit. The biggest area of concern is just mainly timers/loops, as they have the capability to leak handles incredibly fast. If you have a few leaks here and there that only happen once, then nothing is going to happen however if you have a spell that leaks 500 handles every cast because it uses a timer (very common situation) then after 50 casts of that spell, there goes a massive 25000 index's, if it goes above the limit the system will start using slow gamecache

In version 3.40 you can use Debug Mode to monitor the index handles. If you see that your handle index's are slowly increasing without any spells being cast or any user input it means that you are leaking somewhere. Run this map in debug mode and run the Crazzy Ass Jump test to have a look at what should be happening. Although the handles increase/decrease continuously, they never go above a maximum number, this is what should be hapenning in your map

Test Results

Attaching and Retrieving Structs through a single handle (timer)
HSAS = 75.497 Executions per millisecond
ABC = 63.515 Executions per millisecond
HAIL = 68.283 Executions per millisecond
GC = 62.512 Executions per millisecond

Attaching and Retrieving Structs through a multiple handles stored in an array (timer)
HSAS = 90.939 Executions per millisecond
ABC = 63.717 Executions per millisecond
HAIL = 68.510 Executions per millisecond
GC = 64.526 Executions per millisecond
 

Attachments

  • HSAS v3.60.w3x
    144.4 KB · Views: 263
Last edited:
Level 40
Joined
Dec 14, 2005
Messages
10,532
The "Attachment Storage Tests" (Multiple and Single) freeze my WC

Anyways, Crazy Ass Jumping Taurens were win.

The system looks pretty good, not something I would ever use (since I seem to have an objection to most systems not written by me, myself, and I) but that other people may find pretty useful.

~Approved~

I'll tell you if I have any other suggestions when I look over the various bits of code from time to time, but I really wish you would indent your stuff -.-
 
Level 3
Joined
Sep 4, 2007
Messages
49
I only indent when I find it hard to read or follow through, really this system is very simple however your right I should start indenting

Im not sure why the storage tests would freeze your pc, the static one takes a long time (around 2 minutes) because your storing and retrieving 25000+ structs
 
Level 3
Joined
Sep 4, 2007
Messages
49
There has been a pretty serious bug, it seems I got the first index incorrect (it has now been fixed in 3.2)

I also changed the
JASS:
 to [icode=jass] for single lines as requested
 
Level 3
Joined
Sep 4, 2007
Messages
49
UPDATE

there was a problem with multiple static databases no longer working, it has been fixed now (readme also has been updated)
 
Level 13
Joined
Nov 22, 2006
Messages
1,260
Just a minor spelling mistake:

Then when you want to store/retrieve data you would do this (using the example of 1) call AttachStruct1(handle,struct) and [icode=jass]call GetAttachedStruct1(handle)

should be:

Then when you want to store/retrieve data you would do this (using the example of 1) call AttachStruct1(handle,struct) and call GetAttachedStruct1(handle)

You just forgot to put [/icode]
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,198
Something looks wrong with the test results.
When using multiple handles the other systems spead up while yours went slower. What happens if even more handles are used for the test, surely then the results could end up with your system being slower than the others?
 
Level 3
Joined
Sep 4, 2007
Messages
49
Its nothing wrong, my system is still much faster. What multiple handle test does is create 10000 handles, and attaches a struct to each handle. This would be the least likely way the system is going to be used, it is more common that people will attach a struct to the same handle (such as a timer) and retrieve it numerouse times that way. The multiple handle test isnt really an accurate representation, as the majority of people when attaching/retrieving handles are concerned about how fast they retrieve the struct off a single handle (i.e. a periodic timer)

Even then the system is still a massive 35% faster on around 15000 different handles, if you had that many handles and attached a struct to every one of those handles then something weird is going on in your map
 
Level 13
Joined
Nov 22, 2006
Messages
1,260
You put //! runtextmacro HSAS(...) instead of //! runtextmacro HSAS_Static(...)

Running the textmacro makes a library, right? Then we can have two statics with the same number right, because the library puts it in the map header and it is reachable from anywhere, making it not private.

So if we have 4 or more spells in the map, we have to have more than 3 statics (you said we need 2-3 max).
 
Level 3
Joined
Sep 4, 2007
Messages
49
U can make as many as you want. Its that if you make too many the code in ur map can get kinda long, but in terms of memory and lagging it does nothing. If you have 4 spells in a map then you only need 1 static library. You only need more then 1 static library if you want to attach MORE then 1 struct to a handle
 
Level 13
Joined
Nov 22, 2006
Messages
1,260
You can use the same static library for multiple spells?

You said that if you need to attach more than 1 struct to a handle you can make a dynamic library, right? Then you only need one static and one dynamic library in a map.

Why is textmacro HSAS_Static run inside the library and HSAS_Dynamic outside it?

Isn't the purpose in these stuff to avoid game cache?
 
Level 3
Joined
Sep 4, 2007
Messages
49
It only resorts to gamecache if you have somehow used up 26000 handles and havent nulled them. Yes you can use the same static library for many spells, its only when you need to attach multiple structs to a single handle i.e. attach multiple structs to a timer for a spell. However in 90% of situations you will never need to attach more then a single struct to a single handle
 
Level 3
Joined
Sep 4, 2007
Messages
49
HSAS v3.40 came out, it now includes debugging options and the ability to scope static/dynamic libraries (local,public and global). Press re-read the usage trigger for more information
 
Level 3
Joined
Sep 4, 2007
Messages
49
HSAS v3.50 has just been released, you can now specify the limit instead of using the arbitrary 24570 enforced limit in previous versions, refer to the usage manual for more information
 
Level 3
Joined
Sep 4, 2007
Messages
49
I suggest you use HSAS, since you can specify any limit you want and it is much faster then either ABC or HAIL (ABC doesn't even attach to units anymore).

As long as you clean up the handle leaks most of the time you will be good to go
 
Level 12
Joined
Apr 27, 2008
Messages
1,228
:D
I have some interesting results. The results varied with 1-4 each time i run the speed tests but generally remained the same - GC being the fastest.
Now why would I get such results?

Btw I think that the global database(the one you used in the demo map) library should require/use/need the HSAS library.
P.s. one of the attached pictures is from the single struct attachment speed test and the other one is from the multiple ...
 

Attachments

  • Multiple Stucts attachment.JPG
    Multiple Stucts attachment.JPG
    46.2 KB · Views: 176
  • Single Struct attachment.JPG
    Single Struct attachment.JPG
    45.3 KB · Views: 182
Last edited:
Level 12
Joined
Apr 27, 2008
Messages
1,228
I just thought that the test results on page 1 were from the testing system that is in the demo map :p
 
Level 12
Joined
Apr 27, 2008
Messages
1,228
The code is the code from the demo map attached to this thread - your map.
Those results are from the tests you included.
I have made no changes at all to the map. Just opened it in WE and tested it.
But, yeah those results from above are with war3err enabled.
Here are the results with it disabled.
 

Attachments

  • Sin, no war3err.JPG
    Sin, no war3err.JPG
    42.1 KB · Views: 492
  • Mult, no war3err.JPG
    Mult, no war3err.JPG
    39.7 KB · Views: 475
Level 3
Joined
Sep 4, 2007
Messages
49
Disable wc3err, you NEVER have wc3err enabled when benchmarking, it has to pre process each custom function call and thats why gamecache appears on the top
 
Level 12
Joined
Apr 27, 2008
Messages
1,228
Yeah, I learned that(after I made the first post).
Is there something else that should be enabled/disabled that would increase the difference between HSAS' ans GM's speed ?
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,198
I advise this system be reviewed for functionality and compatibility with the upcomming version 1.24 patch. Currently, due to use of H2I double return bug which is being removed, I believe this system will not work come the update. Thus I advise that the creator of it checks for compatibility with 1.24 and updates if need be as it is pointless supplying a system which is unusable.
 
Level 11
Joined
Feb 22, 2006
Messages
752
I don't see why it wouldn't be compatible. Just switch from H2I to GetHandleId(), and StoreInteger() to SaveInteger() or w/e the hashtable equivalent is called.

Tho if hashtable is as fast as some people claim it is (i've heard only 2x slower than array lookup), this system might be obsolete unless you're a REAL speed freak.
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,198
He still has to update it to be compatible as in its current form it will be unusable even if it is not obsolete. Hashtables may not be as fast array lookups, but then again they have the advantage of being like 2D arrays with 2 signed 32 bit integer indexes. Thus they are not as resricted as normal array systems.

Anyway, I am not really arguing about weathor this system is useful or not, but about it being unsupported come the new patch. Although it is easilly changed to work with the new patch, that is not the point of these jass scripts. All jass scripts here should be usable the way they are presented with as minimal alterations as possiable. Weathor the author or you update it to be compatiable with 1.24 is not of any mater, as long as it gets done once the patch is out or this should be removed.
 
Top