| 10-02-2007, 03:22 AM | #1 |
Ok, this is an issue I had in a previous post, and it seems it comes up alot in my style of jass. The basic issue is, if you use one timer to loop through several instances of something (Say a spell), how do you know when your spell is done through the timer loop? Sure you could make a struct, have a certain id attached to it, loop through with TriggerSleepAction until a boolean in your struct has been flagged, but that destroys the point of using a timer (Accuracy). What I'd like to do is pause my calling trigger's thread (Only possible via TriggerSleepAction() is seems) and unpause the calling trigger's thread when I'm done. However, there's no such way to resume from a TriggerSleepAction, or to pause your trigger. So, I'm rather stuck. How do you create a callback for a timer using vJass? I'm hopeless, I know . Thanks for any help. |
| 10-02-2007, 03:24 AM | #2 |
Use ExecuteFunc and temp globals, I'd say. |
| 10-02-2007, 03:57 AM | #3 | ||
Quote:
Not too related to vJass.. Quote:
|
| 10-02-2007, 06:15 AM | #4 |
I can't have a final part, I'm using this for an API, it needs to return after finishing because I don't know what the user wants to be the 'final part'. The only alternative I've come up with is saving a trigger in my struct and executing it, but that'd mean switching between several triggers, which may not even be possible depending on the situation. I really don't see much of a solution to this unfortunantly, I may have to revert to using handle vars -,-. Why coulden't blizzard have implemented just a few more natives damnit >.<. |
| 10-02-2007, 07:09 AM | #5 |
You are simply doing something wrong.... I suggest you change your programming approach. |
| 10-02-2007, 07:47 AM | #6 |
Well I can't get around the issue that I need a timer, if I use trigger sleep action, it won't be accurate waiting periods, not to mention it's bad practice. (Not to mention is hard to mult-instance) The only way I can actualy use this is if I have a callback from a timer. The problem is using globals, I have absolutely no idea how I'd do this. On another note, the only issue I have is that my timer is running and if I wait for it to stop, it's possible I'm going to wait to long (if several things are being processed, it wont end until all of them have been) Additionaly, and type of global structure or anything requires I continuously check to see if it's been updated. Basicaly, timers are the end of my thread with no possible way to exit out of them with accurate timing. Handle vars has the same problem, but you can attach a variable to a timer, so you end up with the ability to wait for the timer. Globals has no such nicety it seems. (I just said the same thing twice didin't I?) Maybe I'll do something incredibly stupid, that usualy works. *Starts making a polled wait loop, screw efficiency!* Or maybe TriggerWaitForSound would work if I used a null sound file.. Hmm? I could create a global callback id and send it to my function to begin it, and have my trigger wait for a null sound afterwards... Brilliant! I'll get on it. Haha, improvisation, blizzard always makes a way! God I hope this works... |
| 10-02-2007, 10:26 AM | #7 | |
Quote:
That's why you have the user pass a callback function that gets called after finishing. |
| 10-02-2007, 01:00 PM | #8 |
What you are trying to do is not possible Blackroot, otherwise people would have already made an accurate wait function by now. |
| 10-02-2007, 01:24 PM | #9 | |
Quote:
|
| 10-02-2007, 07:21 PM | #10 |
I misunderstood what he needed, Vex. I thought he needed to iterate though N instances of a struct and then call a function each time that had a wait in it... but that he wanted the wait to happen simultaneously instead of having a wait before going to the next instance. |
| 10-02-2007, 11:44 PM | #11 | |
Quote:
If nothing else, that may be my only option. |
| 10-03-2007, 04:08 AM | #12 |
Well I give up. This was the only option I could use. Even if I passed a function to execute, It would wait for it to finish, and if I used ExecuteFunc i coulden't pass function arguments. So, here's my surrenderence, blizzard. JASS://! library cast function CastString takes real r returns string local string e = "" local integer i = 0 loop set e = e + "*" set r = r - .1 exitwhen(r <= 0) endloop return e endfunction function BC_CancelledCast takes real x, real y returns nothing local texttag ct = CreateTextTag() call SetTextTagPermanent(ct, false) call SetTextTagPos(ct, x, y, BASE_TEXTTAG_SIZE) call SetTextTagLifespan(ct, 2.25) call SetTextTagVelocity(ct, 0, -.004) call SetTextTagText(ct, "|cFFFF0000Cancelled|r", BASE_TEXTTAG_SIZE) call SetTextTagVisibility(ct, true) endfunction struct Casting_Struct real x real y real time real spd real s_spd texttag tag integer return = 0 unit u boolean cancell = false boolean this_tick = false endstruct globals Casting_Struct array BC_CS integer BC_Casting_Total = 0 timer BC_Casting_Timer = CreateTimer() endglobals function BC_CancellCast takes nothing returns nothing local unit u = GetTriggerUnit() local integer I = GetUnitUserData(u) local trigger t = GetTriggeringTrigger() set BC_CS[i].cancell = true call ResetTrigger(t) call DestroyTrigger(t) endfunction function BC_F_Timer takes nothing returns nothing local integer i = 0 local Casting_Struct cs loop exitwhen(i >= BC_Casting_Total) set cs = BC_CS[i] if(cs.this_tick == true)then set BC_Casting_Total = BC_Casting_Total - 1 set BC_CS[i] = BC_CS[BC_Casting_Total] call DestroyTextTag(cs.tag) set cs.tag = null elseif(cs.cancell == true)then call BC_CancelledCast(cs.x, cs.y) set cs.this_tick = true else set cs.spd = cs.spd - .05 if(cs.spd <= 0.0)then set cs.time = cs.time - cs.s_spd set cs.spd = cs.s_spd if(cs.time <= cs.s_spd)then //********************************************FINISHED IF THIS IS TRUE set cs.this_tick = true else call SetTextTagText(cs.tag, "|cFF35FF35" + CastString(cs.time) + "|r", BASE_TEXTTAG_SIZE) endif endif endif set i = i + 1 endloop if(BC_Casting_Total == 0)then call PauseTimer(BC_Casting_Timer) endif endfunction function BeginCast takes unit u, real time, real spd returns Casting_Struct local Casting_Struct cs local trigger t if(time < .25)then return -1 endif call UnitAddType(u, UNIT_TYPE_PEON) call IssueImmediateOrder(u, "stop") set cs = Casting_Struct.create() set cs.x = GetUnitX(u) - (time * 7) set cs.y = GetUnitY(u) set cs.time = time set cs.spd = spd set cs.s_spd = spd set cs.u = u set cs.tag = CreateTextTag() call SetTextTagPos(cs.tag, cs.x, cs.y, BASE_TEXTTAG_SIZE) call SetTextTagPermanent(cs.tag, true) call SetTextTagText(cs.tag, "|cFF35FF35" + CastString(time) + "|r", BASE_TEXTTAG_SIZE) call SetTextTagVisibility(cs.tag, true) set t = CreateTrigger() call TriggerAddAction(t, function BC_CancellCast) call TriggerRegisterUnitEvent(t, u, EVENT_UNIT_ISSUED_TARGET_ORDER) call TriggerRegisterUnitEvent(t, u, EVENT_UNIT_ISSUED_POINT_ORDER) call SetUnitUserData(u, BC_Casting_Total) if(BC_Casting_Total == 0)then call TimerStart(BC_Casting_Timer, .05, true, function BC_F_Timer) endif set BC_CS[BC_Casting_Total] = cs set BC_Casting_Total = BC_Casting_Total + 1 return cs endfunction function PolledWait2 takes real duration returns nothing local timer t = CreateTimer() local real remaining call TimerStart(t, duration, false, null) loop set remaining = TimerGetRemaining(t) exitwhen(remaining <= 0) if(remaining > .35)then call TriggerSleepAction(.1 * remaining) else call TriggerSleepAction(-1) endif endloop call PauseTimer(t) call DestroyTimer(t) set t = null endfunction function FinishCast takes real time, Casting_Struct cs returns integer I call PolledWait2(time - .2) loop if(cs.this_tick == true) and (cs.cancell == false)then call UnitRemoveType(cs.u, UNIT_TYPE_PEON) call IssueImmediateOrder(cs.u, "stop") call cs.destroy() return 1 endif if(cs.cancell == true)then call UnitRemoveType(cs.u, UNIT_TYPE_PEON) call IssueImmediateOrder(cs.u, "stop") call cs.destroy() return 0 endif call TriggerSleepAction(-1) endloop call UnitRemoveType(cs.u, UNIT_TYPE_PEON) call IssueImmediateOrder(cs.u, "stop") call cs.destroy() return 0 endfunction //! endlibrary It works to... There's always a way damnit, even if it's retarded! I just wish there was a better way, but I can't think of one that's plausable :(. Well thanks for the help guys, but triggersleepaction appears to be the only choice. 3 cheers for polled wait though. |
| 10-03-2007, 06:55 AM | #13 | |
Quote:
|
| 10-03-2007, 07:11 AM | #14 |
Lol... I think my compiler is on the fritz O_o. Fixed haha. Maybe I should upgrade from vJass 0.9.6.2 ;p. |
| 10-03-2007, 12:42 PM | #15 |
if you do something with custom vJass syntax (scope, struct, or pass a struct through a function), vJass changes the line, and, during that process, seems to eliminate any mistakes after the line: JASS:scope IT ' private struct S `' code func '' unit it ' method pork takes nothing returns nothing | call .func.execute() * endmethod ` endstruct * function beef takes S s returns nothing N call s.pork() '+ endfunction //This is the only line that has to be good endscope ''' That will compile, as far as I know... |
