• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

Message Queueing

Level 11
Joined
Apr 29, 2007
Messages
826
- Message Queueing -

OH MY GAWD, not that guy again. Yes. Seriously.
This time with something, I don't know if I could really say useful, well it's simple. It allows you to queue text messages up. Why would anyone need this? err, yeah. I needed this because I had an text message showing up the whole game, I just updated the text of it. So imagine you're creating another text message. Right! It moves up. And because we don't want that, we use my system to queue the new text message in there. And depending on the order selected(no you cant specify it by numbers yet, I was too lazy) it will be under/over it.

Enough talked, just review the script. It isn't very long.
JASS:
library_once MeQ

    globals
        private constant real       INTERVAL       = 0.15
        private constant real       DEFAULT_TIME   = 5
        private constant real       DEFAULT_X      = 0
        private constant real       DEFAULT_Y      = 0
        private constant force      DEFAULT_FORCE  = bj_FORCE_ALL_PLAYERS
        private constant boolean    REVERSE        = true
    endglobals

    private keyword queue
    globals
        queue Queue
        queue MessageQueue
    endglobals
    
    private struct queue extends array
        readonly static integer counter = 0
        private static hashtable hash
        
        private static method onInit takes nothing returns nothing
            set .hash = InitHashtable()
            
            call TimerStart(CreateTimer(), INTERVAL, true, function thistype.display)
        endmethod
        
        private static method display takes nothing returns nothing
            local integer i
            local integer k = -1
            local string msg
            call ClearTextMessages()
            if REVERSE then
                set i = .counter
                loop
                    set i = i-1
                    exitwhen i <= -1
                    set msg = LoadStr(.hash, i, 0)
                    if IsPlayerInForce(GetLocalPlayer(), LoadForceHandle(.hash, StringHash(msg), 5)) then
                        call DisplayTimedTextToPlayer(GetLocalPlayer(), LoadReal(.hash, StringHash(msg), 3), LoadReal(.hash, StringHash(msg), 4), INTERVAL, msg)
                    endif
                    call SaveReal(.hash, StringHash(msg), 2, LoadReal(.hash, StringHash(msg), 2)+INTERVAL)
                    if LoadReal(.hash, StringHash(msg), 2) >= LoadReal(.hash, StringHash(msg), 1) then
                        call .deleteMessage(i)
                    endif
                endloop
            else
                set i = -1
                loop
                    set i = i+1
                    exitwhen i >= .counter
                    set msg = LoadStr(.hash, i, 0)
                    if IsPlayerInForce(GetLocalPlayer(), LoadForceHandle(.hash, StringHash(msg), 5)) then
                        call DisplayTimedTextToPlayer(GetLocalPlayer(), LoadReal(.hash, StringHash(msg), 3), LoadReal(.hash, StringHash(msg), 4), INTERVAL, msg)
                    endif
                    call SaveReal(.hash, StringHash(msg), 2, LoadReal(.hash, StringHash(msg), 2)+INTERVAL)
                    if LoadReal(.hash, StringHash(msg), 2) >= LoadReal(.hash, StringHash(msg), 1) then
                        call .deleteMessage(i)
                    endif
                endloop
            endif
        endmethod
        
        static method registerMessage takes string msg, real time, real x, real y, force to returns integer
            call SaveStr(.hash, .counter, 0, msg)
            call SaveInteger(.hash, StringHash(msg), 0, .counter)
            call SaveReal(.hash, StringHash(msg), 1, time)
            call SaveReal(.hash, StringHash(msg), 2, 0)
            call SaveReal(.hash, StringHash(msg), 3, x)
            call SaveReal(.hash, StringHash(msg), 4, y)
            call SaveForceHandle(.hash, StringHash(msg), 5, to)
            set .counter = .counter+1
            return .counter-1
        endmethod
        
        static method updateMessage takes integer ptr, string msg returns nothing
            call SaveInteger(.hash, StringHash(msg), 0, ptr)
            call SaveReal(.hash, StringHash(msg), 1, LoadReal(.hash, StringHash(LoadStr(.hash, ptr, 0)), 1))
            call SaveReal(.hash, StringHash(msg), 2, LoadReal(.hash, StringHash(LoadStr(.hash, ptr, 0)), 2))
            call SaveReal(.hash, StringHash(msg), 3, LoadReal(.hash, StringHash(LoadStr(.hash, ptr, 0)), 3))
            call SaveReal(.hash, StringHash(msg), 4, LoadReal(.hash, StringHash(LoadStr(.hash, ptr, 0)), 4))
            call SaveForceHandle(.hash, StringHash(msg), 5, LoadForceHandle(.hash, StringHash(LoadStr(.hash, ptr, 0)), 5))
            call SaveStr(.hash, ptr, 0, msg)
        endmethod
        
        static method updateByMessage takes string oldmsg, string newmsg returns nothing
            call .updateMessage(.findMessage(oldmsg), newmsg)
        endmethod
        
        static method deleteMessage takes integer ptr returns nothing
            local integer i = ptr-1
            local string msg
            if LoadStr(.hash, ptr, 0) == "" or ptr < 0 or .counter <= 0 then
                return
            endif
            loop
                set i = i+1
                exitwhen i >= .counter
                call SaveStr(.hash, i, 0, LoadStr(.hash, i+1, 0))
                set msg = LoadStr(.hash, i, 0)
                call SaveInteger(.hash, StringHash(msg), 0, i)
                call SaveReal(.hash, StringHash(msg), 1, LoadReal(.hash, StringHash(msg), 1))
                call SaveReal(.hash, StringHash(msg), 2, LoadReal(.hash, StringHash(msg), 2))
                call SaveReal(.hash, StringHash(msg), 3, LoadReal(.hash, StringHash(msg), 3))
                call SaveReal(.hash, StringHash(msg), 4, LoadReal(.hash, StringHash(msg), 4))
                call SaveForceHandle(.hash, StringHash(msg), 5, LoadForceHandle(.hash, StringHash(LoadStr(.hash, ptr, 0)), 5))
            endloop
            set .counter = .counter-1
        endmethod
        
        static method deleteByMessage takes string msg returns nothing
            call .deleteMessage(.findMessage(msg))
        endmethod
        
        static method findMessage takes string msg returns integer
            local integer i = -1
            loop
                set i = i+1
                exitwhen i >= .counter
                if LoadStr(.hash, i, 0) == msg then
                    return LoadInteger(.hash, StringHash(LoadStr(.hash, i, 0)), 0)
                endif
            endloop
            return -1
        endmethod
    endstruct
    
    function RegisterMessage takes string msg, real time, real x, real y, force to returns integer
        return Queue.registerMessage(msg, time, x, y, to)
    endfunction
    
    function UpdateMessage takes integer ptr, string msg returns nothing
        call Queue.updateMessage(ptr, msg)
    endfunction
    
    function UpdateByMessage takes string oldstr, string newstr returns nothing
        call Queue.updateByMessage(oldstr, newstr)
    endfunction
    
    function DeleteMessage takes integer ptr returns nothing
        call Queue.deleteMessage(ptr)
    endfunction
    
    function DeleteByMessage takes string msg returns nothing
        call Queue.deleteByMessage(msg)
    endfunction
    
    function FindMessage takes string msg returns integer
        return Queue.findMessage(msg)
    endfunction
endlibrary

JASS:
library_once MeQ

    globals
        private constant real       INTERVAL       = 0.15
        private constant real       DEFAULT_TIME   = 5
        private constant real       DEFAULT_X      = 0
        private constant real       DEFAULT_Y      = 0
        private constant boolean    REVERSE        = true
    endglobals

    private keyword queue
    globals
        queue array Queue
        queue array MessageQueue
    endglobals
    
    private struct queue
        readonly integer counter = 0
        readonly timer t = null
        private static hashtable hash
        private static method onInit takes nothing returns nothing
            local integer i = -1
            local timer t
            loop
                set i = i+1
                exitwhen i >= 12
                if GetPlayerSlotState(Player(i)) == PLAYER_SLOT_STATE_PLAYING then
                    set Queue[i] = thistype.allocate()
                    set MessageQueue[i] = Queue[i]
                endif
            endloop
        
            set .hash = InitHashtable()
        endmethod
        
        private static method display takes nothing returns nothing
            local thistype this = LoadInteger(.hash, GetHandleId(GetExpiredTimer()), 0)
            local integer i
            local integer k = -1
            local string msg
            call ClearTextMessages()
            if REVERSE then
                set i = .counter
                loop
                    set i = i-1
                    exitwhen i <= -1
                    set msg = LoadStr(.hash, i, this)
                    call DisplayTimedTextToPlayer(Player(this-1), LoadReal(.hash, StringHash(msg), 3), LoadReal(.hash, StringHash(msg), 4), INTERVAL, msg)
                    call SaveReal(.hash, StringHash(msg), 2, LoadReal(.hash, StringHash(msg), 2)+INTERVAL)
                    if LoadReal(.hash, StringHash(msg), 2) >= LoadReal(.hash, StringHash(msg), 1) then
                        call .deleteMessage(i)
                    endif
                endloop
            else
                set i = -1
                loop
                    set i = i+1
                    exitwhen i >= .counter
                    set msg = LoadStr(.hash, i, this)
                    call DisplayTimedTextToPlayer(Player(this-1), LoadReal(.hash, StringHash(msg), 3), LoadReal(.hash, StringHash(msg), 4), INTERVAL, msg)
                    call SaveReal(.hash, StringHash(msg), 2, LoadReal(.hash, StringHash(msg), 2)+INTERVAL)
                    if LoadReal(.hash, StringHash(msg), 2) >= LoadReal(.hash, StringHash(msg), 1) then
                        call .deleteMessage(i)
                    endif
                endloop
            endif
            
            if .counter == 0 then
                call ClearTextMessages()
                call PauseTimer(.t)
            endif
        endmethod
        
        method registerMessage takes string msg, real time, real x, real y returns integer
            call SaveStr(.hash, .counter, this, msg)
            call SaveInteger(.hash, StringHash(msg), 0, .counter)
            call SaveReal(.hash, StringHash(msg), 1, time)
            call SaveReal(.hash, StringHash(msg), 2, 0)
            call SaveReal(.hash, StringHash(msg), 3, x)
            call SaveReal(.hash, StringHash(msg), 4, y)
            
            if .counter == 0 then
                if .t == null then
                    set .t = CreateTimer()
                    call SaveInteger(.hash, GetHandleId(.t), 0, this)
                endif
                call TimerStart(.t, INTERVAL, true, function thistype.display)
            endif
            
            set .counter = .counter+1
            return .counter-1
        endmethod
        
        method updateMessage takes integer ptr, string msg returns nothing
            call SaveInteger(.hash, StringHash(msg), 0, ptr)
            call SaveReal(.hash, StringHash(msg), 1, LoadReal(.hash, StringHash(LoadStr(.hash, ptr, 0)), 1))
            call SaveReal(.hash, StringHash(msg), 2, LoadReal(.hash, StringHash(LoadStr(.hash, ptr, 0)), 2))
            call SaveReal(.hash, StringHash(msg), 3, LoadReal(.hash, StringHash(LoadStr(.hash, ptr, 0)), 3))
            call SaveReal(.hash, StringHash(msg), 4, LoadReal(.hash, StringHash(LoadStr(.hash, ptr, 0)), 4))
            call SaveStr(.hash, ptr, 0, msg)
        endmethod
        
        method updateByMessage takes string oldmsg, string newmsg returns nothing
            call .updateMessage(.findMessage(oldmsg), newmsg)
        endmethod
        
        method deleteMessage takes integer ptr returns nothing
            local integer i = ptr-1
            local string msg
            if LoadStr(.hash, ptr, this) == "" or ptr < 0 or .counter <= 0 then
                return
            endif
            loop
                set i = i+1
                exitwhen i >= .counter
                call SaveStr(.hash, i, this, LoadStr(.hash, i+1, this))
                set msg = LoadStr(.hash, i, this)
                call SaveInteger(.hash, StringHash(msg), 0, i)
                call SaveReal(.hash, StringHash(msg), 1, LoadReal(.hash, StringHash(msg), 1))
                call SaveReal(.hash, StringHash(msg), 2, LoadReal(.hash, StringHash(msg), 2))
                call SaveReal(.hash, StringHash(msg), 3, LoadReal(.hash, StringHash(msg), 3))
                call SaveReal(.hash, StringHash(msg), 4, LoadReal(.hash, StringHash(msg), 4))
            endloop
            set .counter = .counter-1
        endmethod
        
        method deleteByMsg takes string msg returns nothing
            call .deleteMessage(.findMessage(msg))
        endmethod
        
        method findMessage takes string msg returns integer
            local integer i = -1
            loop
                set i = i+1
                exitwhen i >= .counter
                if LoadStr(.hash, i, this) == msg then
                    return LoadInteger(.hash, StringHash(LoadStr(.hash, i, 0)), 0)
                endif
            endloop
            return -1
        endmethod
    endstruct
    
    function RegisterMessage takes string msg, real time, real x, real y, queue to returns integer
        return to.registerMessage(msg, time, x, y)
    endfunction
    
    function UpdateMessage takes integer ptr, string msg, queue to returns nothing
        call to.updateMessage(ptr, msg)
    endfunction
    
    function UpdateByMessage takes string oldstr, string newstr, queue to returns nothing
        call to.updateByMessage(oldstr, newstr)
    endfunction
    
    function DeleteMessage takes integer ptr, queue to returns nothing
        call to.deleteMessage(ptr)
    endfunction
    
    function DeleteByMessage takes string msg, queue to returns nothing
        call to.deleteByMsg(msg)
    endfunction
    
    function FindMessage takes string msg, queue to returns integer
        return to.findMessage(msg)
    endfunction
endlibrary

And because I for one like cJass
JASS:
    #include "cj_types.j"
    #include "cj_typesEX.j"

library_once MeQ
{

    #define
    {
        private INTERVAL        = 0.15
        private DEFAULT_TIME    = 5
        private DEFAULT_X       = 0
        private DEFAULT_Y       = 0
        private DEFAULT_FORCE   = bj_FORCE_ALL_PLAYERS
        private REVERSE         = true
    }

    private keyword queue
    queue Queue
    queue MessageQueue
    
    #define
    {
        <Queue.registerMessage>(msg)                        = Queue##.registerMessage(msg, DEFAULT_TIME, DEFAULT_X, DEFAULT_Y, DEFAULT_FORCE)
        <Queue.registerMessage>(msg, time)                  = Queue##.registerMessage(msg, time, DEFAULT_X, DEFAULT_Y, DEFAULT_FORCE)
        <Queue.registerMessage>(msg, x, y)                  = Queue##.registerMessage(msg, DEFAULT_TIME, x, y, DEFAULT_FORCE)
        <Queue.registerMessage>(msg, time, x, y)            = Queue##.registerMessage(msg, time, x, y, DEFAULT_FORCE)
        <Queue.registerMessage>(msg, time, x, y, to)        = Queue##.registerMessage(msg, time, x, y, to)
        
        <MessageQueue.registerMessage>(msg)                 = MessageQueue##.registerMessage(msg, DEFAULT_TIME, DEFAULT_X, DEFAULT_Y, DEFAULT_FORCE)
        <MessageQueue.registerMessage>(msg, time)           = MessageQueue##.registerMessage(msg, time, DEFAULT_X, DEFAULT_Y, DEFAULT_FORCE)
        <MessageQueue.registerMessage>(msg, x, y)           = MessageQueue##.registerMessage(msg, DEFAULT_TIME, x, y, DEFAULT_FORCE)
        <MessageQueue.registerMessage>(msg, time, x, y)     = MessageQueue##.registerMessage(msg, time, x, y, DEFAULT_FORCE)
        <MessageQueue.registerMessage>(msg, time, x, y, to) = MessageQueue##.registerMessage(msg, time, x, y, to)
        
        <RegisterMessage>(msg)                              = Register##Message(msg, DEFAULT_TIME, DEFAULT_X, DEFAULT_Y, DEFAULT_FORCE)
        <RegisterMessage>(msg, time)                        = Register##Message(msg, time, DEFAULT_X, DEFAULT_Y, DEFAULT_FORCE)
        <RegisterMessage>(msg, x, y)                        = Register##Message(msg, DEFAULT_TIME, x, y, DEFAULT_FORCE)
        <RegisterMessage>(msg, time, x, y)                  = Register##Message(msg, time, x ,y, DEFAULT_FORCE)
        <RegisterMessage>(msg, time, x, y, to)              = Register##Message(msg, time, x ,y, to)
    }
    
    private struct queue extends array
    {
        readonly static int counter = 0
        private static hashtable hash
        private static void onInit()
        {
            .hash = new hashtable
            
            TimerStart(new timer, INTERVAL, true, function thistype.display)
        }
        
        private static void display()
        {
            int i
            int k = -1
            string msg
            ClearTextMessages()
            if REVERSE
            {
                i = .counter
                do
                {
                    exitwhen --i <= -1
                    msg = LoadStr(.hash, i, 0)
                    if IsPlayerInForce(GetLocalPlayer(), LoadForceHandle(.hash, StringHash(msg), 5))
                    {
                        DisplayTimedTextToPlayer(GetLocalPlayer(), LoadReal(.hash, StringHash(msg), 3), LoadReal(.hash, StringHash(msg), 4), INTERVAL, msg)
                    }
                    SaveReal(.hash, StringHash(msg), 2, LoadReal(.hash, StringHash(msg), 2)+INTERVAL)
                    if LoadReal(.hash, StringHash(msg), 2) >= LoadReal(.hash, StringHash(msg), 1)
                    {
                        .deleteMessage(i)
                    }
                }
            }
            else
            {
                i = -1
                do
                {
                    exitwhen ++i >= .counter
                    msg = LoadStr(.hash, i, 0)
                    if IsPlayerInForce(GetLocalPlayer(), LoadForceHandle(.hash, StringHash(msg), 5))
                    {
                        DisplayTimedTextToPlayer(GetLocalPlayer(), LoadReal(.hash, StringHash(msg), 3), LoadReal(.hash, StringHash(msg), 4), INTERVAL, msg)
                    }
                    SaveReal(.hash, StringHash(msg), 2, LoadReal(.hash, StringHash(msg), 2)+INTERVAL)
                    if LoadReal(.hash, StringHash(msg), 2) >= LoadReal(.hash, StringHash(msg), 1)
                    {
                        .deleteMessage(i)
                    }
                }
            }
        }
        
        static int registerMessage(string msg, float time, float x, float y, force to)
        {
            SaveStr(.hash, .counter, 0, msg)
            SaveInteger(.hash, StringHash(msg), 0, .counter)
            SaveReal(.hash, StringHash(msg), 1, time)
            SaveReal(.hash, StringHash(msg), 2, 0)
            SaveReal(.hash, StringHash(msg), 3, x)
            SaveReal(.hash, StringHash(msg), 4, y)
            SaveForceHandle(.hash, StringHash(msg), 5, to)
            .counter++ 
            return .counter-1
        }
        
        static void updateMessage(int ptr, string msg)
        {
            SaveInteger(.hash, StringHash(msg), 0, ptr)
            SaveReal(.hash, StringHash(msg), 1, LoadReal(.hash, StringHash(LoadStr(.hash, ptr, 0)), 1))
            SaveReal(.hash, StringHash(msg), 2, LoadReal(.hash, StringHash(LoadStr(.hash, ptr, 0)), 2))
            SaveReal(.hash, StringHash(msg), 3, LoadReal(.hash, StringHash(LoadStr(.hash, ptr, 0)), 3))
            SaveReal(.hash, StringHash(msg), 4, LoadReal(.hash, StringHash(LoadStr(.hash, ptr, 0)), 4))
            SaveForceHandle(.hash, StringHash(msg), 5, LoadForceHandle(.hash, StringHash(LoadStr(.hash, ptr, 0)), 5))
            SaveStr(.hash, ptr, 0, msg)
        }
        
        static void updateByMessage(string oldmsg, string newmsg)
        {
            .updateMessage(.findMessage(oldmsg), newmsg)
        }
        
        static void deleteMessage(int ptr)
        {
            int i = ptr-1
            string msg
            if LoadStr(.hash, ptr, 0) == "" || ptr < 0 || .counter <= 0 {return}
            do
            {
                exitwhen ++i >= .counter
                SaveStr(.hash, i, 0, LoadStr(.hash, i+1, 0))
                msg = LoadStr(.hash, i, 0)
                SaveInteger(.hash, StringHash(msg), 0, i)
                SaveReal(.hash, StringHash(msg), 1, LoadReal(.hash, StringHash(msg), 1))
                SaveReal(.hash, StringHash(msg), 2, LoadReal(.hash, StringHash(msg), 2))
                SaveReal(.hash, StringHash(msg), 3, LoadReal(.hash, StringHash(msg), 3))
                SaveReal(.hash, StringHash(msg), 4, LoadReal(.hash, StringHash(msg), 4))
                SaveForceHandle(.hash, StringHash(msg), 5, LoadForceHandle(.hash, StringHash(LoadStr(.hash, ptr, 0)), 5))
            }
            .counter--
        }
        
        static void deleteByMsg(string msg)
        {
            .deleteMessage(.findMessage(msg))
        }
        
        static int findMessage(string msg)
        {
            int i = -1
            do
            {
                exitwhen ++i >= .counter
                if LoadStr(.hash, i, 0) == msg {return LoadInteger(.hash, StringHash(LoadStr(.hash, i, 0)), 0)}
            }
            return -1
        }
    }
    
    int RegisterMessage(string msg, float time, float x, float y, force to)
    {
        return Queue.registerMessage(msg, time, x, y, to)
    }
    
    void UpdateMessage(int ptr, string msg)
    {
        Queue.updateMessage(ptr, msg)
    }
    
    void UpdateByMessage(string oldstr, string newstr)
    {
        Queue.updateByMessage(oldstr, newstr)
    }
    
    void DeleteMessage(int ptr)
    {
        Queue.deleteMessage(ptr)
    }
    
    void DeleteByMessage(string msg)
    {
        Queue.deleteByMsg(msg)
    }
    
    int FindMessage(string msg)
    {
        return Queue.findMessage(msg)
    }
}

JASS:
    #include "cj_types.j"
    #include "cj_typesEX.j"

library_once MeQ
{

    #define
    {
        private INTERVAL        = 0.15
        private DEFAULT_TIME    = 5
        private DEFAULT_X       = 0
        private DEFAULT_Y       = 0
        private REVERSE         = true
    }

    private keyword queue
    queue array Queue
    queue array MessageQueue
    
    private struct queue
    {
        readonly int counter = 0
        readonly timer t = null
        private static hashtable hash
        private static void onInit()
        {
            int i = -1
            timer t
            do
            {
                exitwhen ++i >= 12
                if GetPlayerSlotState(Player(i)) == PLAYER_SLOT_STATE_PLAYING
                {
                    Queue[i] = thistype.allocate()
                    MessageQueue[i] = Queue[i]
                }
            }
        
            .hash = new hashtable
        }
        
        private static void display()
        {
            thistype this = LoadInteger(.hash, GetHandleId(GetExpiredTimer()), 0)
            int i
            int k = -1
            string msg
            ClearTextMessages()
            if REVERSE
            {
                i = .counter
                do
                {
                    exitwhen --i <= -1
                    msg = LoadStr(.hash, i, this)
                    DisplayTimedTextToPlayer(Player(this-1), LoadReal(.hash, StringHash(msg), 3), LoadReal(.hash, StringHash(msg), 4), INTERVAL, msg)
                    SaveReal(.hash, StringHash(msg), 2, LoadReal(.hash, StringHash(msg), 2)+INTERVAL)
                    if LoadReal(.hash, StringHash(msg), 2) >= LoadReal(.hash, StringHash(msg), 1)
                    {
                        .deleteMessage(i)
                    }
                }
            }
            else
            {
                i = -1
                do
                {
                    exitwhen ++i >= .counter
                    msg = LoadStr(.hash, i, this)
                    DisplayTimedTextToPlayer(Player(this-1), LoadReal(.hash, StringHash(msg), 3), LoadReal(.hash, StringHash(msg), 4), INTERVAL, msg)
                    SaveReal(.hash, StringHash(msg), 2, LoadReal(.hash, StringHash(msg), 2)+INTERVAL)
                    if LoadReal(.hash, StringHash(msg), 2) >= LoadReal(.hash, StringHash(msg), 1)
                    {
                        .deleteMessage(i)
                    }
                }
            }
            
            if .counter == 0 {ClearTextMessages(); PauseTimer(.t)}
        }
        
        int registerMessage(string msg, float time, float x, float y)
        {
            SaveStr(.hash, .counter, this, msg)
            SaveInteger(.hash, StringHash(msg), 0, .counter)
            SaveReal(.hash, StringHash(msg), 1, time)
            SaveReal(.hash, StringHash(msg), 2, 0)
            SaveReal(.hash, StringHash(msg), 3, x)
            SaveReal(.hash, StringHash(msg), 4, y)
            
            if .counter == 0
            {
                if .t == null
                {
                    .t = new timer
                    SaveInteger(.hash, GetHandleId(.t), 0, this)
                }
                TimerStart(.t, INTERVAL, true, function thistype.display)
            }
            
            .counter++ 
            return .counter-1
        }
        
        void updateMessage(int ptr, string msg)
        {
            SaveInteger(.hash, StringHash(msg), 0, ptr)
            SaveReal(.hash, StringHash(msg), 1, LoadReal(.hash, StringHash(LoadStr(.hash, ptr, 0)), 1))
            SaveReal(.hash, StringHash(msg), 2, LoadReal(.hash, StringHash(LoadStr(.hash, ptr, 0)), 2))
            SaveReal(.hash, StringHash(msg), 3, LoadReal(.hash, StringHash(LoadStr(.hash, ptr, 0)), 3))
            SaveReal(.hash, StringHash(msg), 4, LoadReal(.hash, StringHash(LoadStr(.hash, ptr, 0)), 4))
            SaveStr(.hash, ptr, 0, msg)
        }
        
        void updateByMessage(string oldmsg, string newmsg)
        {
            .updateMessage(.findMessage(oldmsg), newmsg)
        }
        
        void deleteMessage(int ptr)
        {
            integer i = ptr-1
            string msg
            if LoadStr(.hash, ptr, 0) == "" || ptr < 0 || .counter <= 0 {return}
            do
            {
                exitwhen ++i >= .counter
                SaveStr(.hash, i, this, LoadStr(.hash, i+1, this))
                msg = LoadStr(.hash, i, this)
                SaveInteger(.hash, StringHash(msg), 0, i)
                SaveReal(.hash, StringHash(msg), 1, LoadReal(.hash, StringHash(msg), 1))
                SaveReal(.hash, StringHash(msg), 2, LoadReal(.hash, StringHash(msg), 2))
                SaveReal(.hash, StringHash(msg), 3, LoadReal(.hash, StringHash(msg), 3))
                SaveReal(.hash, StringHash(msg), 4, LoadReal(.hash, StringHash(msg), 4))
            }
            .counter--
        }
        
        void deleteByMsg(string msg)
        {
            .deleteMessage(.findMessage(msg))
        }
        
        int findMessage(string msg)
        {
            int i = -1
            do
            {
                exitwhen ++i >= .counter
                if LoadStr(.hash, i, this) == msg {return LoadInteger(.hash, StringHash(LoadStr(.hash, i, 0)), 0)}
            }
            return -1
        }
    }
    
    int RegisterMessage(string msg, float time, float x, float y, queue to)
    {
        return to.registerMessage(msg, time, x, y)
    }
    
    void UpdateMessage(int ptr, string msg, queue to)
    {
        to.updateMessage(ptr, msg)
    }
    
    void UpdateByMessage(string oldstr, string newstr, queue to)
    {
        to.updateByMessage(oldstr, newstr)
    }
    
    void DeleteMessage(int ptr, queue to)
    {
        to.deleteMessage(ptr)
    }
    
    void DeleteByMessage(string msg, queue to)
    {
        to.deleteByMsg(msg)
    }
    
    int FindMessage(string msg, queue to)
    {
        return to.findMessage(msg)
    }
}
 
Last edited:
Level 11
Joined
Feb 22, 2006
Messages
752
Hashtables vs. arrays for something like this really doesn't matter. If you're spamming so many messages per second enough to actually need that kind of efficiency, then:

1. You're crazy. :p
2. You don't need queueing anyway.

Btw, some documentation on this would be nice.

EDIT:

Tested it. Function name of UpdateMessage is spelled wrong...it's currently "UpdateMassage". And the function itself doesn't seem to be working. And right now it's kind of limited as to which players the queue can be used for. It would be nice if each player had its own queue.
 
Last edited:
Level 11
Joined
Apr 29, 2007
Messages
826
Hashtables vs. arrays for something like this really doesn't matter. If you're spamming so many messages per second enough to actually need that kind of efficiency, then:

1. You're crazy. :p
2. You don't need queueing anyway.

Atleast someone here who argues with me.

Btw, some documentation on this would be nice.
Yeah, I've waited for this until I've finished it(since I've planned some features, but wasn't sure if I'd really do those)

EDIT:

Tested it. Function name of UpdateMessage is spelled wrong...it's currently "UpdateMassage". And the function itself doesn't seem to be working. And right now it's kind of limited as to which players the queue can be used for. It would be nice if each player had its own queue.
ups, lol. :D
And yeah no wonder it isn't working. I forgot that the data is saved under the StringHash of the message.. and when you change the message, it won't load anything ofcourse.
Thought I'd somehow come around that, but I guess that I have to specify the players to which it's shown aswell.


e/ ok, UPDATED. You now have to specify a force to which the text gets displayed to. (The cJass defines make the usage so much easier :/)

e2/ UPDATED again. Now with a version which creates an struct for each player.
 
Last edited:
Level 14
Joined
Nov 18, 2007
Messages
816
use struct member variables. Not for speed reasons, but for readability reasons.

I hope you know that theres a limit on how many in-game-messages can be displayed before it makes the fps drop to ~2? With 4 messages constantly displayed, you will have displayed 20k messages in 12.5 minutes.
 
Level 11
Joined
Apr 29, 2007
Messages
826
use struct member variables. Not for speed reasons, but for readability reasons.

Those libraries here shouldn't be mainly about readability but about functionality. So, who cares? Anyone has another specification of what he likes.

I hope you know that theres a limit on how many in-game-messages can be displayed before it makes the fps drop to ~2? With 4 messages constantly displayed, you will have displayed 20k messages in 12.5 minutes.
Huh? I never had any problems with too many text messages.
 

LeP

LeP

Level 13
Joined
Feb 13, 2008
Messages
539
Those libraries here shouldn't be mainly about readability but about functionality. So, who cares?
Good code is readable code and only good code should be accepted in a resource database.

Have fun writing your shitty code and maintaining it but in the moment you "opensource" it, we all have the problems of reading your code.
Imagine you leave wc3-modding and someone have to update your resource.
He would be realy happy 'bout some nice code.
Ohh, you will also like clean code if you have to update this after some months.
 
Level 11
Joined
Apr 29, 2007
Messages
826
Good code is readable code and only good code should be accepted in a resource database.

Have fun writing your shitty code and maintaining it but in the moment you "opensource" it, we all have the problems of reading your code.
Imagine you leave wc3-modding and someone have to update your resource.
He would be realy happy 'bout some nice code.
Ohh, you will also like clean code if you have to update this after some months.

Calm down dude, why do people always search for unnecessary things to complain about. Seriously, why would anyone need to "update" this?
 
Level 11
Joined
Apr 29, 2007
Messages
826

Ok I see, I tried it out. After some time the FPS slowly starts to drop, but when you hit F12, you have a short freeze and the FPS is back to its standard. Don't know why it is so, but I think I can't do anything about that.

Because those things are not as unnecessary as you think they are.
*sigh*, what do you think should I do to increase readability? -_-
 
Good code is readable code and only good code should be accepted in a resource database.

Have fun writing your shitty code and maintaining it but in the moment you "opensource" it, we all have the problems of reading your code.
Imagine you leave wc3-modding and someone have to update your resource.
He would be realy happy 'bout some nice code.
Ohh, you will also like clean code if you have to update this after some months.


Good code is code that does not leak, is useful, and is easy to use.
Who gives a damn if it's readable. It just needs to work. 90% of the time, you won't need to read the code. The other 10%, it won't matter, because you'll know what it is your looking for.

You, sir, are a noob in terms of what is good code.
I myself can read it fine.

Oh, and arrays are 25% faster than hashtables, if I remember correctly.
Nice job, using cJASS too. Any chance for a Zinc version? :D

Oh, one last thing: COMMENT CODE PLOX.
 

LeP

LeP

Level 13
Joined
Feb 13, 2008
Messages
539
You, sir, are a noob in terms of what is good code.

"The Newest JASS noob."
( ≖‿≖)

Good code is code that does not leak, is useful, and is easy to use.
Who gives a damn if it's readable. It just needs to work. 90% of the time, you won't need to read the code. The other 10%, it won't matter, because you'll know what it is your looking for.

Ok, i'll start with a quote:
"Code is read much more often than it is written."
Realy, write it once nice nave have problems again.

Sometime you will understand...

Ohh, and since the code have to be approved someone have to read it. Probably a moderator. Just of this we got a reasons for readable code: the moderator does the review in his free time so make his work as easy as possible.

And since it is a public resource it should be easy as possible to modify the source. I would rather write the "system" myself to be able to easy add features then have to work with some shitty code.
(Ok, only if the "system" is small.)
 
lol I added that like months ago when I started learning JASS as a joke.

And I know the jobs of resource moderators. I don't want to sound rude by saying this, but if a resource mod can't suck it up and read the code, ugly or not, they should be replaced. A staff member who doesn't do there jobs is just a member with a fancy title. (coming from an admin of another forum who's demoted people for not doing jobs)
Now, I'm not trying to be rude or disrespectful to any staff member by saying that. I'm just giving you my opinion.

Anyway, the code was readable to me. Try getting some glasses. Might help you read it.
 
Level 14
Joined
Nov 18, 2007
Messages
816
fucking no. That code was frowned upon before 1.24.
Its the same as if you were using Handle Vars (only that instead of the a bit more descriptive "Caster" as the second key, you use integers and one has to guess from context what the fuck they store). Also, struct variables are more efficient AND easier to read AND easier to write (that is...less thinking involved and the resulting code is shorter).

I dont know where you pulled the 25% from. Tests i have seen indicate that hashtables take roughly 175% of the time arrays take.
 
Level 8
Joined
Oct 3, 2008
Messages
367
Graveyarded because:
  • It leaks a lot, and there's nothing we can do to fix it.
  • It lags after time.
  • It really isn't all that useful in my own opinion.
  • There are still inefficiencies that were not fixed (a lesser point).
 
Top