| 09-17-2008, 05:01 AM | #1 |
I've been away from the Jass world for a long time (about a year) and I'm working on a project from way back when. This project makes use of numerous handle functions (H2I, SetHandleHandle, SetHandleInt, SetHandleBoolean, SetHandleReal, etc. etc.) to control handles and all that jazz. Are handles still used regularly? Have their functions changed in the last year (or are my old ones the same as what is 'current')? |
| 09-17-2008, 05:27 AM | #2 |
Most people use Structs to do all that now, and just attach the structs (as integers) to timers, and retrieve them as such. No more I2H bugs, or whatever. It's also far cleaner, since you don't need to call a bunch of SetHandleBlah/GetHandleBlah stuff. |
| 09-17-2008, 10:59 AM | #3 | |
Quote:
Mostly replaced by SetBlahStructBlah.. |
| 09-17-2008, 11:50 AM | #4 |
Or a simple create method. |
| 09-17-2008, 12:27 PM | #5 |
Handles are still used...you can't avoid using handles in WC3...units, groups, locations, etc, are all handles. Then there are pseudo handles like lightning. Anyway, handle variables like KaTaNNa's system are no longer used due to bugs with I2H, etc., and advances, primarily with vJASS through a preprocessor. Legacy support for avoiding the I2H issues is available through a KaTaNNa replacement library I made (search my threads in here), but it's slow, so really not recommended for new code. Also, we no longer destroy triggers (dynamic triggers are out), and nor do we destroy groups (static groups) or timers (which we recycle). DestroyTrigger bugs (can cause multiple units to be on the same variable), groups leak if they are destroyed after being enumed (oh, and always enum with a boolexpr that isn't null, or that leaks every single enum), and timers are also dodgy when destroying them. |
| 09-17-2008, 12:52 PM | #6 |
I still have not seen why destroying triggers is always bad. |
| 09-17-2008, 01:31 PM | #7 | |
Quote:
But can you completely and effectively replace them with the new struct systems? |
| 09-17-2008, 03:10 PM | #8 |
Lol, how are you going to replace units with structs? Some data structures such as groups and locations could be sometimes replaced with structs, but it's much slower, and you still have to deal with them when you are using natives that expect handles. |
| 09-17-2008, 03:41 PM | #9 |
So if Katanna's handle system isn't being used, what is? Even a link to the post where I can read up on it myself would be wonderful. |
| 09-17-2008, 03:56 PM | #10 | |
Quote:
|
| 09-17-2008, 04:15 PM | #11 |
Sorry for the long bit of code. Tried searching a bit for a post on current handle functions, just copy/pasted this from my old project. These are the 'current' ones in use, yes? Thanks in advance Vex (and everyone!) JASS:// =========================== function H2I takes handle h returns integer return h return 0 endfunction // =========================== function LocalVars takes nothing returns gamecache // Replace InitGameCache("jasslocalvars.w3v") with a global variable!! return InitGameCache("jasslocalvars.w3v") endfunction function SetHandleHandle takes handle subject, string name, handle value returns nothing if value==null then call FlushStoredInteger(LocalVars(),I2S(H2I(subject)),name) else call StoreInteger(LocalVars(), I2S(H2I(subject)), name, H2I(value)) endif endfunction function SetHandleInt takes handle subject, string name, integer value returns nothing if value==0 then call FlushStoredInteger(LocalVars(),I2S(H2I(subject)),name) else call StoreInteger(LocalVars(), I2S(H2I(subject)), name, value) endif endfunction function SetHandleBoolean takes handle subject, string name, boolean value returns nothing if value==false then call FlushStoredBoolean(LocalVars(),I2S(H2I(subject)),name) else call StoreBoolean(LocalVars(), I2S(H2I(subject)), name, value) endif endfunction function SetHandleReal takes handle subject, string name, real value returns nothing if value==0 then call FlushStoredReal(LocalVars(), I2S(H2I(subject)), name) else call StoreReal(LocalVars(), I2S(H2I(subject)), name, value) endif endfunction function SetHandleString takes handle subject, string name, string value returns nothing if value==null then call FlushStoredString(LocalVars(), I2S(H2I(subject)), name) else call StoreString(LocalVars(), I2S(H2I(subject)), name, value) endif endfunction function GetHandleHandle takes handle subject, string name returns handle return GetStoredInteger(LocalVars(), I2S(H2I(subject)), name) return null endfunction function GetHandleInt takes handle subject, string name returns integer return GetStoredInteger(LocalVars(), I2S(H2I(subject)), name) endfunction function GetHandleBoolean takes handle subject, string name returns boolean return GetStoredBoolean(LocalVars(), I2S(H2I(subject)), name) endfunction function GetHandleReal takes handle subject, string name returns real return GetStoredReal(LocalVars(), I2S(H2I(subject)), name) endfunction function GetHandleString takes handle subject, string name returns string return GetStoredString(LocalVars(), I2S(H2I(subject)), name) endfunction function GetHandleUnit takes handle subject, string name returns unit return GetStoredInteger(LocalVars(), I2S(H2I(subject)), name) return null endfunction function GetHandleTimer takes handle subject, string name returns timer return GetStoredInteger(LocalVars(), I2S(H2I(subject)), name) return null endfunction function GetHandleTrigger takes handle subject, string name returns trigger return GetStoredInteger(LocalVars(), I2S(H2I(subject)), name) return null endfunction function GetHandleEffect takes handle subject, string name returns effect return GetStoredInteger(LocalVars(), I2S(H2I(subject)), name) return null endfunction function GetHandleGroup takes handle subject, string name returns group return GetStoredInteger(LocalVars(), I2S(H2I(subject)), name) return null endfunction function GetHandleLightning takes handle subject, string name returns lightning return GetStoredInteger(LocalVars(), I2S(H2I(subject)), name) return null endfunction function GetHandleWidget takes handle subject, string name returns widget return GetStoredInteger(LocalVars(), I2S(H2I(subject)), name) return null endfunction function FlushHandleLocals takes handle subject returns nothing call FlushStoredMission(LocalVars(), I2S(H2I(subject)) ) endfunction |
| 09-17-2008, 08:53 PM | #12 |
Not really. SetHandleInt/GetHandleInt could still be used if you don't need 100% top notch speed, but attaching handles (units, timers, triggers, effects, etc.) is a no-no by that method, since it uses (inlined) I2H, which can cause issues. There are different methods of attaching (oh so many). For legacy code, I made a system to replace that code (KaTaNNa's system) with the same API; since you've got a variation from the version at wc3jass, you'll need to tweak it a big, but nothing too hard. New code should use one of the attachment systems in our database. Attachment to timers can be done via TimerUtils (which also has timer recycling - highly recommended), units you could use an indexing system like PUI or just attach, possibly with H2I and a hash / big arrays. Or just SetHandleInt. Really you want to be attaching structs for most cases (ie: one int). |
| 09-17-2008, 09:03 PM | #13 |
Well at the moment my implementation doesn't hardly make use of the handles at all (mainly because I don't have much of the JASS done yet) so now is the time to completely replace it with one of the new systems we're using. How does attachment to timers work, specifically? And if I use something like TimerUtils would I also need an indexing system like PUI for units? Or can I attach units to timers using TimerUtils? |
| 09-17-2008, 11:02 PM | #14 | |
Quote:
You can store the unit in a struct, then attach that to the timer (and retrieve it later) e.g. JASS:struct MyData unit someUnit //You can put the rest of your stuff that needs to be passed to the timer function in here as well endstruct function Callback takes nothing returns nothing local timer t = GetExpiredTimer () local MyData d = GetTimerData (t) //I forget the precise function name call DoSomeStuffWithUnit (d.someUnit) //Poof, we've got the Triggering Unit from the Start function =D call ReleaseTimer (t) set t = null endfunction function Start takes nothing returns nothing local MyData d = MyData.create () local timer t = NewTimer () set d.someUnit = GetTriggerUnit () call SetTimerData (t, d) //I forget the order of arguments ^_^ call TimerStart (t, INTERVAL, false, function Callback) set t = null endfunction |
| 12-29-2008, 10:49 AM | #15 | |
Quote:
We don't need to destroy them or what ? |
