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::
And here is some old code from DT4a A4 before and after::
old code::
//replaced code
Changing code to use this is much easier then say replacing faux structs from circa 2006.
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.