Advertisement
A-G-D

MultidimensionalArray

Feb 9th, 2017
107
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 18.27 KB | None | 0 0
  1. library MultidimensionalArray /* v1.2
  2.  
  3.  
  4. */uses /*
  5.  
  6. */Table /* http://www.hiveworkshop.com/threads/snippet-new-table.188084/
  7.  
  8. [Resource Link] - http://www.hiveworkshop.com/threads/snippet-multidimensional-array.289785/
  9.  
  10. *///! novjass
  11.  
  12. /* This snippet allows you to have array storage. Unlike default arrays, you can use an index beyond 8190
  13. since this snippet uses Tables which uses hashtable. Therefore, saving data with a really large index
  14. such as using GetHandleId(handle) as the index would not be a problem.
  15.  
  16. But you may ask, why would we want to use this when there is already the Table library which can support
  17. any type that we want to store? First, this has a feature which supports multidimensions that allows you
  18. to have up to 5-dimensional array. Table already allows you to create multidimensional storage if you do
  19. proper nesting but this library removes the need for users to do it on their own and this also helps set
  20. a standard instead of having redundant scripts that work for the same puspose. Secondly, unlike Table,
  21. this implements a type specific storage i.e., you can create an array storage that is only exclusive for
  22. a specific type but of course, this also provides a generic storage like Table but with a nicer API.
  23. Furthermore, this includes some safety precautions such as compile time safety which throws an error if
  24. you're using an incorrect number of dimensions, as well as preventing the use of an Array instance which
  25. isn't allocated in DEBUG_MODE. lastly, this gives users a nice and intuitive syntax which resembles that
  26. of the original vanilla Jass arrays (call KillUnit(u[1][3])) without having a need for an ugly keyword
  27. at the end (ex: call KillUnit(u[1].unit[3])). */
  28.  
  29.  
  30. |=========|
  31. | Credits |
  32. |=========|
  33.  
  34. /* AGD : Author
  35. Bribe : For the Table library, and for the algorithm of making n-dimensional storage by nesting Tables */
  36.  
  37.  
  38. |-----|
  39. | API |
  40. |-----|
  41.  
  42. Creating an Array:
  43. /* Creates a new array for a specific type */
  44. local Unit1D u = Array.create()
  45. local Unit3D u3 = Unit3D.create()
  46. local Unit5D u5 = Timer4D.create() //You could actually use any of the dimensional array creator
  47. local Array4D a4 = Array.create()
  48.  
  49. Storing inside an Array:
  50. /* Stores data inside an array */
  51. set u[GetHandleId(timer)] = GetTriggerUnit()
  52. set u3[0x2000]['AAAA'] = GetTriggerUnit() //Syntax error: number of indexes does not match with the number of dimensions
  53. set u5[1][2][3][4][5] = GetTriggerUnit()
  54. set a4[1][2][3][4].unit = GetTriggerUnit()
  55.  
  56. Retrieving from an Array:
  57. /* Retrieves data from an array */
  58. call KillUnit(u[1234567])
  59. call KillUnit(u3['A']['B']['C'])
  60. call KillUnit(u5[1][2][3][4]) //Syntax error: number of indexes does not match with the number of dimensions
  61. call KillUnit(a4[1][2][3][4].unit)
  62.  
  63. Checking storage vacancy:
  64. /* Checks if there is data stored inside an array index */
  65. return u.has(index) //Similar to Table(u).unit.has(index)
  66. return u3[1][2].has(3)
  67. return u5[1].has(2) //Checks if the fourth dimension has index 2
  68. return a4[1][2][3][4].hasHandle()
  69.  
  70. Removing an Array index:
  71. /* Destroys the table instance of an index and clears all its child nodes if there are any */
  72. call u.remove(1)
  73. call u3[1].remove(2)
  74. call u5[1][2][3][4][5].remove(6) //Syntax error: cannot use remove() on a node which has no children
  75. call a4[1][2][3][4].removeHandle()
  76.  
  77. Flushing an Array Index:
  78. /* Flushes all child nodes attached to the specific index */
  79. call u.flush() //Flushes all data inside the array, analogous to flushing a parent hashtable
  80. call u3[1][2][3].flush() //Syntax error: cannot clear a node which has no children, use u3[1][2].remove(3) instead
  81. call u5[1][2].flush() //Flushes all child nodes attached to the index "2" of the second dimension
  82. call a4[1][2].flush()
  83.  
  84. Destroying an Array:
  85. /* Destroys an array instance, flushing all data inside it */
  86. call u.destroy()
  87. call u3.destroy()
  88. call u5[1].destroy() //If destroy() is called upon a node which is not a root node, it will work like clear() instead
  89. call a4.destroy()
  90.  
  91. //! endnovjass
  92.  
  93. static if DEBUG_MODE then
  94. private struct S extends array
  95. static key allocated
  96. endstruct
  97.  
  98. private function Debug takes string msg returns nothing
  99. call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60, "|CFFFFCC00[MultidimensionalArray] |R" + msg)
  100. endfunction
  101. endif
  102.  
  103. private function AllocateIndex takes integer this, integer index returns integer
  104. debug if not Table(S.allocated).boolean[this] then
  105. debug return 0
  106. debug endif
  107. debug set Table(S.allocated).boolean[HashTable(this)[index]] = true
  108. return HashTable(this)[index]
  109. endfunction
  110.  
  111. /*============= For a uniform allocator syntax =) ==============*/
  112. struct Array extends array
  113. static method create takes nothing returns thistype
  114. static if DEBUG_MODE then
  115. local Table t = Table.create()
  116. set Table(S.allocated).boolean[t] = true
  117. return t
  118. else
  119. return Table.create()
  120. endif
  121. endmethod
  122. endstruct
  123. /*==============================================================*/
  124.  
  125. /*====================== Struct methods ========================*/
  126. private module Methods
  127. static method create takes nothing returns thistype
  128. return Array.create()
  129. endmethod
  130. static if not thistype.remove.exists then
  131. method remove takes integer index returns nothing
  132. call HashTable(this).remove(index)
  133. endmethod
  134. endif
  135. static if not thistype.has.exists then
  136. method has takes integer index returns boolean
  137. return HashTable(this).has(index)
  138. endmethod
  139. endif
  140. method flush takes nothing returns nothing
  141. call Table(this).flush()
  142. endmethod
  143. method destroy takes nothing returns nothing
  144. call Table(this).destroy()
  145. debug set Table(S.allocated).boolean[this] = false
  146. endmethod
  147. endmodule
  148. /*==============================================================*/
  149.  
  150. /*================= Generic Type Array Storage =================*/
  151. private struct Type extends array
  152.  
  153. static key index
  154.  
  155. method operator agent= takes agent value returns nothing
  156. debug if not Table(S.allocated).boolean[this] then
  157. debug call Debug("|CFFFF0000[Operator agent= ERROR] : Attempt to use a non-allocated array instance|R")
  158. debug return
  159. debug endif
  160. set Table(this).agent[Table(this)[index]] = value
  161. endmethod
  162.  
  163. //! textmacro GENERIC_DIMENSIONAL_ARRAY_METHODS takes NAME, TYPE
  164. method has$NAME$ takes nothing returns boolean
  165. return Table(this).$TYPE$.has(Table(this)[index])
  166. endmethod
  167. method remove$NAME$ takes nothing returns nothing
  168. call Table(this).$TYPE$.remove(Table(this)[index])
  169. endmethod
  170. //! endtextmacro
  171.  
  172. //! textmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS takes TYPE
  173. method operator $TYPE$ takes nothing returns $TYPE$
  174. return Table(this).$TYPE$[Table(this)[index]]
  175. endmethod
  176. method operator $TYPE$= takes $TYPE$ value returns nothing
  177. debug if not Table(S.allocated).boolean[this] then
  178. debug call Debug("|CFFFF0000[Operator $TYPE$= ERROR] : Attempt to use a non-allocated array instance|R")
  179. debug return
  180. debug endif
  181. set Table(this).$TYPE$[Table(this)[index]] = value
  182. endmethod
  183. //! endtextmacro
  184.  
  185. //! runtextmacro GENERIC_DIMENSIONAL_ARRAY_METHODS("Int", "integer")
  186. //! runtextmacro GENERIC_DIMENSIONAL_ARRAY_METHODS("Real", "real")
  187. //! runtextmacro GENERIC_DIMENSIONAL_ARRAY_METHODS("Str", "string")
  188. //! runtextmacro GENERIC_DIMENSIONAL_ARRAY_METHODS("Boolean", "boolean")
  189. //! runtextmacro GENERIC_DIMENSIONAL_ARRAY_METHODS("Handle", "handle")
  190.  
  191. //! runtextmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS("integer")
  192. //! runtextmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS("real")
  193. //! runtextmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS("string")
  194. //! runtextmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS("boolean")
  195. //! runtextmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS("player")
  196. //! runtextmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS("widget")
  197. //! runtextmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS("destructable")
  198. //! runtextmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS("item")
  199. //! runtextmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS("unit")
  200. //! runtextmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS("ability")
  201. //! runtextmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS("timer")
  202. //! runtextmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS("trigger")
  203. //! runtextmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS("triggercondition")
  204. //! runtextmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS("triggeraction")
  205. //! runtextmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS("event")
  206. //! runtextmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS("force")
  207. //! runtextmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS("group")
  208. //! runtextmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS("location")
  209. //! runtextmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS("rect")
  210. //! runtextmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS("boolexpr")
  211. //! runtextmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS("sound")
  212. //! runtextmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS("effect")
  213. //! runtextmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS("unitpool")
  214. //! runtextmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS("itempool")
  215. //! runtextmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS("quest")
  216. //! runtextmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS("questitem")
  217. //! runtextmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS("defeatcondition")
  218. //! runtextmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS("timerdialog")
  219. //! runtextmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS("leaderboard")
  220. //! runtextmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS("multiboard")
  221. //! runtextmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS("multiboarditem")
  222. //! runtextmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS("trackable")
  223. //! runtextmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS("dialog")
  224. //! runtextmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS("button")
  225. //! runtextmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS("texttag")
  226. //! runtextmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS("lightning")
  227. //! runtextmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS("image")
  228. //! runtextmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS("ubersplat")
  229. //! runtextmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS("region")
  230. //! runtextmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS("fogstate")
  231. //! runtextmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS("fogmodifier")
  232. //! runtextmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS("hashtable")
  233.  
  234. endstruct
  235.  
  236. struct Array1D extends array
  237. method remove takes integer index returns nothing
  238. call Table(this).remove(index)
  239. endmethod
  240. implement Methods
  241. method operator [] takes integer index returns Type
  242. debug if not Table(S.allocated).boolean[this] then
  243. debug return 0
  244. debug endif
  245. set Table(this)[Type.index] = index
  246. return this
  247. endmethod
  248. endstruct
  249.  
  250. //! textmacro NEW_DIMENSIONAL_ARRAY_STRUCT takes DIM, RETURNED
  251. struct Array$DIM$D extends array
  252. implement Methods
  253. method operator [] takes integer index returns Array$RETURNED$D
  254. return AllocateIndex(this, index)
  255. endmethod
  256. endstruct
  257. //! endtextmacro
  258.  
  259. //! runtextmacro NEW_DIMENSIONAL_ARRAY_STRUCT("2", "1")
  260. //! runtextmacro NEW_DIMENSIONAL_ARRAY_STRUCT("3", "2")
  261. //! runtextmacro NEW_DIMENSIONAL_ARRAY_STRUCT("4", "3")
  262. //! runtextmacro NEW_DIMENSIONAL_ARRAY_STRUCT("5", "4")
  263. // If you want to increase the maximum number of available
  264. // dimensions, just run the textmacros above once again like:
  265. // runtextamcro NEW_DIMENSIONAL_ARRAY_STRUCT("LAST_MAX_DIM + 1", "LAST_MAX_DIM")
  266. /*==============================================================*/
  267.  
  268. /*================ Type Specific Array Storage =================*/
  269. //! textmacro NEW_DIMENSIONAL_ARRAY takes NAME, TYPE
  270. struct $NAME$1D extends array
  271. method remove takes integer index returns nothing
  272. call Table(this).$TYPE$.remove(index)
  273. endmethod
  274. method has takes integer index returns boolean
  275. return Table(this).$TYPE$.has(index)
  276. endmethod
  277. implement Methods
  278. method operator [] takes integer index returns $TYPE$
  279. return Table(this).$TYPE$[index]
  280. endmethod
  281. method operator []= takes integer index, $TYPE$ value returns nothing
  282. debug if not Table(S.allocated).boolean[this] then
  283. debug call Debug("|CFFFFCC00[ArrayType: $NAME$]|R |CFFFF0000[Operator []= ERROR] : Attempt to use a non-allocated array instance|R")
  284. debug return
  285. debug endif
  286. set Table(this).$TYPE$[index] = value
  287. endmethod
  288. endstruct
  289.  
  290. struct $NAME$2D extends array
  291. implement Methods
  292. method operator [] takes integer index returns $NAME$1D
  293. return AllocateIndex(this, index)
  294. endmethod
  295. endstruct
  296.  
  297. struct $NAME$3D extends array
  298. implement Methods
  299. method operator [] takes integer index returns $NAME$2D
  300. return AllocateIndex(this, index)
  301. endmethod
  302. endstruct
  303.  
  304. struct $NAME$4D extends array
  305. implement Methods
  306. method operator [] takes integer index returns $NAME$3D
  307. return AllocateIndex(this, index)
  308. endmethod
  309. endstruct
  310.  
  311. struct $NAME$5D extends array
  312. implement Methods
  313. method operator [] takes integer index returns $NAME$4D
  314. return AllocateIndex(this, index)
  315. endmethod
  316. endstruct
  317. //! endtextmacro
  318. // If you want to increase the maximum number of available
  319. // dimensions, just copy the last struct above and increase the
  320. // number of dimension in the struct name and the returned struct
  321. // of the operator [] by 1.
  322. /*==============================================================*/
  323.  
  324. /*======== Implement textmacros for every storage type =========*/
  325. //! runtextmacro NEW_DIMENSIONAL_ARRAY("Integer", "integer")
  326. //! runtextmacro NEW_DIMENSIONAL_ARRAY("Real", "real")
  327. //! runtextmacro NEW_DIMENSIONAL_ARRAY("Str", "string")
  328. //! runtextmacro NEW_DIMENSIONAL_ARRAY("Boolean", "boolean")
  329. //! runtextmacro NEW_DIMENSIONAL_ARRAY("Player", "player")
  330. //! runtextmacro NEW_DIMENSIONAL_ARRAY("Widget", "widget")
  331. //! runtextmacro NEW_DIMENSIONAL_ARRAY("Destructable", "destructable")
  332. //! runtextmacro NEW_DIMENSIONAL_ARRAY("Item", "item")
  333. //! runtextmacro NEW_DIMENSIONAL_ARRAY("Unit", "unit")
  334. //! runtextmacro NEW_DIMENSIONAL_ARRAY("Ability", "ability")
  335. //! runtextmacro NEW_DIMENSIONAL_ARRAY("Timer", "timer")
  336. //! runtextmacro NEW_DIMENSIONAL_ARRAY("Trigger", "trigger")
  337. //! runtextmacro NEW_DIMENSIONAL_ARRAY("TriggerCondition", "triggercondition")
  338. //! runtextmacro NEW_DIMENSIONAL_ARRAY("TriggerAction", "triggeraction")
  339. //! runtextmacro NEW_DIMENSIONAL_ARRAY("TriggerEvent", "event")
  340. //! runtextmacro NEW_DIMENSIONAL_ARRAY("Force", "force")
  341. //! runtextmacro NEW_DIMENSIONAL_ARRAY("Group", "group")
  342. //! runtextmacro NEW_DIMENSIONAL_ARRAY("Location", "location")
  343. //! runtextmacro NEW_DIMENSIONAL_ARRAY("Rect", "rect")
  344. //! runtextmacro NEW_DIMENSIONAL_ARRAY("BooleanExpr", "boolexpr")
  345. //! runtextmacro NEW_DIMENSIONAL_ARRAY("Sound", "sound")
  346. //! runtextmacro NEW_DIMENSIONAL_ARRAY("Effect", "effect")
  347. //! runtextmacro NEW_DIMENSIONAL_ARRAY("UnitPool", "unitpool")
  348. //! runtextmacro NEW_DIMENSIONAL_ARRAY("ItemPool", "itempool")
  349. //! runtextmacro NEW_DIMENSIONAL_ARRAY("Quest", "quest")
  350. //! runtextmacro NEW_DIMENSIONAL_ARRAY("QuestItem", "questitem")
  351. //! runtextmacro NEW_DIMENSIONAL_ARRAY("DefeatCondition", "defeatcondition")
  352. //! runtextmacro NEW_DIMENSIONAL_ARRAY("TimerDialog", "timerdialog")
  353. //! runtextmacro NEW_DIMENSIONAL_ARRAY("Leaderboard", "leaderboard")
  354. //! runtextmacro NEW_DIMENSIONAL_ARRAY("Multiboard", "multiboard")
  355. //! runtextmacro NEW_DIMENSIONAL_ARRAY("MultiboardItem", "multiboarditem")
  356. //! runtextmacro NEW_DIMENSIONAL_ARRAY("Trackable", "trackable")
  357. //! runtextmacro NEW_DIMENSIONAL_ARRAY("Dialog", "dialog")
  358. //! runtextmacro NEW_DIMENSIONAL_ARRAY("Button", "button")
  359. //! runtextmacro NEW_DIMENSIONAL_ARRAY("TextTag", "texttag")
  360. //! runtextmacro NEW_DIMENSIONAL_ARRAY("Lightning", "lightning")
  361. //! runtextmacro NEW_DIMENSIONAL_ARRAY("Image", "image")
  362. //! runtextmacro NEW_DIMENSIONAL_ARRAY("Ubersplat", "ubersplat")
  363. //! runtextmacro NEW_DIMENSIONAL_ARRAY("Region", "region")
  364. //! runtextmacro NEW_DIMENSIONAL_ARRAY("FogState", "fogstate")
  365. //! runtextmacro NEW_DIMENSIONAL_ARRAY("FogModifier", "fogmodifier")
  366. //! runtextmacro NEW_DIMENSIONAL_ARRAY("Hashtable", "hashtable")
  367. /*==============================================================*/
  368.  
  369.  
  370. endlibrary
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement