vJASS & Zinc Documentation
For the latest documentation about how it works vJASS and Zinc language layers for Warcraft III, please follow these links:
Jasshelper documentation - Zinc documentation - WC3 Optimizer documentation

[snippet] AllocLoop (AKA Alloc 2)

moyack · 25573

0 Members and 1 Guest are viewing this topic.

Rating

Average Score - 5 / 5

« Created: October 09, 2017, 12:30:15 AM by moyack »
+ Show previous

[snippet] AllocLoop (AKA Alloc 2)
on: August 15, 2012, 11:51:28 PM
Category: Execution, Variables
Language: vJASS

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
  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.
« Last Edit: December 19, 2017, 01:34:48 PM by moyack »



Re: [snippet] AllocLoop (AKA Alloc 2)
Reply #1 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
  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.  
« Last Edit: August 19, 2012, 10:01:28 PM by Purgeandfire »



Re: [snippet] AllocLoop (AKA Alloc 2)
Reply #2 on: August 16, 2012, 11:08:48 AM

Can i say this is ugly ?

vJass is already a jass preprocessor, no need to (ab)use vJass features in order to make some inferior vJass preprocessor coded "by hand".


Re: [snippet] AllocLoop (AKA Alloc 2)
Reply #3 on: August 19, 2012, 04:45:59 PM

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.



Re: [snippet] AllocLoop (AKA Alloc 2)
Reply #4 on: August 20, 2012, 12:34:45 AM

Can i say this is ugly ?
Your opinion is respectable :) any suggestions to make it prettier??

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.
I've seen a lot of linked list scripts, do you have one you suggest??



Re: [snippet] AllocLoop (AKA Alloc 2)
Reply #5 on: August 20, 2012, 12:46:21 AM

Depends on what you need. There are static linked lists, circular linked lists, regular linked lists, heh.



Re: [snippet] AllocLoop (AKA Alloc 2)
Reply #6 on: August 20, 2012, 01:12:14 AM

Depends on what you need. There are static linked lists, circular linked lists, regular linked lists, heh.

It'd be better to just do a Linked List module that is statically instanced >.>.
I think static should do the work... To be honest I've never used that kind of systems



Re: [snippet] AllocLoop (AKA Alloc 2)
Reply #7 on: August 20, 2012, 12:48:08 PM




Re: [snippet] AllocLoop (AKA Alloc 2)
Reply #8 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

vJass is already a jass preprocessor, no need to (ab)use vJass features in order to make some inferior vJass preprocessor coded "by hand".


Re: [snippet] AllocLoop (AKA Alloc 2)
Reply #9 on: August 22, 2012, 10:16:44 PM

Here is every simple collection you'll ever need
http://www.hiveworkshop.com/forums/submissions-414/std-collections-collections-221515/
LOVELY!!! checking nowww


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.



Re: [snippet] AllocLoop (AKA Alloc 2)
Reply #10 on: August 23, 2012, 11:11:30 AM

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.

vJass is already a jass preprocessor, no need to (ab)use vJass features in order to make some inferior vJass preprocessor coded "by hand".


Re: [snippet] AllocLoop (AKA Alloc 2)
Reply #11 on: August 26, 2012, 01:39:05 PM

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
  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.


Re: [snippet] AllocLoop (AKA Alloc 2)
Reply #12 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.



Re: [snippet] AllocLoop (AKA Alloc 2)
Reply #13 on: October 01, 2012, 08:51:16 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


 

Power of Corruption - A Warcraft III altered melee map   Chaos Realm - The world of Game modders and wc3 addicts     WC3JASS.com - The JASS Vault   Jetcraft - A Starcraft II mod