Snippet Recycle

Jesus4Lyf

Good Idea™
Reaction score
397
>So do you guys really want me to submit this (when and if cJASS gets approved, lol)
No, we want you to write some code we can actually read.
Hence Recycle. People are like, So much stuff that does that already. I'm saying that the stuff that does it already is wrong. Why? It couples a resource you don't necessarily need with a resource that you do need.
I thought it obvious that we don't need Recycle coupled to cJass on the same principle.

You are basically saying it is "wrong" whether or not TH approves cJass. Or maybe your principles should only be applied when it suits you. Maybe it's not wrong for you, only everyone else.
 

Nestharus

o-o
Reaction score
84
Misconstrued my meaning entirely jesus4lyf. I'm talking about code that does extra stuff that someone doesn't necessarily need, thus lowering the overall performance of the code.


For example, if you were to write something to recycle handles, well, you'd expect it to recycle handles. What if you suddenly want to do data attachment in the same thingie? Now it recycles handles and does data attachment all in the same function. Someone who only wanted to recycle the handle would get a loss of performance by the extra wasted function ^_-.

Minimize Coupling
Maximize Cohesion

That is what I mean jesus4lyf : )
 

Nestharus

o-o
Reaction score
84
Updated Recycle and released C Recycle

Recycle:
Now includes an auto clear mode and debug mode. In essence, you can determine whether or not recycle will auto clear recycled handles (GroupClear, PauseTimer). You can also put recycle into debug mode by itself just like regular debug ;).

Edit
Added optional red/blue data attachment very similar to TimerUtils ;).


C Recycle:
Will come out when LSO is out : ).
 

Jesus4Lyf

Good Idea™
Reaction score
397
JASS:
private constant boolean AUTO_CLEAR = false

I can't believe that you just broke backwards compatibility for everything using this system. You really astound me. You are absolutely useless as a system writer if you have an attitude that no one else matters except yourself.

For example, you just broke this, which is a fantastic system (which took a lot more effort than this) but apparently the author should not have trusted you. You also have betrayed my trust in some sort of permanent way, for writing something which was meant to be a standard but then breaking backwards compatibility on it.

JASS:
private constant boolean AUTO_CLEAR = false

-->
JASS:
private constant boolean AUTO_CLEAR = true

Fix the bug (which I have assumed was intentional but no doubt you'll now say it wasn't).
Current Version:
JASS:
library Recycle initializer Initialization
//settings
globals
    private constant boolean AUTO_CLEAR = false
    private constant boolean DEBUG = false
    private constant boolean ATTACH_RED = false
    private constant boolean ATTACH_BLUE = false
endglobals
/*Utility Information
//===================================================================
Name: Recycle
Version: 5.0
Author: Nestharus
-Help from Jesus4Lyf for initial designs

Description:
    What does it do-
        Recycles handles so that when getting new handles of the same type,
        a recycled handle can be returned instead of creating a new handle. This
        increases map performance.
        
Requirements: NA

Installation: NA

Variables:
------------------------------------------------------------------
AUTO_CLEAN-
    If true, will automatically clear out recycled handles (GroupClear,
    PauseTimer) at a slight performance hit.
    
DEBUG-
    Debug mode for Recycle. This is so you don't have to put the entire map
    into debug mode to debug only Recycle.
    
ATTACH_RED-
    Similiar to TimerUtils/GroupUtils red
    
ATTACH_BLUE-
    Similiar to TimerUtils/GroupUtils blue

Functions:
------------------------------------------------------------------
-get returns type
    will return the type
    
    Timer.get()
    Group.get()
    
    ex-
    timer t = Timer.get()

-release(type h)
    Will release the type and stop it.
    
    Timer.release(h)
    Group.release(h)
    
    ex-
    timer t = Timer.get()
    Timer.release(t)

*THESE ARE ONLY ENABLED IF ATTACH_RED OR ATTACH_BLUE ARE TRUE*
-setData(type var, integer value)
    Sets integer data on type
    
    Timer.setData(myTimer, 5)
    Group.setData(myGroup, 5)

-getData(type var) returns integer
    Gets integer data on type
    
    local integer hello = Timer.getData(myTimer)
    local integer hello = Group.getData(myGroup)
------------------------------------------------------------------*/
    globals
        private timer privateTimer
        private integer offset
        private hashtable memory
    endglobals
    //! textmacro CREATE_STACK takes name, type, clean, create
        struct $name$ extends array
            private $type$ handles
            private static integer index = 0
            private static integer array data
            
            public static method setData takes $type$ var, integer value returns nothing
                static if ATTACH_RED
                    static if DEBUG then
                        if GetHandleId(var)-offset > 8191 then
                            call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, "ERROR - Attach: Too many handles.")
                            return
                        endif
                    endif
                    set .data[GetHandleId(var)-offset] = value
                endif
                static if ATTACH_BLUE
                    call SaveInteger(memory, GetHandleId(var), 0, value)
                endif
            endmethod
            
            public static method getData takes $type$ var returns integer
                static if ATTACH_RED
                    return .data[GetHandleId(var)-offset]
                endif
                static if ATTACH_BLUE
                    return LoadInteger(memory, GetHandleId(var), 0)
                endif
                return 0
            endmethod

            public static method release takes $type$ h returns nothing
                static if DEBUG then
                    if h == null then
                        call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, "ERROR - Recycle: Freed null handle.")
                    endif
                    if $name$.index > 8190 then
                        call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, "ERROR - Recycle: Overfilled recycle stack (8191 released objects)!")
                    endif
                endif
                static if AUTO_CLEAR then
                    $clean$
                endif
                set $name$[$name$.index].handles = h
                set $name$.index = $name$.index + 1
                static if ATTACH_RED
                    static if DEBUG then
                        if GetHandleId(var)-offset > 8191 then
                            call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, "ERROR - Attach: Too many handles.")
                            return
                        endif
                    endif
                    set .data[GetHandleId(h)-offset] = 0
                endif
                static if ATTACH_BLUE
                    call FlushChildHashtable(memory, GetHandleId(h))
                endif
            endmethod

            public static method get takes nothing returns $type$
                if $name$.index == 0 then
                    return $create$
                endif
                set $name$.index = $name$.index - 1
                return $name$[$name$.index].handles
            endmethod
        endstruct
    //! endtextmacro
    
    //! runtextmacro CREATE_STACK("Timer", "timer", "call PauseTimer(h)", "CreateTimer()")
    //! runtextmacro CREATE_STACK("Group", "group", "call GroupClear(h)", "CreateGroup()")
    
    private function Initialization takes nothing returns nothing
        static if ATTACH_RED
            set privateTimer = CreateTimer()
            set offset = GetHandleId(privateTimer)
            call Timer.release(privateTimer)
            set privateTimer = null
        endif
        static if ATTACH_BLUE
            set memory = InitHashtable()
        endif
    endfunction
endlibrary
 

Nestharus

o-o
Reaction score
84
Sry, fixed

Wasn't thinking about it when I set it to false

No need to get all hyped it, it's a single var change ><
 

Jesus4Lyf

Good Idea™
Reaction score
397
Cheers. :)
JASS:
            public static method setData takes $type$ var, integer value returns nothing
                static if ATTACH_RED
                    static if DEBUG then
                        if GetHandleId(var)-offset &gt; 8191 then
                            call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, &quot;ERROR - Attach: Too many handles.&quot;)
                            return
                        endif
                    endif
                    set .data[GetHandleId(var)-offset] = value
                endif
                static if ATTACH_BLUE
                    call SaveInteger(memory, GetHandleId(var), 0, value)
                endif
            endmethod

Let's talk about this. Your red attachment is utterly unstable and should never be released (for obvious reasons) and I request you remove it. Your blue implementation is simple hashtable attachment, which is brilliant but has nothing to do with recycling. You have said so yourself that Recycle should not attach data. Users are capable of writing the hashtable line, no need to confuse your interfaces, remove both the blue & red attach stuff.

:)
 

Nestharus

o-o
Reaction score
84
That's a definite thought, this was just an initial design to trying to get data attachment implemented. It'd be better as a separate library that used Recycling's internal vars.

Edit
Updated Recycle

Shall I submit Data as a separate thing? (it's 100% coupled with Recycle and uses internal vars, which is why I had to make that stuff public)
Or should I put it in the same post since it's like an add on?

Also, for data red attachment style, it does retrieve an offset at the start ;p. Other than that, I can try to make it more stable ; ).
 

Jesus4Lyf

Good Idea™
Reaction score
397
Yay, it's gone. :thup:

Feel free to post it here (not in the first post, just in a new post) so people can discuss it and give feedback on it. I definitely think Recycle should not attach data, but a separate lib that does things like data attachment may be ok. If you post it, I may be able to give some suggestions as to how to can go about it, or say users should just hashtable implement stuff instead. :p

Honestly, you will never make RED attachment work without preloading stuff. At which point, this becomes TimerUtils.

>Debug mode for Recycle. This is so you don't have to put the entire map into debug mode to debug only Recycle.
I think that's annoying.

Edit:
JASS:
globals
    public constant boolean AUTO_CLEAR = true
    public constant boolean DEBUG = false
endglobals

-->
JASS:
globals
    private constant boolean AUTO_CLEAR = true
endglobals


JASS:
static if DEBUG then

-->
JASS:
static if DEBUG_MODE then


JASS:
public $type$ handles
            public static integer index = 0

I think the public keyword can be omitted. Why are these exposed, again? Encapsulation is nicer.
 

Nestharus

o-o
Reaction score
84
1. on DEBUG
Idea with this is so that you can have only certain utilities and what not in your given map spewing out debug messages. It's a practice I just started up : p. Rather than relying on a global debug where some systems that you don't even care to see messages from spew stuff out thus cluttering the stuff you are looking for, you only put the stuff you actually want to see in debug mode.


2. On public
Those were exposed in this version (previously private) so that Data could access them ^_^
 

Jesus4Lyf

Good Idea™
Reaction score
397
>It's a practice I just started up
And I'm asking nicely that you may stop. Debug messages are critical errors, why would you ever want them not to be displayed when you are working on a map... don't make your users flick a switch for every system they have before releasing, that's tragic. :(

>Those were exposed in this version (previously private) so that Data could access them ^_^
Can it wait until Data is approved? Just include a version of recycle in the Data thread until Data is approved (if ever, which I doubt).
 

Nestharus

o-o
Reaction score
84
Ah, but what if you have 30 systems in your map and 29 are working but one isn't? It uses recycle, so you'd like to see recycle debug messages along with its messages, but you want to avoid the other 28. You flag only both of them.

What if you have a system that doesn't use Recycle at all and it doesn't work?

etc

I run into this all the time, which is why I started this practice. It's like 100% necessary in stuff I work on ><. AGL alone floods the entire screen with debug messages in a few commands ><, so I really want only things that are meant to be displayed to be displayed at this point.


Then again, you are right in that Recycle only has critical error debugs in it, lol. Stuff I normally work on has debug messages for tracking memory changes ;\.

I guess I should change this into global debug ; ).
 

Kenny

Back for now.
Reaction score
202
What do you think about adding something like this:

JASS:
function New$name$ takes nothing returns $type$
    return $name$.get()
endfunction

function Release$name$ takes $type$ h returns nothing
    call $name$.release(h)
endfunction


For those of us who like the old school stuff? :p

You could also add some static ifs to check if the user has TimerUtils and/or GroupUtils imported, and not add the functions to stop conflicts.

Just a thought.

(I already added them myself, but I thought they would be a nice addition)

Edit:

Also, I'm not to sure if AUTO_CLEAR will ever be set to false for most people...

I for one would like my timers paused when they are recycled, and groups being cleaned doesn't bother me.

The performance difference is negligible in this situation, and I see no need to remove those calls except for an incredibly minimal efficiency increase.

+1 for removing AUTO_CLEAR. :) Unless you can give substantial evidence into why it is needed.
 

Jesus4Lyf

Good Idea™
Reaction score
397
>You could also add some static ifs to check if the user has TimerUtils and/or GroupUtils imported, and not add the functions to stop conflicts.
How?

It would conflict, I'm pretty sure. Regardless.

>+1 for removing AUTO_CLEAR.
Or rename it AUTO_BREAK_EVERY_SYSTEM_USING_THIS. 'Cos that's all it achieves so far.
 

Kenny

Back for now.
Reaction score
202
>How?

For a second there I thought you could use [ljass]not[/ljass] in static ifs, but I don't think you can.

I guess you could do something like:

JASS:
static if LIBRARY_TimerUtils then // If you could use &#039;not&#039; it would be a lot easier.
    function GetTimer takes nothing returns timer
        return Timer.get()
    endfunction
else
    function NewTimer takes timer h returns nothing
        call Timer.release(h)
    endfunction
endif


But it doesn't really matter anymore, seeing as static ifs outside functions wont be around for much longer.
 

Nestharus

o-o
Reaction score
84
ok, I'm on ; )

Also, I'm not to sure if AUTO_CLEAR will ever be set to false for most people...

I for one would like my timers paused when they are recycled, and groups being cleaned doesn't bother me.

The performance difference is negligible in this situation, and I see no need to remove those calls except for an incredibly minimal efficiency increase.

+1 for removing AUTO_CLEAR. Unless you can give substantial evidence into why it is needed.

I added it in because I needed it for a map once and I was like, why not, won't hurt anyone ; p. As it stands, it doesn't do any harm, and if you aren't using any systems that need to clear out (I have quite a few that don't need to clear out), then it's helpful =).

>But it doesn't really matter anymore, seeing as static ifs outside functions wont be around for much longer.
That's what I meant by "how".
Also, I think it still counts as a redeclaration already...

Yea... last time I tried static ifs it didn't throw a syntax error, but it never results in true : |, and that was only a few days ago. I don't really trust them outside of functions. Until Vexorian says they can be used out of functions and supports it, only way to have that kind of modularity is with cJASS definitions ><.

JASS:

static if LIBRARY_TimerUtils then // If you could use &#039;not&#039; it would be a lot easier.
    function GetTimer takes nothing returns timer
        return Timer.get()
    endfunction
else
    function NewTimer takes timer h returns nothing
        call Timer.release(h)
    endfunction
endif


If you are using TimerUtils, then you are having two collections and it kills the point of even using Recycle : ). I know I released a utility that acts just like TimerUtils but runs off of Recycle and has the same sort of syntax as Recycle : \. In short, if you are using TimerUtils, I don't expect you to be using this, lol : P.

As for the functions-
JASS:

function NewTimer takes timer h returns nothing
        call Timer.release(h)
    endfunction


NewTimer wouldn't be removed from code file since it has a parameter ><, so that'd actually be hurtful ;\. I'd do it if it were a definition, lol.

Personally, I'm more for c# style, but I suppose some are more for procedural style, so I'll try and figure out a way to do it in vJASS without incrementing the code for a lot of people without a good reason ><.
 

Kenny

Back for now.
Reaction score
202
Well to be honest, it doesn't bother me much, i rewrote this to suit me anyway. No AUTO_CLEAR and those functions I asked for.

I find [ljass]Timer.get()[/ljass] pretty horrible. Something like [ljass]Timer.retrieve()[/ljass] looks better to me. Obviously that is just personal opinion though. Many would think differently.
 

Nestharus

o-o
Reaction score
84
Really should be something like-
Timer.retrieve()
Timer.throw() or Timer.release()

as this is really a pool ; ), but I chose what most people are comfortable with ;o.

Actually, release is generally used ; D, I just think throw it back into the pool and fish it out : p
 

Jesus4Lyf

Good Idea™
Reaction score
397
>Personally, I'm more for c# style, but I suppose some are more for procedural style, so I'll try and figure out a way to do it in vJASS without incrementing the code for a lot of people without a good reason ><.

No, hopefully you just stop trying to change things.

>If you are using TimerUtils, then you are having two collections and it kills the point of even using Recycle : )

No, maybe you like group recycling.

>I'm more for c# style

Maybe this has nothing to do with C#, since it should be timer.get() if it was... else the type would be Timer.

>Timer.retrieve()
I agree, but it is more typing, so who cares. As long as the interface of this stays the same, and doesn't randomly provide multiple function names to the same thing, I'm pretty satisfied.
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top