[snippet] AllocLoop (AKA Alloc 2)

Scripts

14 years
edited 8 years
Based on Alloc by Sevion, this version adds the possibility to make struct iteration. The idea of this snippet has credits for PurgeandFire.

In other words: this is Alloc version 1.09 with an extension to manage struct iterations. As a side note, this snippet is almost the core of PoC, and helped me to optimize the spell coding on it. So I ensure it works :)

Here's the code:

Code (jass) Select
1
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2
//~~ AllocLoop ~~ by moyack ~~ Version 1.0 ~~ Variant version of...
3
//~~ Alloc ~~ By Sevion ~~ Version 1.09 ~~
4
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5
//
6
//  What is Alloc?
7
//         - Alloc implements an intuitive allocation method for array structs
8
//
9
//    =Pros=
10
//         - Efficient.
11
//         - Simple.
12
//         - Less overhead than regular structs.
13
//
14
//    =Cons=
15
//         - Must use array structs (hardly a con).
16
//         - Must manually call OnDestroy.
17
//         - Must use Delegates for inheritance.
18
//         - No default values for variables (use onInit instead).
19
//         - No array members (use another Alloc struct as a linked list or type declaration).
20
//
21
//    Methods:
22
//         - struct.allocate()
23
//         - struct.deallocate()
24
//
25
//           These methods are used just as they should be used in regular structs.
26
//
27
//    Modules:
28
//         - Alloc
29
//           Implements the most basic form of Alloc. Includes only create and destroy
30
//           methods.
31
//
32
//  Details:
33
//         - Less overhead than regular structs
34
//
35
//         - Use array structs when using Alloc. Put the implement at the top of the struct.
36
//
37
//         - Alloc operates almost exactly the same as default structs in debug mode with the exception of onDestroy.
38
//
39
//  How to import:
40
//         - Create a trigger named Alloc.
41
//         - Convert it to custom text and replace the whole trigger text with this.
42
//
43
//  Thanks:
44
//         - Nestharus for the method of allocation and suggestions on further merging.
45
//         - Bribe for suggestions like the static if and method names.
46
//         - PurgeandFire111 for some suggestions like the merging of Alloc and AllocX as well as OnDestroy stuff.
47
//
48
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
49
library Alloc    
50
    //! textmacro Alloc
51
        private static integer instanceCount = 0
52
        private thistype recycle
53
    
54
        static method allocate takes nothing returns thistype
55
            local thistype this
56
    
57
            if (thistype(0).recycle == 0) then
58
                debug if (instanceCount == 8190) then
59
                    debug call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, "Alloc ERROR: Attempted to allocate too many instances!")
60
                    debug return 0
61
                debug endif
62
                set instanceCount = instanceCount + 1
63
                set this = instanceCount
64
            else
65
                set this = thistype(0).recycle
66
                set thistype(0).recycle = thistype(0).recycle.recycle
67
            endif
68
69
            debug set this.recycle = -1
70
    
71
            return this
72
        endmethod
73
    
74
        method deallocate takes nothing returns nothing
75
            debug if (this.recycle != -1) then
76
                debug call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, "Alloc ERROR: Attempted to deallocate an invalid instance at [" + I2S(this) + "]!")
77
                debug return
78
            debug endif
79
80
            set this.recycle = thistype(0).recycle
81
            set thistype(0).recycle = this
82
        endmethod
83
    //! endtextmacro
84
    
85
    //! textmacro AllocLoop
86
        private static integer instanceCount = 0
87
        private thistype recycle
88
        thistype next
89
        thistype prev
90
    
91
        static method allocate takes nothing returns thistype
92
            local thistype this
93
    
94
            if (thistype(0).recycle == 0) then
95
                debug if (instanceCount == 8190) then
96
                    debug call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, "Alloc ERROR: Attempted to allocate too many instances!")
97
                    debug return 0
98
                debug endif
99
                set instanceCount = instanceCount + 1
100
                set this = instanceCount
101
            else
102
                set this = thistype(0).recycle
103
                set thistype(0).recycle = thistype(0).recycle.recycle
104
            endif
105
106
            debug set this.recycle = -1
107
            
108
            set thistype(0).next.prev = this // "next" of head has our new instance as "previous"
109
            set this.next = thistype(0).next // "next" of our node is the "next" of head
110
            set thistype(0).next = this // "next" of head is now our node
111
            set this.prev = 0 // "previous" of our node is the head [this case, thistype(0)]
112
            return this
113
        endmethod
114
    
115
        method deallocate takes nothing returns nothing
116
            set .next.prev = .prev // set the "prev" of the "next" node to our "prev"
117
            set .prev.next = .next // set the "next" of the "prev" node to our "next"
118
            
119
            debug if (this.recycle != -1) then
120
                debug call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, "Alloc ERROR: Attempted to deallocate an invalid instance at [" + I2S(this) + "]!")
121
                debug return
122
            debug endif
123
124
            set this.recycle = thistype(0).recycle
125
            set thistype(0).recycle = this
126
        endmethod
127
    //! endtextmacro
128
    
129
    module Alloc
130
        //! runtextmacro Alloc()
131
    endmodule
132
    
133
    module AllocLoop
134
        //! runtextmacro AllocLoop()
135
    endmodule
136
    
137
    // - This module must be used with "AllocLoop" textmacro
138
    // - this module must be pacled after a local definition in the code ALWAYS
139
    // - always use "this" as variable name
140
    module loop 
141
        local thistype this = thistype(0).next 
142
        loop
143
            exitwhen integer(this) == 0
144
    endmodule
145
146
    // this will end the looping code
147
    module endloop 
148
            set this = this.next
149
        endloop
150
    endmodule
151
endlibrary


Comments are always welcome.
14 years
edited 13 years
Nice all-in-one snippet. :) I like it.

edit: If you wanna reduce one line, you can initialize this to thistype(0).recycle:
Code (jass) Select
1
    static method allocate takes nothing returns thistype
2
            local thistype this = thistype(0).recycle
3
    
4
            if (this == 0) then
5
                debug if (instanceCount == 8190) then
6
                    debug call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, "Alloc ERROR: Attempted to allocate too many instances!")
7
                    debug return 0
8
                debug endif
9
                set instanceCount = instanceCount + 1
10
                set this = instanceCount
11
            else
12
                // this isn't needed then -> set this = thistype(0).recycle
13
                set thistype(0).recycle = this.recycle
14
            endif
15
 
14 years
Can i say this is ugly ?
13 years
It'd be better to just do a Linked List module that is statically instanced >.>.

In the create method, you'd add to the list. In destroy, you'd remove from the list.

Pretty simple.
13 years
Depends on what you need. There are static linked lists, circular linked lists, regular linked lists, heh.
13 years
textmacros + modules uses as textmacros == uber spaghetti code for speedfreaks.
There is nothing you can do about it, now i suppose i'm the only one here which hates these module usages, there are probably also "legion" of people on wc3c.net who share my opinion, but meh it's wc3c.net :p
13 years
Quote from: nestharus on August 20, 2012, 12:48:08 PM
Here is every simple collection you'll ever need
http://www.hiveworkshop.com/forums/submissions-414/std-collections-collections-221515/
LOVELY!!! checking nowww


Quote from: Troll-Brain on August 20, 2012, 01:25:05 PM
textmacros + modules uses as textmacros == uber spaghetti code for speedfreaks.
There is nothing you can do about it, now i suppose i'm the only one here which hates these module usages, there are probably also "legion" of people on wc3c.net who share my opinion, but meh it's wc3c.net :p
AQctually you can choose that suites the best for you: modules or texmacros.

13 years
Spaghetti code is spaghetti code.
Modules used as textmacros are textmacros with a different API but that's pretty much the same.
Speedfreak is speedfreak.

It's fine to try to optimize when it realy does matter and has a visible performance improvement, like recycle dummies units instead of create/destroy units, but here for me it's really overkill and makes no sense for the vJass code, that's really ugly in my opinion.
Not to mention that i hardly believe you will see any difference in performance.
13 years
Quote from: Purgeandfire on August 16, 2012, 12:12:26 AM
Nice all-in-one snippet. :) I like it.

edit: If you wanna reduce one line, you can initialize this to thistype(0).recycle:
Code (jass) Select
1
    static method allocate takes nothing returns thistype
2
            local thistype this = thistype(0).recycle
3
    
4
            if (this == 0) then
5
                debug if (instanceCount == 8190) then
6
                    debug call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, "Alloc ERROR: Attempted to allocate too many instances!")
7
                    debug return 0
8
                debug endif
9
                set instanceCount = instanceCount + 1
10
                set this = instanceCount
11
            else
12
                // this isn't needed then -> set this = thistype(0).recycle
13
                set thistype(0).recycle = this.recycle
14
            endif
15
 


I did your suggestions and the system broke :( I'll remove the textmacros and left only modules.
13 years
I usually use arrays instead of the dot syntax :P

Anyway, this is not a bad resource.
It just reduces the amount of code you need to write.

And since the most common type of collection you'd need is a doubly linked list, then this could be pretty useful.
13 years
Quote from: Magtheridon96 on September 02, 2012, 11:18:17 PM
I usually use arrays instead of the dot syntax :P

Anyway, this is not a bad resource.
It just reduces the amount of code you need to write.

And since the most common type of collection you'd need is a doubly linked list, then this could be pretty useful.

Thanks for the approval. Love for ya :D