| 07-19-2009, 03:32 PM | #1 |
so i have some sort of cinematic intro sequence at the start of my map and i was lead to develop this thing to manage its writing/assembly and execution. opinions? or there better alternatives? i don't think it is superfluous... is it? Script: JASS:library FunctionSequencer uses TimerUtils //!//////////////////////////////////////////////////////////////////////////////////////////////////////////////!// //! FunctionSequencer //!==============================================================================================================!// //! //! //! //! //! //! //!//////////////////////////////////////////////////////////////////////////////////////////////////////////////!// //!IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII!// //!IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII!// //! - CONFIGURATION - globals constant integer FUNCSEQUENCER_MAX_NUMBER_OF_SEQUENTS = 100 endglobals //!IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII!// //!IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII!// //! - API - //!IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII!// //!IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII!// //! - FUNCTIONS - function interface sequentfunc takes nothing returns nothing struct funcsequencer readonly sequentfunc array sequent[FUNCSEQUENCER_MAX_NUMBER_OF_SEQUENTS] readonly real array duration[FUNCSEQUENCER_MAX_NUMBER_OF_SEQUENTS] readonly integer countSequent = 0 readonly boolean isRunning = false readonly boolean isPaused = false readonly integer currentSequentIndex = 0 private timer tim public static method create takes nothing returns funcsequencer local funcsequencer new = funcsequencer.allocate() set new.tim = NewTimer() call SetTimerData(new.tim, new) return new endmethod public method onDestroy takes nothing returns nothing call .stop() call ReleaseTimer(.tim) endmethod public method addSequent takes sequentfunc sequent, real duration returns boolean if .isRunning or .countSequent == FUNCSEQUENCER_MAX_NUMBER_OF_SEQUENTS or duration < 0.00 then return false endif set .sequent[.countSequent] = sequent set .duration[.countSequent] = duration set .countSequent = .countSequent + 1 return true endmethod public method flush takes nothing returns boolean if .isRunning then return false endif set .countSequent = 0 return true endmethod public method run takes nothing returns boolean if .isRunning or .countSequent == 0 then return false endif set .isRunning = true set .isPaused = false set .currentSequentIndex = 0 call .iterate() return true endmethod private method iterate takes nothing returns nothing loop call .sequent[.currentSequentIndex].evaluate() if .isRunning == false then return endif exitwhen .duration[.currentSequentIndex] > 0.00 set .currentSequentIndex = .currentSequentIndex + 1 if .currentSequentIndex == .countSequent then call .stop() return endif endloop call TimerStart(.tim, .duration[.currentSequentIndex], false, function funcsequencer.router) set .currentSequentIndex = .currentSequentIndex + 1 if .currentSequentIndex == .countSequent then call .stop() endif endmethod private static method router takes nothing returns nothing call funcsequencer(GetTimerData(GetExpiredTimer())).iterate() endmethod public method pause takes boolean do returns boolean if not .isRunning then return false endif if do != .isPaused then if do then call PauseTimer(.tim) elseif .duration[.currentSequentIndex] == 0.00 then call .iterate() else call TimerStart(.tim, TimerGetRemaining(.tim), false, function funcsequencer.router) endif set .isPaused = do endif return true endmethod public method stop takes nothing returns nothing if .isRunning then set .isRunning = false call PauseTimer(.tim) endif endmethod endstruct endlibrary Example JASS:library Example initializer Initializer requires FunctionSequencer globals private funcsequencer fs endglobals private function A takes nothing returns nothing call BJDebugMsg("A") endfunction private function B takes nothing returns nothing call BJDebugMsg("B") endfunction private function C takes nothing returns nothing call BJDebugMsg("C") endfunction private function D takes nothing returns nothing call BJDebugMsg("D") endfunction private function E takes nothing returns nothing call BJDebugMsg("E") endfunction private function F takes nothing returns nothing call BJDebugMsg("F") endfunction private function Run takes nothing returns nothing call fs.run() endfunction private function Initializer takes nothing returns nothing local trigger trig = CreateTrigger() set fs = funcsequencer.create() call fs.addSequent(sequentfunc.A, 1.00) call fs.addSequent(sequentfunc.B, 0.00) call fs.addSequent(sequentfunc.C, 0.00) call fs.addSequent(sequentfunc.D, 0.00) call fs.addSequent(sequentfunc.E, 2.00) call fs.addSequent(sequentfunc.F, 3.00) call TriggerRegisterPlayerChatEvent(trig, Player(0), "-ex", true) call TriggerAddAction(trig, function Run) set trig = null endfunction endlibrary |
| 07-19-2009, 10:31 PM | #2 |
A linked list seems better suited to this task than an array. Also, I'm more a fan of timestamps than durations, myself. |
| 07-20-2009, 02:27 AM | #3 |
what's a timestamp? |
| 07-20-2009, 02:42 AM | #4 |
Similar to the duration between actions, except that it is instead the duration from the start of the sequence to the action. |
| 07-20-2009, 04:06 AM | #5 |
if i implement that: if i use 1 timer (small countdown; approximation) it wont be accurate if i use many timers then ill be using... many timers. are there other ways to implement timestamp? how is it better than this? |
| 07-20-2009, 11:23 AM | #6 | ||
Quote:
Quote:
|
| 07-21-2009, 07:34 AM | #7 |
in a sequence as i conceive it, each sequent may follow from another and may be followed by another, but no two sequents can be simultaneous. for timestamps to be 'ok', they must be cohesive and prepared with this cohesion in mind, such that no sequent 'overlaps' with another. this doesn't afford 'dynamic sequences' (if that's the term). (although my application here - a cinematic - isn't dynamic, i would like the script to the usable wherever else i might need to use it). sequents with relative durations are 'ok' with respect to the meaning of 'sequence' (above) because each is never to overlap with another. so, this far, maybe both ways can be implemented... ??? but is there a 'better' and more general way? maybe one that has these two as just cases? also, am i right to use LinkedList according to your suggestion? do the .data's of Links get destroyed along with the latter, and along with the latters' parent List's? if not, how can i flush them along? edit: flush them by a loop through the List on-destroy? |
