System TMAAS (Textmacro Abusing Attachment System)

Gwypaas

hook DoNothing MakeGUIUsersCrash
Reaction score
50
Why should you use this?
You should use this because it's safe and because it's really as fast as you can get it but still safe.
This is safe because it works until your (handle amount - Your handles at start > 400 000) which is pretty extremely high.

JASS:
//*******************************************************
//*                                                     *
//*         Textmacro Abusing Attachment System         *
//*                      TMAAS v1.2                     *
//*                     By: Gwypaaas                    *
//*_____________________________________________________*
//*                      About                          *
//* This system uses H2I to store the value into an     *  
//* array. This system is very fast if the ID the       *
//* system uses is less then 8191, otherwise it stores  *
//* your struct into a premade array with 409550 size.  *
//*_____________________________________________________*
//*                                                     *
//*                       Usage                         *
//*                                                     *
//* Create a new trigger named "TMAAS" and paste all    *
//* this code into it. When you use this system remember*
//* that you cannot use associations to the attached    *
//* struct until after the textmacro. Also, you cannot  *
//* use the textmacro before the locals since that      *
//* will cause a syntax error.                          *
//*                                                     *
//*   The usage of the Textmacros is explained below.   *
//* ____________________________________________________*
//*
//*
//*
//* This system contains these macros:
//* 
//* //! runtextmacro TMAAS_Attach ("<Name of Handle variable>", "<Name of struct variable>")
//* //! runtextmacro TMAAS_Get ("<Name of Handle variable>", "<To which variable the attachment should be set>")
//*
//*
//*
//* Pros:
//*    Really fast because it is inlined
//*    Pretty handle safe since it decreases the handle amount that is in the map at time 0.0
//* Cons:   
//*    Can't get the variable without the use of a textmacro, 
//*    therefore you can't use the struct in the local declaration.
//*    
//*******************************************************
library_once TMAAS initializer init
globals
    public integer DECREASE = 0x100000
    public integer array DATAZ
    public integer array DATAZBIG[409550]
    
    public integer Temp
endglobals

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

//! textmacro TMAAS_Attach takes HANDLE, STRUCT
    set TMAAS_Temp = TMAAS_H2I($HANDLE$) - TMAAS_DECREASE
    if TMAAS_Temp < 8191 then
        set TMAAS_DATAZ[TMAAS_Temp] = $STRUCT$
    else
        set TMAAS_DATAZBIG[TMAAS_Temp] = $STRUCT$
    endif
//! endtextmacro

//! textmacro TMAAS_Get takes HANDLE, STRUCT
    set TMAAS_Temp = TMAAS_H2I($HANDLE$) - TMAAS_DECREASE
    if TMAAS_Temp < 8191 then
        set $STRUCT$ = TMAAS_DATAZ[TMAAS_Temp]
    else
        set $STRUCT$ = TMAAS_DATAZBIG[TMAAS_Temp]
    endif
//! endtextmacro


private function SetDecrease takes nothing returns nothing
    set TMAAS_DECREASE = TMAAS_H2I(CreateTrigger())
endfunction

private function init takes nothing returns nothing
    call TimerStart(CreateTimer(), 0.00, false, function SetDecrease)
endfunction
endlibrary



Changelog
v 1.2 - Rewrote the init function so it didn't need to create any trigger. Improved documentation.
v 1.1 - Made everything public so it won't collide with something else and made it use library_once so you can't import 2 systems.
v 1.0 - Initial Release
 

Attachments

  • TMAAS.w3x
    23.8 KB · Views: 182

Trollvottel

never aging title
Reaction score
262
This is safe because it works until your handle amount > 400 000 (Which is pretty extremely high.)

if you forget to null handles, it will slow down and slow down and so on? and i think, CSData also works until a high number of instances, so i would like to see benchmarking. (vs GameCache, ABC, CSData, HSAS)
 

Gwypaas

hook DoNothing MakeGUIUsersCrash
Reaction score
50
Your map breaks down FAR before that value and this can actully store more since it decreases the handles ID with (0x100000 + Your handle amount at time 0).

And it's not to null handles, that leaks almost nothing but if you forget to remove them then this could eventually braek.
 

Romek

Super Moderator
Reaction score
963
This seems to work nearly the same as HSAS and HAIL.
Any benchmark results?

So many people are making systems that have been made before... Especially their own 'better than the rest struct attachment', which in reality isn't really.

JASS:
set DECREASE = (TMAASH2I(CreateTrigger())-0x100000) + DECREASE

Shouldn't that be:
JASS:
set DECREASE = (TMAASH2I(CreateTrigger())-DECREASE) + DECREASE

Or better yet:
JASS:
set DECREASE = (TMAASH2I(CreateTrigger()))


How exactly would I use the struct once I used the Get macro?
You can't exactly do
JASS:
set MyStruct = TMAASGET("blah", "blah")


Maybe you could add another argument to the textmacro. The struct attached is set to a variable with that name.

I'm also not a real fan of textmacros... But that's just personal opinion.
 

Gwypaas

hook DoNothing MakeGUIUsersCrash
Reaction score
50
This seems to work nearly the same as HSAS and HAIL.
Any benchmark results?

So many people are making systems that have been made before... Especially their own 'better than the rest struct attachment', which in reality isn't really.
I made this because I got the idea and I thought like, why not try it, noone else has done it this way before.

JASS:
set DECREASE = (TMAASH2I(CreateTrigger())-0x100000) + DECREASE

Shouldn't that be:
JASS:
set DECREASE = (TMAASH2I(CreateTrigger())-DECREASE) + DECREASE
No it shouldn't since "DECREASE" isn't a constant value but 0x100000 is.
Or better yet:
JASS:
set DECREASE = (TMAASH2I(CreateTrigger()))
That wouldn't work at all. Or maybe it would but.. I'm not sure.

How exactly would I use the struct once I used the Get macro?
You can't exactly do
JASS:
set MyStruct = TMAASGET("blah", "blah")


Maybe you could add another argument to the textmacro. The struct attached is set to a variable with that name.
You use it like this:
JASS:
function blah takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local myStruct ms
    //! runtextmacro TMAASGet("t", "ms") 
endfunction

When that would set the value stored to "t" into the "ms" struct.

I'm also not a real fan of textmacros... But that's just personal opinion.
I made this to be fast, not modular :)
 

Romek

Super Moderator
Reaction score
963
I made this because I got the idea and I thought like, why not try it, noone else has done it this way before.
Yes they have. As I said before, HSAS and HAIL function nearly exactly the same as this. Except you create the set of functions with a single textmacro. So you don't need to keep using textmacros.

That wouldn't work at all. Or maybe it would but.. I'm not sure.
Yes it would. And there really isn't a reason why you shouldn't do it like that.

You use it like this:
JASS:

function blah takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local myStruct ms
    //! runtextmacro TMAASGet("t", "ms") 
endfunction

When that would set the value stored to "t" into the "ms" struct.


I made this to be fast, not modular :)
Benchmarks?
 

Gwypaas

hook DoNothing MakeGUIUsersCrash
Reaction score
50
Check out the code that this process and the code that Timerutils, HSAS, HAIL processes.

The only system I can see that is faster is CSData but this is CSData + an if the check if your handle amount is less then 8191, if it's bigger then this is a little bit slower then timerutils (blue) because of the extra if.
 

Romek

Super Moderator
Reaction score
963
We prefer benchmark results, not a guess looking at some code.

Anyway, from your guess, why would this be faster than HSAS and HAIL?

(We still want benchmarks :D)
 

Gwypaas

hook DoNothing MakeGUIUsersCrash
Reaction score
50
HSAS Get function:
JASS:
$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


HAIL Get function:
JASS:
        $scope$ function Get$name$ takes handle h returns $type$
            local integer i = HAIL_H2I(h) - HAIL_FIRST_HANDLE_INDEX
            if HAIL_handles<i> != h and HAIL_counts<i> != 0 then
                set i = HAIL_GetIndex(h, i, false)
            endif
            return HAIL$name$val<i>
        endfunction
</i></i></i>


My inlined Get code.
JASS:
    set TMAASTemp = TMAASH2I($HANDLE$) - DECREASE
    if TMAASTemp &lt; 8191 then
        set $STRUCT$ = TMAASDATAZ[TMAASTemp]
    else
        set $STRUCT$ = TMAASDATAZBIG[TMAASTemp]
    endif


Pros of mine:
Inlined = faster
Less code = Faster
 

Azlier

Old World Ghost
Reaction score
461
You can't be sure that less code is faster... A lot of the time, BJ's shorten code by calling 1+ natives to do the dirty work. It makes the code shorter, but not faster in the least.
 

Romek

Super Moderator
Reaction score
963
...Benchmarks? -.-"

Also, is there any reason why you're using 2 different arrays (One of them over-sized)?
The oversized array will never use indices 0-8191, which is a bit of a waste.
That's an entire array.

Don't say it's faster, because oversized arrays do something like this:
JASS:
if index &lt; 8191 then
return ARRAYA[index]
elseif index &lt; 16382 then
return ARRAYB[index-8191]
//etc.
endif


So, if the index is below 8191, it uses only 1 if-condition check. Otherwise it uses more.
You're using an if inside the actual function. So the speed remains basically the same.

It could actually lower the speed for the larger indices...
 

Gwypaas

hook DoNothing MakeGUIUsersCrash
Reaction score
50
I use 2 arrays for speed, the smaller when your handle amount is low, the big when your handle amount is big for safety so it doesn't break down when the amount increases.

You can't be sure that less code is faster... A lot of the time, BJ's shorten code by calling 1+ natives to do the dirty work. It makes the code shorter, but not faster in the least.
If you compare the 3 different ways, then you see that my way uses the least amount of locals, calls and it doesn't need to jump into a function and return it's value.
 

Romek

Super Moderator
Reaction score
963
I use 2 arrays for speed, the smaller when your handle amount is low, the big when your handle amount is big for safety so it doesn't break down when the amount increases.
I would appreciate it if you actually read my post properly.

If you compare the 3 different ways, then you see that my way uses the least amount of locals, calls and it doesn't need to jump into a function and return it's value.
Maybe. I still want to see benchmarks.
Also, your system makes peoples code look quite ugly.
Normal Systems:
JASS:
local Data d = GetSomeData(GetExpiredTimer())
local integer A = d.a + 5
local integer B = d.b
local real C = d.c
local real D = d.c + d.a + d.b


Your System:
JASS:
local Data d
local integer A
local integer B
local real C
local real D

//! runtextmacro TMAASGet (GetExpiredTimer(), d)

set A = d.a + 5
set B = d.b
set C = d.c
set D = d.c + d.a + d.b


...And that's only with 4 locals. Many spells use much more than that.
 

Gwypaas

hook DoNothing MakeGUIUsersCrash
Reaction score
50
This system is made for speed, not for nice looking as I said before.
 

Flare

Stops copies me!
Reaction score
662
Neat way of setting DECREASE (shame that it can't be made constant though, let's just hope people won't be idiotic about it :))

Usage seems a bit confusing though (perhaps you could add that example you posted to the first post, would be a great help)

This seems to work nearly the same as HSAS and HAIL.
Nearly the same as HAIL? Ahm, no it doesn't... have you even looked at the code for HAIL? It's somewhat similar to HSAS (far from 'nearly the same' though, mainly due to HSAS' gamecache usage when the fast array is full, and multi-dimensional arrays)

So many people are making systems that have been made before... Especially their own 'better than the rest struct attachment', which in reality isn't really.
And your point? Do you have an issue with people wanting to make their own systems, even if it's already done before? And to be honets, there's no 'better' system, since every system does have it's advantages and disadvantages, and people have personal preference which, to be honest, is what should come first since speed differences are rarely noticeable.

A lot of the time, BJ's shorten code by calling 1+ natives to do the dirty work
Well, that's BJ's calling (multiple) natives, this is just a single function call and setting a variable - can't really compare them that way :\ BJ's are short, but they are doing work that the native is already capable of doing. This is short, but it's only doing what it has to

It could actually lower the speed for the larger indices...
That's assuming you go outside the fast array bounds which, if you are any way capable of nulling things, shouldn't happen and, as such, system maintains whatever speed it has
 

Romek

Super Moderator
Reaction score
963
Nearly the same as HAIL? Ahm, no it doesn't... have you even looked at the code for HAIL? It's somewhat similar to HSAS (far from 'nearly the same' though, mainly due to HSAS' gamecache usage when the fast array is full, and multi-dimensional arrays)
Well, I remember that both of them simply took away 0x100000 from the handle indexes and set them. And I also remember that both of them where very similar. Seeing as this does that too, I said it was similar.

And your point? Do you have an issue with people wanting to make their own systems, even if it's already done before? And to be honets, there's no 'better' system, since every system does have it's advantages and disadvantages, and people have personal preference which, to be honest, is what should come first since speed differences are rarely noticeable.
I think there isn't a point in getting more of the same thing.
Yes, we have many of them, and yes people have different preferences, but when there are so many of them, it's a bit silly.

That's assuming you go outside the fast array bounds which, if you are any way capable of nulling things, shouldn't happen and, as such, system maintains whatever speed it has
But, it still makes it slower.
And it doesn't affect the speed in any way for the 'fast' array.
Seeing as this system focuses mainly on speed, that should probably be changed.
 

Gwypaas

hook DoNothing MakeGUIUsersCrash
Reaction score
50
All I say is, compare an if and an if + function call, then tell me which is fastest. The single if is always faster no matter what.
 

Flare

Stops copies me!
Reaction score
662
Well, I remember that both of them simply took away 0x100000 from the handle indexes and set them. And I also remember that both of them where very similar. Seeing as this does that too, I said it was similar.
From what I recall (and I've used HAIL since about v1.02 I think), HAIL has always used a hash table (hence the neccesity for using the Reset functions, to keep space available in the table). HSAS uses the H2I - 0x000000, until you've exceeded the array limit, then it goes to GC (if you're using a static variant), not sure how the dynamic variant works

I think there isn't a point in getting more of the same thing.
Yes, we have many of them, and yes people have different preferences, but when there are so many of them, it's a bit silly.
It's something different, and there's nothing stopping them, so there's no good reason to whine about it (if this was a carbon copy of something else, fair enough, but as it is now, it's different both visually and code-wise). Nobody is asking you to use the system...

And it doesn't affect the speed in any way for the 'fast' array.
It doesn't make it faster, as such, it just prevents it from being slower (since you don't have to go into the oversized array values)

And to be honest, what's the big fucking whoop about speed? Sure, it's all well and good to have something fast, but will it ever be noticed in-game? Unless the system being used sucks ass, then no it won't and will the player care? NO THEY DON'T. They play maps for that exact reason - TO PLAY. They don't play maps to benchmark people's codes and do they even give a toss about the code? Highly unlikely

If you're so bloody interested in speed, maybe WC3C is the place for you

JASS:
local Data d
local integer A
local integer B
local real C
local real D

//! runtextmacro TMAASGet (GetExpiredTimer(), d)

set A = d.a + 5
set B = d.b
set C = d.c
set D = d.c + d.a + d.b

And? May be a bit of extra work, but it's not going to break the game to not initialize your variables when declaring them... it's a little extra work, sure, but if you like the system and are accustomed to it, you will get over it
 

Romek

Super Moderator
Reaction score
963
From what I recall (and I've used HAIL since about v1.02 I think), HAIL has always used a hash table (hence the neccesity for using the Reset functions, to keep space available in the table). HSAS uses the H2I - 0x000000, until you've exceeded the array limit, then it goes to GC (if you're using a static variant), not sure how the dynamic variant works
Well, I apologize. I've never used neither of them, and I briefly looked over the code.

And to be honest, what's the big fucking whoop about speed? It's all well and good to have something fast, but will it ever be noticed in-game? Unless the system being used sucks ass, then no it won't and will the player care? NO. They play maps for that exact reason - TO PLAY. They don't play maps to benchmark people's codes and do they even give a toss about the code? Highly unlikely

If you're so bloody interested in speed, maybe WC3C is the place for you
No need to start flaring up so much!
I mentioned speed because in the first post, the system's biggest PRO is it's speed. I actually agree that speed doesn't make much difference, which is why I stick to the easiest, and nicest systems.
Before all the newer attachment systems, people used GameCache, which is considered ridiculously slow by todays standards. Even so, it worked, and the speed of it was unnoticeable in-game.

If usability matters so much, then this system doesn't win much. It's quite annoying, and ugly to write the following all the time.
JASS:
local Data d
local integer A
local integer B
local real C
local real D

//! runtextmacro TMAASGet (GetExpiredTimer(), d)

set A = d.a + 5
set B = d.b
set C = d.c
set D = d.c + d.a + d.b

And? May be a bit of extra work, but it's not going to break the game to not initialize your variables when declaring them... it's a little extra work, sure, but if you like the system and are accustomed to it
It obviously won't break the game, but it does make code ugly and long (In my opinion).
If you like it, then that's up to you.
 

Flare

Stops copies me!
Reaction score
662
but it does make code ugly and long
If I use the system for my own map (lol, my own map :D), will you ever see the code? Probably not. Will you be affected by the ugliness and length? Again, probably not. In the end, it's rarely going to make a difference to anyone but the end-user, and there's nothing forcing you to use it if you think it's too ugly

No need to start flaring up so much!
Excusing the pun, flaring up? I'm trying to make the point (since, regardless of your supposed standpoint on speed, you've mentioned the word benchmark in all but one post in this thread, said one post being your latest one), and nice-and-quiet, for me, never works to get a point across.

Anyway, it doesn't take a genius to figure out a reasonable guess as to the system's speed - considering the methodology is similar to that of CSData (i.e. H2I - 0x00000 and chucking the value into that array index), and CSData is one of the fastest systems there, it's a matter of putting two and two together. There's nothing radically different in the method employed, so speed-wise, it seems logical that it'd be along the same lines as CSData, or TimerUtils (blue). Whether it's faster or slower than CSData is questionable, but it's not really that important
 
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