Dismiss Notice
60,000 passwords have been reset on July 8, 2019. If you cannot login, read this.

[vJASS][System]Timed

Discussion in 'Graveyard' started by Nestharus, Aug 13, 2009.

  1. Nestharus

    Nestharus

    Joined:
    Jul 10, 2007
    Messages:
    6,146
    Resources:
    8
    Spells:
    3
    Tutorials:
    4
    JASS:
    1
    Resources:
    8
    Bit Streams

    ---------------------------------------------

    Officially tested to *8000* different timers on a 128 bit stream with 0 lag going in increments starting from 1 bit!

    News Count: 2
    News Data: 8-27-09 at 9:48pm PST

    -News-
    News 1

    Build 1 of the new build is released.

    What is going to be changed?
    A way to attach data to timers =).

    A way to split streams up from the main stream without a loss in speed.

    Is this hella fast?
    It depends... because everything runs on the main stream, the more variety in timers you have, the more laggy it gets because the main stream has to handle more. If you have 8000 of the fastest possible timer, it'd be faster than 8000 dif timers that are all like 100 seconds (fastest possible might run 32 times a second).

    So how will this change?
    I'm going to split the main stream into two stream types, these being fast and slow.

    What will this do?
    It will make timers that won't fire for awhile run only once every once and awhile instead of every time, so instead of every bit, it'll run every 32 bits or something : D.

    Will this be faster?
    Yes... it should be much faster when I think about it o_O.


    News 2

    So, I split up the streams for the most epic optimization stuff ever!

    Maximum Optimization To Smallest Bit Timer-
    The smallest bit timer runs on the actual main stream timer making it as fast as a single standard timer o-o, 0 extras.

    Small Timers have extra optimization-
    With the introduction of the 2 stream types, those being the big stream and the small stream, the small timers that always run on the small stream have various elements that they don't do, meaning that they run faster =). These elements have to do with swapping between the big stream and the small stream. What does this mean? You can go smaller without the performance hit.

    Big Timers have extra optimization-
    Big timers run on a combo of the big and small streams. The big streams don't run as often (once a second). This means that the main stream doesn't have to process as much code making the entire thing run smoother. When a big timer has less than 1 second left (less, not less than or equal to), it swaps to the small stream, carries out the rest of its time, and then goes back to the big stream. You the user don't have to worry about anything.

    Maintain Accuracy, Speed, and Performance on your smallest timers, your small timers, and your big timers =).

    Does this run as fast and as well as KT2?
    I really don't know. I guess someone will have to test it. My only advice is that the best way to stress test this is by creating "unique" timers. Creating a bundle of the same timer will not add anything to the main stream... you have to create as many smaller streams as possible ^_^. This also has a limit of 8191 unique streams and from there 8191 unique pieces of code. Why? It uses arrays : D.


    What is next?
    Data Attachment
    Syncing to and Desyncing from streams
    Getting a code's life
    Setting a code's life
    Forced release of a stream and regular release of a stream (clear it out and release it or release if empty)
    Forced release of Code and regular release of code (release now or release on next run)
    Further optimizations? =p


    Demo-

    Copy this somewhere into the map and hit test map to see a small demonstration of this system.

    Code (vJASS):

    scope Test initializer Initialization
        globals
            private integer stream
        endglobals
       
        private function HelloWorld takes nothing returns nothing
            call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, "Hello World!"))
            call BS_ReleaseCode(stream)
        endfunction
       
        private function Initialization takes nothing returns nothing
            set stream = BS_StreamCode(1.25, function HelloWorld)
        endfunction
    endscope
     


    System-
    Code (vJASS):

    /*Utility Information
    //===================================================================
    Name: Bit Streams
    Version: 3.4
    Author: Nestharus

    Settings:
    */
    //===================================================================
    //! textmacro BS_BIT_RATE
        private constant integer BIT_RATE = 128
    //! endtextmacro

    //! textmacro BS_BIT_MAX
        private constant real BIT_MAX = 1
    //! endtextmacro
    /*//===================================================================

    Description:
    Stream: [url]http://en.wikipedia.org/wiki/Stream_(computing[/url])
    This runs on a single Stream (timer) that creates various sub streams. The timer
    is split into 3 primary streams. When a sub steam on one of the primary streams is
    ready to run, its trigger is fired and all the actions on it go off. The actions are
    split into two parts. The first part is internal. It is very small and simply prepares
    the data for the second part. It also lets the system know exactly what piece of code is
    running. The second part is the user part.

    The only task a main stream does is go through everything on its stream and increment
    it by its interval. While it's doing this, it checks to see if anything has reached its
    timeout period or if it needs to move to the opposite stream.

    Primary Stream: The primary stream starts the 3 main streams, these being the small stream,
    the big stream, and the cleanup stream. The primary stream also increasing the game
    time interval and the current bit. A bit is like a clock and it tells the streams
    exactly what bit they are on. The primary stream will only run main streams if they
    have data on them.

    Small Stream: The small stream runs on small interval timers. When a big interval
    timer has less than a big stream interval left, it swaps to the small stream
    to finish off and then swaps back to the big stream. The small stream interval
    is that of the BIT_RATE. The BIT_RATE is how many times per second the small stream
    runs. Things have an interval of less than one second stay on the small stream. Things
    that have the same interval as the small stream get added to the actual small stream.

    Big Stream: The big stream runs bigger intervals. The big stream usually runs once
    every second, but this can vary depending on the bitrate. A bitrate of more than one
    should have an interval of 1 second on the big stream. A bitrate of one should have an
    interval of 2 on the big stream. An bitrate of less than one should have an interval
    of BIT*BIT.

    Cleanup Stream: This stream rummages through a cleanup array after everything else is
    done running. This means that when code is released, it is not cleaned up immediately. If
    it were cleaned up immediately, the stream that it would be running on would be fractured.

    So, what makes this system better than other systems that do around the same thing?
    More features and an easier to use interface
    Dynamic optimizations (streams going from big to small to big, always small staying small
    and always big staying big), streams only run when they have something in them, and well,
    the cleanup of course. This can actually run 8000 different streams on my laptop with a 128
    bitrate with 0 lag starting at 1 bit and ending at 8000 bits and it can run just about as
    well as plain timers when running single streams. There are so many optimizations in this, all
    of them dynamic, there is just too much to explain o-o.

    There are 3 main types of data associated with a piece of code that is streamed in.
    1.The first is the codeId, which is returned when it is sent in. Worried about having to keep track of it?
    No problem, the codeId is accessible whenever the code runs.
    2. The next is the data attached to the code, which is optional of course and can be changed at any time.
    3. The final is the life of the code (how many times it should run). This life can of course be changed
    and the current age of the code can always be retrieved.

    So, do you have to do anything strange like with KT2? Do you need to say true here and false there and return
    a boolean? Nope. You just run your everyday function in like you would a normal timer and BS does the rest. It
    does use trigger conditions, so don't worry, it just converts the code you send into it into condition form.

    Requirements: None

    Installation: NA

    Variables:
    -BIT_RATE
        How many times per second the stream runs. The bigger the bit rate,
        the more accurate your timers can be. 128 is a good value and 64 is
        safe.
       
    -BIT_MAX
        Suggest 1 for a bit rate of anything higher than one, BIT+BIT for
        1, and BIT*BIT for anything lower than 1.
       
    -Main Functions:


    Functions:
    ------------------------------------------------------------------
    -BS_StreamCode(interval, code) returns integer
        Streamlines code and returns an id of the code
        local integer myStreamedCode = BS_StreamCode(1, function Hello)
       
    -BS_ReleaseCode(codeId) returns nothing
        Will take code out of a stream
        call BS_ReleaseCode(myStreamedCode)

    -BS_GET_STREAM_TIME(codeId) returns real
        Takes a code id value and returns the interval of the stream it is
        running on.
        local real timeout = BS_GET_STREAM_TIME(myStreamedCode)

    -BS_GET_STREAM(codeId) returns integer
        Takes a code id value and returns the stream id that it is running
        on
        local integer stream = BS_GET_STREAM(myStreamedCode)
       
    -BS_GET_ELAPSED_GAME_TIME() returns real
        Will return the current elapsed game time.
        local real gameTime = GetElapsedGameTime()
       
    -BS_GET_DATA() returns integer
        Will return data for the current running code

    -BS_UpdataData(data) returns nothing
        Will set the data for the current running code
       
    -BS_GET_CURRENT_CODE() returns integer
        Will return the current running code
       
    -BS_GET_CURRENT_STREAM() returns integer
        Will return the current running stream
       
    -BS_GET_CODE_AGE() returns integer
        Will return how many times the code has run

    -BS_GET_CODE_LIFE() returns itneger
        Will return how many times the code can run before being released
       
    -BS_SetCodeLife(codeId, life)
        sets the life of the code
       
    -BS_SetCurrentCodeLife(life)
        sets the life of the current running code
       
    -BS_StreamCodeData(interval, code, data) returns integer
        Streamlines code and attaches data to it.
       
    -BS_StreamCodeLife(interval, code, life) returns integer
        Streamlines code and sets its life
       
    -BS_StreamCodeCombo(interval, code, data, life) returns integer
        Streamlines code and attaches data to it and sets its life
    ------------------------------------------------------------------*/

    //===================================================================

    library BS initializer Initialization
        globals
            //! runtextmacro BS_BIT_RATE()
            private constant integer BIT_SIZE = BIT_RATE*BIT_RATE
            private constant real BIT = 1./BIT_RATE
            //! runtextmacro BS_BIT_MAX()
            private real array bits
            private integer array bitIds
            private integer bitIdIndex = -1
            private boolean array streamExists
            private real array bitTable
            private integer array streamCodeCount
            private real gameSeconds = 0
            private real currentBit = 0
            private integer currentStream = 0
            private integer currentRunningCode = 0
            private trigger array streams
            private triggercondition array codeStreams
            private boolexpr array codes
            private integer codeStreamsIndex = 0
            private integer array codeStreamsQueu
            private integer codeStreamsQueuIndex = 0
            private integer array codeStreamId
            private real array codeStream
            private real array codeStreamProcess
            private boolean array streamHasRun
            private integer array smallStreamStack
            private integer array smallStreamStackR
            private integer array bigStreamStack
            private integer array bigStreamStackR
            private integer smallStreamStackIndex = 0
            private integer bigStreamStackIndex = 0
            private integer specialBigStreamStackIndex = 0
            private real array bitFired
            private integer array lastCode
            private integer array nextCode
            private integer array firstCode
            private integer array currentCode
            private integer array codeStack
            private integer array codeStackQueu
            private integer codeStackQueuIndex = 0
            private integer array codePointToStack
            private integer codeStackIndex = 0
            private integer array codeStackLoop
            private boolexpr setupCodeData
            private boolexpr specialSetupCodeData
            private boolexpr specialSetupCodeDataBig
            private integer array codeData
            private integer array toBeReleased
            private integer toBeReleasedIndex = 0
            private integer array codeAge
            private integer array codeLife
            private trigger cleanup = CreateTrigger()
           
            private trigger stream = CreateTrigger()
            private trigger bigStream = CreateTrigger()
            private event streamEvent = TriggerRegisterTimerEvent(stream, BIT, true)
            private boolexpr releaseCode
        endglobals
       
        private function AddStreamToBigStack takes integer id returns nothing
            set bigStreamStackIndex = bigStreamStackIndex + 1
            set bigStreamStack[bigStreamStackIndex] = id
            set bigStreamStackR[id] = bigStreamStackIndex
        endfunction
       
        private function AddStreamToSmallStack takes integer id returns nothing
            set smallStreamStackIndex = smallStreamStackIndex + 1
            set smallStreamStack[smallStreamStackIndex] = id
            set smallStreamStackR[id] = smallStreamStackIndex
        endfunction
       
        private function RemoveStreamFromBigStack takes integer id returns nothing
            set bigStreamStack[bigStreamStackR[id]] = bigStreamStack[bigStreamStackIndex]
            set bigStreamStackR[bigStreamStack[bigStreamStackIndex]] = bigStreamStackR[id]
            set bigStreamStackR[id] = 0
            set bigStreamStackIndex = bigStreamStackIndex - 1
        endfunction
       
        private function RemoveStreamFromSmallStack takes integer id returns nothing
            set smallStreamStack[smallStreamStackR[id]] = smallStreamStack[smallStreamStackIndex]
            set smallStreamStackR[smallStreamStack[smallStreamStackIndex]] = smallStreamStackR[id]
            set smallStreamStackR[id] = 0
            set smallStreamStackIndex = smallStreamStackIndex - 1
        endfunction
       
        private constant function BIG_STREAM takes real currentTime, real time returns boolean
            return (time-currentTime >= 1)
        endfunction
       
        private constant function IN_BIG_STREAM_STACK takes integer id returns boolean
            return (bigStreamStackR[id] > 0)
        endfunction
       
        private constant function IN_SMALL_STREAM_STACK takes integer id returns boolean
            return (smallStreamStackR[id] > 0)
        endfunction
       
        private function AddStreamToStack takes integer id, real currentTime, real time returns nothing
            if (time != currentTime) then
                if BIG_STREAM(currentTime, time) then
                    if not IN_BIG_STREAM_STACK(id) then
                        if IN_SMALL_STREAM_STACK(id) then
                            call RemoveStreamFromSmallStack(id)
                        endif
                        call AddStreamToBigStack(id)
                    endif
                elseif not IN_SMALL_STREAM_STACK(id) then
                    if IN_BIG_STREAM_STACK(id) then
                        call RemoveStreamFromBigStack(id)
                    endif
                    call AddStreamToSmallStack(id)
                endif
            endif
        endfunction
       
        private function RemoveStreamFromStack takes integer id, real currentTime, real time returns nothing
            if BIG_STREAM(currentTime, time) then
                if IN_BIG_STREAM_STACK(id) then
                    call RemoveStreamFromBigStack(id)
                endif
            elseif IN_SMALL_STREAM_STACK(id) then
                call RemoveStreamFromSmallStack(id)
            endif
        endfunction
       
        private function SetupStream takes integer id, real time returns nothing
            set bitIdIndex = bitIdIndex + 1
            set bitIds[bitIdIndex] = id
            set bitTable[id] = time
            set streamExists[id] = true
        endfunction
       
        private function CreateStream takes integer id, real time returns nothing
            set streams[id] = CreateTrigger()
            call SetupStream(id, time)
        endfunction
       
        private constant function GET_BIT_SIZE takes real time returns real
            return time/BIT
        endfunction
       
        private function Time2Id takes real time returns integer
            return R2I(GET_BIT_SIZE(time)-R2I(GET_BIT_SIZE(time)/8191)*8191)
        endfunction
       
        private function FindTime takes integer id, real time returns integer
            loop
                exitwhen bitTable[id] == time or bitTable[id] == 0
                set id = id + 1
            endloop
            return id
        endfunction
       
        private function GetStreamId takes real time returns integer
            local integer id = FindTime(Time2Id(time), time)
            if not streamExists[id] then
                call CreateStream(id, time)
            endif
            return id
        endfunction
       
        private function GetCodeId takes nothing returns integer
            if codeStreamsQueuIndex == 0 then
                set codeStreamsIndex = codeStreamsIndex + 1
                return codeStreamsIndex
            endif
            set codeStreamsQueuIndex = codeStreamsQueuIndex - 1
            return codeStreamsQueu[codeStreamsQueuIndex+1]
        endfunction
       
        private function StreamIntervalCode takes integer codeId, real time, boolexpr c returns triggercondition
            local integer id = GetStreamId(time)
            call AddStreamToStack(id, 0, time)
            set codeStreamId[codeId] = id
            set streamCodeCount[id] = streamCodeCount[id]+1
            set codes[codeId] = And(setupCodeData, c)
            return TriggerAddCondition(streams[id], codes[codeId])
        endfunction
       
        public constant function GET_STREAM_TIME takes integer codeId returns real
            return codeStream[codeId]
        endfunction
       
        public constant function GET_STREAM takes integer codeId returns integer
            return codeStreamId[codeId]
        endfunction
       
        private function ConvertTime takes real time returns real
            local real convertedTime
            local integer roundedTime
            if time > BIT then
                set convertedTime = time/BIT
                set roundedTime = R2I(convertedTime)
                return (R2I(convertedTime-roundedTime+BIT_MAX-.001)+roundedTime)*BIT
            endif
            return BIT
        endfunction
       
        private function GetCodeStream takes real time, boolexpr c, integer codeId returns triggercondition
            if time == BIT then
                set codeStreamId[codeId] = 1
                set codes[codeId] = And(specialSetupCodeData, c)
                return TriggerAddCondition(stream, codes[codeId])
            elseif time == BIT_MAX then
                set codeStreamId[codeId] = 2
                set specialBigStreamStackIndex = specialBigStreamStackIndex + 1
                set codes[codeId] = And(specialSetupCodeDataBig, c)
                return TriggerAddCondition(bigStream, codes[codeId])
            endif
            return StreamIntervalCode(codeId, time, c)
        endfunction
       
        private constant function CHECK_NEXT_CODE takes integer id returns boolean
            return (nextCode[codeStackLoop[id]] > 0)
        endfunction
       
        private function NextCode takes integer id returns integer
            local integer result = codeStackLoop[id]
            if CHECK_NEXT_CODE(id) then
                set codeStackLoop[id] = nextCode[codeStackLoop[id]]
            elseif not CHECK_NEXT_CODE(id) then
                set codeStackLoop[id] = firstCode[id]
            endif
            return codeStack[result]
        endfunction
       
        private function AddToCodeStackQueu takes integer stack returns nothing
            set codeStackQueuIndex = codeStackQueuIndex + 1
            set codeStackQueu[codeStackQueuIndex] = stack
        endfunction
       
        private function RemoveCodeFromStack takes integer id, integer stack returns integer
            local integer recycled = currentCode[id]
            if stack < currentCode[id] then
                set codeStack[stack] = codeStack[currentCode[id]]
                set codePointToStack[codeStack[stack]] = stack
            endif
            set nextCode[lastCode[currentCode[id]]] = 0
            set lastCode[currentCode[id]] = 0
            set currentCode[id] = currentCode[id] - 1
            return recycled
        endfunction
       
        private function RemoveCode takes integer id, integer codeId returns nothing
            call AddToCodeStackQueu(RemoveCodeFromStack(id, codePointToStack[codeId]))
            set codePointToStack[codeId] = 0
        endfunction
       
        private function CodeStackIndex takes integer id returns integer
            if codeStackQueuIndex > 0 then
                set codeStackQueuIndex = codeStackQueuIndex - 1
                return codeStackQueu[codeStackQueuIndex+1]
            endif
            return 0
        endfunction
       
        private function GetCodeStackIndex takes integer id returns integer
            local integer instancedIndex = CodeStackIndex(id)
            if instancedIndex == 0 then
                set codeStackIndex = codeStackIndex + 1
                return codeStackIndex
            endif
            return instancedIndex
        endfunction
       
        private function NewCode takes integer id returns integer
            local integer instancedIndex = GetCodeStackIndex(id)
            set lastCode[instancedIndex] = nextCode[lastCode[currentCode[id]]]
            set nextCode[lastCode[instancedIndex]] = instancedIndex
            set currentCode[id] = instancedIndex
            return instancedIndex
        endfunction
       
        private function StreamCodeList takes integer codeId, integer id returns nothing
            local integer instancedIndex
            if currentCode[id] > 0 then
                set instancedIndex = NewCode(id)
            else
                set instancedIndex = GetCodeStackIndex(id)
                set firstCode[id] = instancedIndex
                set currentCode[id] = instancedIndex
                set lastCode[currentCode[id]] = instancedIndex
                set nextCode[currentCode[id]] = instancedIndex
                set codeStackLoop[id] = firstCode[id]
            endif
            set codeStack[instancedIndex] = codeId
            set codePointToStack[codeId] = instancedIndex
        endfunction
       
        public constant function GET_DATA takes nothing returns integer
            return codeData[currentRunningCode]
        endfunction
       
        public constant function GET_CURRENT_CODE takes nothing returns integer
            return currentRunningCode
        endfunction
       
        public constant function GET_CURRENT_STREAM takes nothing returns integer
            return currentStream
        endfunction
       
        public function UpdateData takes integer data returns nothing
            set codeData[currentRunningCode] = data
        endfunction
       
        public function ReleaseCode takes integer codeId returns nothing
            set toBeReleasedIndex = toBeReleasedIndex + 1
            set toBeReleased[toBeReleasedIndex] = codeId
        endfunction
       
        private function IncCodeAge takes integer currentRunningCode returns boolean
            set codeAge[currentRunningCode] = codeAge[currentRunningCode] + 1
            return (codeLife[currentRunningCode] > 0 and codeAge[currentRunningCode] >= codeLife[currentRunningCode])
        endfunction
       
        private function SetupCodeData takes nothing returns boolean
            set currentRunningCode = NextCode(currentStream)
            if IncCodeAge(currentRunningCode) then
                call ReleaseCode(currentRunningCode)
            endif
            return true
        endfunction
       
        private function SpecialSetupCodeData takes nothing returns boolean
            set currentStream = 1
            call SetupCodeData()
            return true
        endfunction
       
        private function SpecialSetupCodeDataBig takes nothing returns boolean
            set currentStream = 2
            call SetupCodeData()
            return true
        endfunction
       
        public constant function GET_CODE_AGE takes nothing returns integer
            return codeAge[currentRunningCode]
        endfunction
       
        public constant function GET_CODE_LIFE takes nothing returns integer
            return codeLife[currentRunningCode]
        endfunction
       
        private function ReleaseCodeLife takes integer codeId, integer life returns boolean
            if life < 0 then
                set codeLife[codeId] = codeAge[codeId]
                return true
            endif
            return false
        endfunction
       
        public function SetCodeLife takes integer codeId, integer life returns nothing
            if not ReleaseCodeLife(codeId, life) then
                set codeLife[codeId] = life
            endif
        endfunction
       
        public function SetCurrentCodeLife takes integer life returns nothing
            call SetCodeLife(currentRunningCode, life)
        endfunction
       
        public function CatchCode takes nothing returns boolean
            local real time
            local integer id
            local integer codeId
            loop
                exitwhen toBeReleasedIndex == 0
                set codeId = toBeReleased[toBeReleasedIndex]
                set toBeReleasedIndex = toBeReleasedIndex - 1
                set time = GET_STREAM_TIME(codeId)
                if time >= BIT then
                    set id = GET_STREAM(codeId)
                    call RemoveCode(id, codeId)
                    if time == BIT then
                        call TriggerRemoveCondition(stream, codeStreams[codeId])
                    elseif time == BIT_MAX then
                        set specialBigStreamStackIndex = specialBigStreamStackIndex - 1
                        call TriggerRemoveCondition(bigStream, codeStreams[codeId])
                    else
                        call TriggerRemoveCondition(streams[id], codeStreams[codeId])
                        set streamCodeCount[id] = streamCodeCount[id] - 1
                        if streamCodeCount[id] == 0 then
                            set codeStackLoop[id] = firstCode[id]
                            call RemoveStreamFromStack(id, codeStreamProcess[id], bitTable[id])
                        endif
                    endif
                    call DestroyBoolExpr(codes[codeId])
                    set codeStreams[codeId] = null
                    set codes[codeId] = null
                    set codeStreamsQueuIndex = codeStreamsQueuIndex + 1
                    set codeStreamsQueu[codeStreamsQueuIndex] = codeId
                endif
            endloop
            return true
        endfunction
       
        private function RunBigStream takes integer id returns nothing
            if (codeStreamProcess[bigStreamStack[id]] == bitTable[bigStreamStack[id]]) then
                set codeStreamProcess[bigStreamStack[id]] = 0
                set currentStream = bigStreamStack[id]
                set bitFired[bigStreamStack[id]] = currentBit
                call TriggerEvaluate(streams[bigStreamStack[id]])
            endif
        endfunction
       
        private function RunSmallStream takes integer id returns nothing
            if (codeStreamProcess[smallStreamStack[id]] == bitTable[smallStreamStack[id]]) then
                set codeStreamProcess[smallStreamStack[id]] = 0
                set currentStream = smallStreamStack[id]
                set bitFired[smallStreamStack[id]] = currentBit
                call TriggerEvaluate(streams[smallStreamStack[id]])
            endif
        endfunction
       
        private function IncBigStreamProcess takes integer id, real increase returns nothing
            set codeStreamProcess[bigStreamStack[id]] = codeStreamProcess[bigStreamStack[id]] + increase
        endfunction
       
        private function IncSmallStreamProcess takes integer id returns nothing
            set codeStreamProcess[smallStreamStack[id]] = codeStreamProcess[smallStreamStack[id]] + BIT
        endfunction
       
        private function StreamAddToSmallStack takes integer i returns nothing
            call AddStreamToStack(smallStreamStack[i], codeStreamProcess[smallStreamStack[i]], bitTable[smallStreamStack[i]])
        endfunction
       
        private function StreamAddToBigStack takes integer i returns nothing
            call AddStreamToStack(bigStreamStack[i], codeStreamProcess[bigStreamStack[i]], bitTable[bigStreamStack[i]])
        endfunction
       
        private function SmallStream takes nothing returns boolean
            local integer i = 1
            local integer end = smallStreamStackIndex
            loop
                exitwhen i > end
                call IncSmallStreamProcess(i)
                call RunSmallStream(i)
                if bitTable[smallStreamStack[i]] >= BIT_MAX then
                    set streamHasRun[smallStreamStack[i]] = true
                    call StreamAddToSmallStack(i)
                endif
                set i = i + 1
            endloop
            return true
        endfunction
       
        private function BigStream takes nothing returns boolean
            local integer i = 1
            local integer end = bigStreamStackIndex
            loop
                exitwhen i > end
                if not streamHasRun[bigStreamStack[i]] then
                    call IncBigStreamProcess(i, BIT_MAX)
                    call RunBigStream(i)
                    call StreamAddToBigStack(i)
                elseif bitTable[bigStreamStack[i]] > 1 then
                    call IncBigStreamProcess(i, (BIT_MAX-bitFired[bigStreamStack[i]]))
                    call RunBigStream(i)
                    set streamHasRun[bigStreamStack[i]] = false
                    call StreamAddToBigStack(i)
                else
                    set streamHasRun[bigStreamStack[i]] = false
                endif
                set i = i + 1
            endloop
            return true
        endfunction
       
        public constant function GET_ELAPSED_GAME_TIME takes nothing returns real
            return currentBit + gameSeconds
        endfunction
       
        private constant function BIG_STREAM_CHECK takes nothing returns boolean
            return (currentBit == BIT_MAX)
        endfunction

        private function Stream takes nothing returns boolean
            if BIG_STREAM_CHECK() then
                set gameSeconds = gameSeconds + BIT_MAX
            endif
            set currentBit = currentBit - R2I(currentBit) + BIT
            if smallStreamStackIndex > 0 then
                call SmallStream()
            endif
            if BIG_STREAM_CHECK() then
                if bigStreamStackIndex > 0 or specialBigStreamStackIndex > 0 then
                    call TriggerEvaluate(bigStream)
                endif
            endif
            if toBeReleasedIndex > 0 then
                call TriggerEvaluate(cleanup)
            endif
            return true
        endfunction
       
        private function ClearCodeData takes integer codeId returns nothing
            set codeData[codeId] = 0
            set codeAge[codeId] = 0
            set codeLife[codeId] = 0
        endfunction
       
        private function AddCodeToStream takes real time, code c returns integer
            local integer codeId = GetCodeId()
            set time = ConvertTime(time)
            set codeStream[codeId] = time
            set codeStreams[codeId] = GetCodeStream(time, Condition(c), codeId)
            call StreamCodeList(codeId, codeStreamId[codeId])
            return codeId
        endfunction
       
        public function StreamCode takes real time, code c returns integer
            local integer codeId = AddCodeToStream(time, c)
            call ClearCodeData(codeId)
            return codeId
        endfunction
       
        public function StreamCodeData takes real time, code c, integer data returns integer
            local integer codeId = StreamCode(time, c)
            set codeData[codeId] = data
            return codeId
        endfunction
       
        public function StreamCodeLife takes real time, code c, integer life returns integer
            local integer codeId = StreamCode(time, c)
            set codeLife[codeId] = life
            return codeId
        endfunction
       
        public function StreamCodeCombo takes real time, code c, integer data, integer life returns integer
            local integer codeId = StreamCode(time, c)
            set codeData[codeId] = data
            set codeLife[codeId] = life
            return codeId
        endfunction
       
        private function Initialization takes nothing returns nothing
            call TriggerAddCondition(bigStream, Condition(function BigStream))
            call TriggerAddCondition(stream, Condition(function Stream))
            set setupCodeData = Condition(function SetupCodeData)
            set specialSetupCodeData = Condition(function SpecialSetupCodeData)
            set specialSetupCodeDataBig = Condition(function SpecialSetupCodeDataBig)
            call TriggerAddCondition(cleanup, Condition(function CatchCode))
            set bitTable[1] = BIT
            set bitTable[2] = BIT_MAX
        endfunction
    endlibrary
     
     
    Last edited: Aug 28, 2009
  2. MapperMalte

    MapperMalte

    Joined:
    Nov 4, 2007
    Messages:
    326
    Resources:
    5
    Maps:
    2
    Spells:
    2
    JASS:
    1
    Resources:
    5
    Does this measure the speed of systems?
     
  3. Nestharus

    Nestharus

    Joined:
    Jul 10, 2007
    Messages:
    6,146
    Resources:
    8
    Spells:
    3
    Tutorials:
    4
    JASS:
    1
    Resources:
    8
    nop... I used stop watch natives to get those results for a new build I'm working on : |.

    This build is slow compared to current systems, but it's feature list is much nicer and its capabilities are also nice.

    Just check out the demo if you want to see an example : d.
     
  4. MapperMalte

    MapperMalte

    Joined:
    Nov 4, 2007
    Messages:
    326
    Resources:
    5
    Maps:
    2
    Spells:
    2
    JASS:
    1
    Resources:
    5
    Stop trying to reinvent the wheel all the time !
    Most of your submissions have a wrong concept, shall fix all your problems
    and have already been invented twice as good.
     
  5. Nestharus

    Nestharus

    Joined:
    Jul 10, 2007
    Messages:
    6,146
    Resources:
    8
    Spells:
    3
    Tutorials:
    4
    JASS:
    1
    Resources:
    8
    Update numero 1 ^_^

    Update numero 2 ^_^

    Ok, working on a third build that where 1 timer on this should be just about as fast as a regular timer... 2 timers on this should be almost as fast as 1 timer and faster than 2 timers... 10 timers should be faster than 2 timers and almost as fast as 1 timer.

    I call it Lucy (no not really) but yea... I had a genius idea for the new build that has never been done. It will have 0 triggers and 1 timer for the ultimate in speed, it'll maintain its current API ^_^.
     
    Last edited: Aug 29, 2009
  6. aznricepuff

    aznricepuff

    Joined:
    Feb 22, 2006
    Messages:
    749
    Resources:
    4
    Maps:
    2
    Spells:
    1
    Tutorials:
    1
    Resources:
    4
    Finally decided to graveyard this. Why? Because nobody possibly uses enough timers going off at the same time for this to be useful.