System Caster a type cast library

weaaddar

New Member
Reaction score
6
Hi all,
Here is a typecast library that allows you to cast integers to agent types, and agents to other agents. (as promised from my graveyard-ed box)

The library is to help bridge old map to use the fogstate exploit, without alot of effort with a pretty clean syntax.
The syntax is the following::
CastInt[somevar].as_(agentType)
or
CastAgent[someagent].as_(agentType)

You can also .is_agenttype to test if the object is an agent.

There is also a configuration setting of speed mode. SPEEDMODE = true means that it'll inline all casts to Agent types, but won't clean up after itself. This shouldn't be a big concern at all. If you are using speed mode, and still care about memory, you can use the static method CastInt.flushCache(), the method doesn't have to be called for SPEEDMODE = false.

The performance penalty is obviously there for using this library, but if you are porting old code FuaxhandleVars and other macros may not be easy enough.

Here is the code::
JASS:
library Caster
{
   /*************************************************************************
    * Caster is a typecast library. It creates new syntax that allows
    * you to use operator abuse to do some nice typecasting code.
    * Caster brings 2 structs. CastInt and CastAgent.
    * constant config value SPEEDMODE
    *********************************
    * SPEEDMODE = true, all as_*agent* and is_*agent* methods will inline,
    * but won't clear the hashtable indexs they use.
    * Static Method index:
    **********************
    * CastInt[integer]-> CastInt
    * CastAgent[agent]-> CastInt
    *  -- These prep the integer/agent for use in being casted to other types.
    
    * CastInt.clearCache()
    * -- clears the cache that might be saved in castInt, only needed if you are
    * using SPEEDMODE = false.
    * Instance Method index:
    ***********************
    * as_integer -- returns the agent or integers handle id. (only for debug purposes)
    * as_*agent* -- returns the object casted as *agent* where agent is one of the agenttypes.
    * is_*agent* -- returns true if the object is *agent*, otherwise returns false.
    *
    
    * syntax examples::
    * CastInt[intvar].as_unit
    * CastAgent[Widget].as_item 
    *************************************************************************/

    hashtable Table = InitHashtable();
    constant boolean SPEEDMODE = true;
    public struct CastAgent[]
    {
        static method operator[](agent a)->CastInt
        {
            SaveAgentHandle(Table,0,GetHandleId(a),a);
            return CastInt(GetHandleId(a));
        }
    }
    public struct CastInt[]
    {
        static method operator[](integer index)->thistype
        {
            SaveFogStateHandle(Table,0,index,ConvertFogState(index));
            return thistype(index);
        }
        
        static method ClearCache()
        {
            FlushChildHashtable(Table,0);
        }
        
        method operator as_integer() -> integer
        {
            static if(SPEEDMODE)
                return this;
            else
            {
                RemoveSavedHandle(Table,0,this);
                return this;
            }
        }
        
        //! textmacro CasterTemplate takes TypeName,T
        method operator as_$T$() -> $T$
        {
            static if(SPEEDMODE)
                return Load$TypeName$(Table,0,this);
            else
            {
                $T$ retVal = Load$TypeName$(Table,0,this);
                RemoveSavedHandle(Table,0,this);
                return retVal;
            }
        }
        method operator is_$T$() -> boolean
        {
            return this.as_$T$ == null;
        }
        //! endtextmacro
        // You should remove the types you aren't going to use. It'll make your map load faster.
        // but keeping them all here allows for full functionality. 
        //! runtextmacro CasterTemplate("PlayerHandle","player")
        //! runtextmacro CasterTemplate("WidgetHandle","widget")
        //! runtextmacro CasterTemplate("DestructableHandle","destructable")
        //! runtextmacro CasterTemplate("ItemHandle","item")
        //! runtextmacro CasterTemplate("UnitHandle","unit")
        //! runtextmacro CasterTemplate("AbilityHandle","ability")
        //! runtextmacro CasterTemplate("TimerHandle","timer")
        //! runtextmacro CasterTemplate("TriggerHandle","trigger")
        //! runtextmacro CasterTemplate("TriggerConditionHandle","triggercondition")
        //! runtextmacro CasterTemplate("TriggerEventHandle","event")
        //! runtextmacro CasterTemplate("ForceHandle","force")
        //! runtextmacro CasterTemplate("GroupHandle","group")
        //! runtextmacro CasterTemplate("LocationHandle","location")
        //! runtextmacro CasterTemplate("RectHandle","rect")
        //! runtextmacro CasterTemplate("BooleanExprHandle","boolexpr")
        //! runtextmacro CasterTemplate("SoundHandle","sound")
        //! runtextmacro CasterTemplate("EffectHandle","effect")
        //! runtextmacro CasterTemplate("QuestHandle","quest")
        //! runtextmacro CasterTemplate("QuestItemHandle","questitem")
        //! runtextmacro CasterTemplate("DefeatConditionHandle","defeatcondition")
        //! runtextmacro CasterTemplate("TimerDialogHandle","timerdialog")
        //! runtextmacro CasterTemplate("LeaderboardHandle","leaderboard")
        //! runtextmacro CasterTemplate("MultiboardHandle","multiboard")
        //! runtextmacro CasterTemplate("MultiboardItemHandle","multiboarditem")
        //! runtextmacro CasterTemplate("TrackableHandle","trackable")
        //! runtextmacro CasterTemplate("DialogHandle","dialog")
        //! runtextmacro CasterTemplate("ButtonHandle","button")
        //! runtextmacro CasterTemplate("RegionHandle","region")
        //! runtextmacro CasterTemplate("FogModifierHandle","fogmodifier")
        //! runtextmacro CasterTemplate("HashtableHandle","hashtable")     
        
    }
}

And here is some old code from DT4a A4 before and after::
old code::
JASS:
function H2I takes handle h returns integer
    return h
    return 0
endfunction

function Hero_getBag takes unit hero returns item
    return GetStoredInteger(udg_gc,I2S(H2I(hero)),"m_bag")
    return null
endfunction

function Hero_getHolder takes unit hero returns unit
    return GetStoredInteger(udg_gc,I2S(H2I(hero)),"m_holder")
    return null
endfunction


//replaced code
JASS:
function H2I takes handle h returns integer
    return GetHandleId(h)
endfunction

function Hero_getBag takes unit hero returns item
    return CastInt[GetStoredInteger(udg_gc,I2S(H2I(hero)),"m_bag")].as_item
endfunction

function Hero_getHolder takes unit hero returns unit
    return CastInt[GetStoredInteger(udg_gc,I2S(H2I(hero)),"m_holder")].as_unit
endfunction


Changing code to use this is much easier then say replacing faux structs from circa 2006.
 

Nestharus

o-o
Reaction score
84
I fail to see the point or use in this.

I think about 6 or 7 people have tried to submit something exactly like this so far, and all of them were graveyarded.

Do you know why?

[ljass]GetHandleId[/ljass]
[ljass]hashtable[/ljass]


and that about sums it up.
 

weaaddar

New Member
Reaction score
6
Yes, new maps can easily use Hashtable and GetHandleId, but taking something like my old DT4a A4 and porting it to something that will work in 1.24c, to replace the hashtable and H2Is with GetHandleId is a tremendous effort. But doing something like::
JASS:
function Bag_getItem takes item bag,integer index returns item
    return GetStoredInteger(udg_gc,I2S(H2I(bag)),I2S(index))
    return null
endfunction

To this is much easier (for me anyway).
JASS:
function Bag_getItem takes item bag, integer index returns item
     return CastInt[GetStoredInteger(udg_gc,I2S(H2I(bag)),I2S(index))].as_item
endfunction


Besides after all, I'm sort of the founder of H2I (blizzard is the first to use the wrong handle return bug) and this fogstate thing.
 

Nestharus

o-o
Reaction score
84
#1-
What's up with the gamecache use?
[ljass]GetStoredInteger(udg_gc,I2S(H2I(bag)),I2S(index))[/ljass]


#2-
You know what you are typing is actually harder than what you could be typing right?

[ljass]call SaveItemHandle(myHashTable, GetHandleId(myItem), 0, myItem)[/ljass]
[ljass]call LoadItemHandle(myHashTable, myHandleId, 0)[/ljass]


#3-
The comparison?
[ljass]CastInt[GetStoredInteger(udg_gc,I2S(H2I(bag)),I2S(index))].as_item[/ljass]
[ljass]LoadItemHandle(myHashtable, GetHandleId(bad), I2S(index))[/ljass]

Winner
plain hashtable
 

weaaddar

New Member
Reaction score
6
Thats more work, Nes, the point is not to recode an old library that uses lots of function to use hashtable especially when it comes to thing concats "m_bag_"+I2S(something).

Rewriting things to use HT can be very difficult when code isn't pretty, first thing to do is use something like a typecast library to get it to compile in 1.24c, then to switch to a struct (if you want to get the performance back up).

Nes, what I'm typing isn't hard as your example is nonsense, I already have ~50 old gamecache usage so converting to hashtables is more typing. But adding a caster call is less effort as I don't have to change the structuring of data from gc to hashtable. It'll be slower, but DT4a wasn't about super fast.
 

Nestharus

o-o
Reaction score
84
Thats more work, Nes, the point is not to recode an old library that uses lots of function to use hashtable especially when it comes to thing concats "m_bag_"+I2S(something).

Rewriting things to use HT can be very difficult when code isn't pretty, first thing to do is use something like a typecast library to get it to compile in 1.24c, then to switch to a struct (if you want to get the performance back up).

Nes, what I'm typing isn't hard as your example is nonsense, I already have ~50 old gamecache usage so converting to hashtables is more typing. But adding a caster call is less effort as I don't have to change the structuring of data from gc to hashtable. It'll be slower, but DT4a wasn't about super fast.

Just saying that these are hashtable wrappers and they are inefficient ones at that. Also, it's just as easy to use plain hashtables.. I mean I could understand if this did indexing in the background for structs... but as all it literally does is return a hashtable val : |...
 

Jesus4Lyf

Good Idea™
Reaction score
397
Besides after all, I'm sort of the founder of H2I
SuperIKI?

Um. I'm gonna say exactly what I said last time everyone pretended the return bug was ok. Just because you can do it, doesn't mean Blizzard won't remove it. People on this forum will tell you I faught hard against return bug use.

My current belief is that the fogstate stuff doesn't belong in hashtables, because they are not agents, and hence Blizzard could remove the associated natives at any point. :)

PS. We kind of already have this, should suggest an update to that resource rather than make a new one...
 

weaaddar

New Member
Reaction score
6
Actually, it was some IRC thing where we discovered that there was a blizzard.j function with the wrong return type. From there he wrote something like
JASS:
function Handle2Int takes handle h returns integer
if(true)then
return h
endif
return 0
endfunction

And Zephyr and myself discovered that the if-then-else was unneccessary and I just chose the name H2I :)

While what you say might be true, other non-agent types (other things that aren't agent) can be casted around through this exploit. All handle types seem to be stored in the same bucket. Using SaveFogStateHandle with a H2I(triggeraction) for instance, lets you retrieve a triggeraction and other simmilar abuses.
 

weaaddar

New Member
Reaction score
6
Don't remember, but you can diff your 1.23b blizzard.j and 1.24c blizzard.j and beside the hashtable wrappers the other differences should be this function.

Also unittypeid and itemtypeid were once typedefs of integer but they are gone now, really wierd.
 
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