| 12-08-2009, 04:28 AM | #1 |
Caster is a library to facilitate typecasting and move old code over to new system without great deals of effort and clean syntax. It can also be used in modern maps that are okay with suffering performance penalties, like for test code. Zinc://! zinc 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") } } //! endzinc Here is some old DT4a A4 code to show how to replace old syntax with new cleaner syntax that might inline and won't be horrible:: 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 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 Which compiles to:: Zinc:function Hero_getBag takes unit hero returns item return (LoadItemHandle(Caster__Table, 0, (s__CastInt__staticgetindex(GetStoredInteger(udg_gc, I2S((GetHandleId((hero)))), "m_bag"))))) // INLINED!! endfunction function Hero_getHolder takes unit hero returns unit return (LoadUnitHandle(Caster__Table, 0, (s__CastInt__staticgetindex(GetStoredInteger(udg_gc, I2S((GetHandleId((hero)))), "m_holder"))))) // INLINED!! endfunction This is probably the easiest way to translate all old abusers and if you are using speed mode it'll translate pretty cleanly. |
| 12-08-2009, 05:32 AM | #2 |
We can't endorse I2H in the database... We are trying to move people away from it, not give them a reason to keep using it. I can move this to the T&S forum and leave it there as a link for people who need it, but I really can't let this slip into the script database like some supported library for reasons I hope are obvious. |
| 12-08-2009, 06:49 AM | #3 |
I agree. I'm using it as a clutch to help translate an old map. Its a debug script and obviously not something you should be using for a resource, but if you want an old map to work without much pain this is better then recoding to use modern facilities like hashtables, GetHandleId, and structs. You can move to T&S if you must. |
| 12-08-2009, 01:06 PM | #4 |
Okay cool, glad we agreed. Moved. :) |
