HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

[Help] TimerFuncs

01-16-2008, 06:29 AM#1
xombie
Due to the fact that this thread caused way too much stupidity, I've removed the code altogether.
01-16-2008, 06:53 AM#2
Silvenon
To tell you the truth, I never got that next/prev system, maybe there is a tut on that somewhere?

I'm not sure what might be the problem, but I think it's that you're using a single global timerfunc for two different instances. I think you have a problem with MUI here, just think about it: you create one timerfunc, the global is set to that instance, then you create the second one, then the global is set to that instance, then you destroy the first one...........and you have the wrong CURR.time.

Sorry if that was wrong, but that was all I could figure out.

Btw, isn't Vex already screwing around with timers?
01-16-2008, 06:59 AM#3
xombie
The variable CURR keeps track of the currently counting down timerfunc, and as such I only set CURR when it needs to be replaced by something that is going to expire sooner.

I heard of TimeLib but had absolutely no idea how to actually use it, and this MagicTimers thing confuses me just as much. I wish I could get a look at the system cohadar uses, I remember him once saying that he uses one different than MagicTimers and TimeLib.

The next and prev are linking the specific timerfunc to the two that come before and after it, so that it can be easily referenced in the handler function.
01-16-2008, 07:01 AM#4
Silvenon
Oh, CURR stands for current I suppose.... :)

Sorry, I'm outta ideas.
01-16-2008, 08:51 AM#5
Troll-Brain
Collapse JASS:
    globals
        private timer T=CreateTimer()
        private timer ET=CreateTimer()
        private trigger TR=CreateTrigger()
        
        private timerfunc CURR=0
    endglobals

We can use CreateSomething in a global declaration now ?
01-16-2008, 09:40 AM#6
Silvenon
Sure, but you can't use custom functions (like systems, for example NewTimer() from CSSafety)
01-16-2008, 11:45 AM#7
Troll-Brain
Could you explain what you want exactly ?
01-16-2008, 08:12 PM#8
Silvenon
Maybe because when you create multiple instances of timerfunc, CURR is not set to second one (I think it's supposed to), because CURR will not be 0, it will be a pointer to the previous struct...........so......nah I don't know what I'm talking about.

I have no idea what's this library even supposed to do.

You lost yourself in your own invention, only you can find the way out of it.
01-16-2008, 10:31 PM#9
xombie
Well I know whats going on throughout this entire thing, its not terribly complex, but the indexing gets messed up when certain conditions are met. Whenever a timerfunc is created it checks to see whether or not it will timeout sooner than any existing timerfunc. If it is the first in line, then it will replace CURR with the newly created timerfunc.

Whenever a timerfunc is destroyed (happens on expiration) and it is the CURR then it will reassign CURR to the next in line timerfunc, if there is one.

The methods are create and onDestroy, where the reassigning of CURR takes place.
01-23-2008, 02:53 AM#10
StealthOfKing
How about instead of trying to steal credit for my code and ideas at wc3c, you just use my system? I wasn't particularly ready to post this here but you have gone too far :(

Collapse JASS:
library TimerObjects initializer Init
//******************************
//* Timer Objects 0.3
//* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
//*    By StealthOfKing
//*
//* Requires vJass.
//*
//* TimerObjects is a small library that allows you to use "timed structs". A timerobject is little more that a node within a
//* linked list, with methods to start and stop it. By using a linked list approach it is easy to stop and start timerobjects
//* (add and remove them from the list). Also included is a basic system to let you use delayed functions.
//*
//* Credit to Vexorian for original idea from TimeLib and vJass!
//*
//* To use:
//*     timerobject             - The basic timed struct.
//*     DelayedFunction         - The function interface to use with DelayedCall.
//*
//*     function DelayedCall    - Executes any function that follows the DelayedFunction interface after a specified delay.
//*
globals
//* Configuration
//* ¯¯¯¯¯¯¯¯¯¯¯¯¯
//* Enables a debug mode for timerobjects, informing you of every object started, stopped or expired, and the content of the
//* list at that time.
    debug constant boolean TIMER_OBJECTS_DEBUG = true
//*
//**********************************************************************************************************************************
endglobals

// Simple function interface.
function interface DelayedFunction takes integer tag returns nothing

// function DelayedCall start's a timed function. Returns a delayedfuncstr, which lets you store the DelayedFunction allowing
// you to stop it (and restart it).
//   Takes:
//      DelayedFunction func    - The function you want to call after the delay (any function that follows the DelayedFunction function interface).
//      integer tag             - Any integer value you wish, allows you to pass data (perhaps a struct) to the DelayedFunction.
//      real delay              - The time you want to delay by, should be 0 or more.
function DelayedCall takes DelayedFunction func, integer tag, real delay returns delayedfuncstr
    local delayedfuncstr t = delayedfuncstr.create()
    set t.func = func
    set t.tag = tag
    call t.start(delay, false)
    return t
endfunction

// A very basic timerobject struct used to execute DelayedFunctions.
struct delayedfuncstr extends timerobject
    DelayedFunction func
    integer         tag

    method onExpire takes nothing returns nothing
        call .func.execute(.tag)    // Execute the DelayedFunction.
        call .destroy()             // DelayedFunctions execute only once then are destroyed.
    endmethod
endstruct

// Interface only used to give the onExpire method signature to timerobjects.
interface timerobjectinterface
    // Called when an object expires.
    method onExpire takes nothing returns nothing defaults nothing
endinterface

// Main struct.
struct timerobject extends timerobjectinterface
    real        timeout                     // The delay... it is easier to work with these objects by thinking of when they
                                            // will expire in relation to total elapsed time (so this will store delay +
                                            // elapsed game time).
    timerobject next        = 0             // List pointers. Default 0 means they point to nothing when created.
    timerobject prev        = 0

    boolean     periodic    = false

    static timer T          = CreateTimer() // Timer for running timerobjects.
    static timer ET         = CreateTimer() // Elapsed game time.
    static timerobject curr = 0             // The first object (next to expire) in the list.

    debug method debug takes string txt returns nothing
        debug local timerobject obj = timerobject.curr
        debug local string s = ""
        debug if not TIMER_OBJECTS_DEBUG then
            debug return
        debug endif
        debug loop
            debug exitwhen obj == 0
            debug set s = s + I2S(obj) + "@" + R2S(obj.timeout) + ", "
            debug set obj = obj.next
        debug endloop
        debug call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 999, txt + I2S(this) + "@" + R2S(.timeout) + ".")
        debug call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 999, "Queued: " + s)
    debug endmethod

    // The main function that handles any timerobject expiring.
    static method onExpireHandler takes nothing returns nothing
        local timerobject expired = timerobject.curr

        set timerobject.curr = expired.next

        if expired.periodic then
        else
            if timerobject.curr != 0 then   // Starts the next timerobject to expire if there is any.
                if timerobject.curr.next == expired then    // Clear's the next object's pointers if it is the only remaining timerobject.
                    set timerobject.curr.next = 0
                endif
                set timerobject.curr.prev = 0
                call TimerStart(timerobject.T, timerobject.curr.timeout - TimerGetElapsed(timerobject.ET), false, function timerobject.onExpireHandler)
            endif

            set expired.next = 0    // Clear the pointers.
            set expired.prev = 0
        endif

        debug call expired.debug("Expired ")

        call expired.onExpire() // Woop!
    endmethod

    // Method start adds the object to the expiring list. Objects are added in order of shortest timeout to longest timeout.
    method start takes real timeout, boolean periodic returns nothing
        local timerobject obj = timerobject.curr

        debug if .next != 0 and .prev != 0 then
            debug call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, ".start(" + R2S(timeout) + ", " + b2s.evaluate(periodic) + ") called on active timerobject@" + I2S(this) + ".")
            debug return
        debug endif

        set .periodic = periodic

        // If the list is empty then start the object, otherwise find its place in the list, and add it. If the object added
        // is the next to expire, then start it.
        if obj == 0 then
            set .timeout = timeout + TimerGetElapsed(timerobject.ET)

            set .next = 0
            set .prev = 0

            set timerobject.curr = this
            call TimerStart(timerobject.T, timeout, false, function timerobject.onExpireHandler)
        else
            set timeout = timeout + TimerGetElapsed(timerobject.ET)
            set .timeout = timeout
            loop
                if timeout < obj.timeout then
                    set .next = obj
                    set .prev = obj.prev
                    set .next.prev = this
                    set .prev.next = this
                    exitwhen true
                elseif obj.next == 0 then
                    set .next = 0
                    set .prev = obj
                    set .prev.next = this
                    exitwhen true
                endif
                set obj = obj.next
            endloop
            if .next == timerobject.curr then   // Check if the object is the first to expire.
                set timerobject.curr = this
                call PauseTimer(timerobject.T)
                call TimerStart(timerobject.T, timeout - TimerGetElapsed(timerobject.ET), false, function timerobject.onExpireHandler)
            endif
        endif
        debug call .debug("Started ")
    endmethod

    // Method stop removes an object from the expiring list, stopping it's wait/execution.
    method stop takes nothing returns nothing
        debug if .next == 0 and .prev == 0 then
            debug call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, ".stop() called on inactive timerobject@" + I2S(this) + ".")
            debug return
        debug endif

        // If this is the next timerobject scheduled to expire stop the timer, start it for the next object (if it is not 0).
        if this == timerobject.curr then
            call PauseTimer(timerobject.T)

            set timerobject.curr = .next

            if timerobject.curr != 0 then
                set timerobject.curr.prev = 0
                call TimerStart(timerobject.T, timerobject.curr.timeout - TimerGetElapsed(timerobject.ET), false, function timerobject.onExpireHandler)
            endif
        elseif .next != 0 then      // Timerobject must be somewhere in the list, but not at the end (or .next would have a value).
            set .prev.next = .next  // Remove object from list and repair pointers.
            set .next.prev = .prev
        else                        // Last timerobject in list.
            set .prev.next = 0      // Clear the previous object's pointer.
        endif

        set .next = 0
        set .prev = 0

        debug call .debug("Stopped ")
    endmethod

    // Stop any objects that are destroyed.
    method onDestroy takes nothing returns nothing
        if .next != 0 or .prev != 0 then
            call .stop()
        endif
    endmethod
endstruct

// Init only needs to start the elapsed game time timer.
public function Init takes nothing returns nothing
    call TimerStart(timerobject.ET, 999999, false, null)
endfunction

// Debug related.
debug constant function b2s takes boolean b returns string
    debug if b then
        debug return "true"
    debug else
        debug return "false"
    debug endif
debug endfunction
endlibrary

If you feel like releasing more of my code to the public, I will do it when I am ready thanks, and next time make sure you get a working version first.

EPIC FAIL, now stfu.
01-23-2008, 05:07 AM#11
Ammorth
Who the hell are you? How the hell can you justify that that Xombie stole your code? How the hell could Xombie have stolen something from wc3c that doesn't exist on wc3c?

As far as I am concerned, I explained to Xombie how to implement the linked-list method of structs.

If this is just pure coincidence, then does that mean no one can make an RPG map anymore because an RPG map has already been created by some idiot? How about some handle attach system? We have like 10 of them. Do they all count as copies of each-other? I sure hope not.
01-23-2008, 05:16 AM#12
StealthOfKing
Who am I? I am StealthOfKing, you can find me on Azeroth in channel Clan BoM. I am a talented Jasser and I keep myself to myself. That enough info for you to go on?

Xombie is on my MSN list, was part of my clan and he is taking the code from 'S O M A Code Development.w3x'. Soma is an RPG I am working on, I can show you the map, and what he has done here is barely more than variable renaming. Who the hell are you to question one of the few posts I make here, in an attempt to atleast claim credit for my own work?
01-23-2008, 01:53 PM#13
Silvenon
Ammorth! I saw you using GetTriggerUnit(), I USE THAT!! How dare you steal my code and claim it as yours??? And I could SWEAR I saw you using CreateTimer().......that's it Ammorth, you're a fucking CODE STEALER!! I'm not speaking to you!
01-23-2008, 02:20 PM#14
Ammorth
Quote:
Originally Posted by Silvenon
Ammorth! I saw you using GetTriggerUnit(), I USE THAT!! How dare you steal my code and claim it as yours??? And I could SWEAR I saw you using CreateTimer().......that's it Ammorth, you're a fucking CODE STEALER!! I'm not speaking to you!

Made me laugh.
I actually don't use GetTriggerUnit() but I'm guilty as charged on the other one

Quote:
Originally Posted by StealthOfKing
Who the hell are you to question one of the few posts I make here, in an attempt to atleast claim credit for my own work?
I'm the guy who asks questions.

Let's wait for Xombie to respond before we all slit each other's throat.
01-23-2008, 02:37 PM#15
StealthOfKing
I feel both Ammorth's and Silvenon's comments have been totally inappropriate (Ammorth's first), can someone explain why I have been targeted here?

I thought wc3c was all for crediting people on their work, your map submission rules certainly suggest so. My own time has gone into the development of my TimerObjects library, and I don't appreciate Xombie renaming variables and cutting it down unsuccessfully, and acting like it is his own. Anyone who takes a few seconds to compare the code can clearly see Xombie is using my system without credit.

Quote:
Originally Posted by Silvenon
Ammorth! I saw you using GetTriggerUnit(), I USE THAT!! How dare you steal my code and claim it as yours??? And I could SWEAR I saw you using CreateTimer().......that's it Ammorth, you're a fucking CODE STEALER!! I'm not speaking to you!
How is use of a native comparable to stealing 200+ lines of code? Oh, I see, sarcasm, very clever and humorous. You are welcome to try again though.