14 years
edited 8 years
1 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~2 //~~ Rectwraps ~~ By Azlier ~~ Documentation ripped off from Jesus4Lyf ~~3 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~4 //5 // What is Rectwraps?6 // - Rectwraps are essentially vJass replacements for the native rects and regions.7 // - They can be attached to safely, which has certain uses.8 // - Rectwraps recycles anything it creates.9 //10 // =Pros=11 // - Easy to use, once you learn the basic methods.12 // - Possibly faster than even native rects and regions.13 // - Fast, safe region attachment.14 // - No H2I/GetHandleId. Backwards compatability through patch 1.23 and 1.24.15 //16 // =Cons=17 // - Uses TriggerExecCount to store data. If over 1000 rectwraps are created at one time,18 // there may be a short lag spike.19 // - Only 8191 rectwraps can exist at one time with the default settings.20 //21 // Variables:22 // These coordinate variables can be both read and set. Reading them is much, much faster than setting them.23 // They are faster than their GetRect**** counterparts.24 //25 // .minX26 // The x coordinate of the rectwrap's left side.27 //28 // .maxX29 // The x coordinate of the rectwrap's right side.30 //31 // .minY32 // The y coordinate of the rectwrap's bottom side.33 //34 // .maxY35 // The x coordinate of the rectwrap's top side.36 //37 // .cenX38 // The x coordinate of the rectwrap's center.39 //40 // .cenY41 // The y coordinate of the rectwrap's center.42 //43 // This integer variable is really there just for fun. Do not use it in any public resource.44 // .userData45 //46 // Methods:47 // ~ Event responses48 // GetTriggeringRectwrap takes nothing returns rectwrap49 // This returns the entered/exited rectwrap when you enter/exit one.50 //51 // rectwrap.getTriggering() takes nothing returns rectwrap52 // Same as above, but in static method form.53 //54 // ~ Static55 // .wrap takes rect which returns rectwrap56 // Wraps a rect for use as a rectwrap. Purely for gg_rct rects.57 //58 // .create takes real x1, real y1, real x2, real y2 returns rectwrap59 // Creates a rectwrap from the given coordinates.60 //61 // .createFromPoint takes real x, real y, real width, real height returns rectwrap62 // Creates a rectwrap at a point with a set width and height.63 // ~ Non-static64 // .registerEnter takes trigger which returns trigger65 // Rigs a trigger to fire when the rectwrap is entered.66 // Also returns the given trigger so that you can use that weird one-line67 // coding style... if you really want to.68 //69 // .registerExit takes trigger which returns trigger70 // Same as above, but when the rectwrap is exited.71 //72 // .registerEnterCode takes code c returns trigger73 // Like .registerEnter, but takes a code. Returns the trigger the code was registered to.74 // THE CODE MUST RETURN A BOOLEAN.75 //76 // .registerExitCode takes code c returns trigger77 // ...Must I really explain?78 //79 // .destroy takes nothing returns nothing80 // Cleans the rectwrap's members. Recycles all handle members.81 //82 // .setTo takes real x1, real y1, real x2, real y2 returns nothing83 // Shifts a rectwrap's dimensions to the given values.84 //85 // .moveTo takes real x, real y returns nothing86 // Simply moves a rectwrap to the given coordinates without altering dimensions.87 //88 // .copy takes nothing returns rectwrap89 // Copies a rectwrap completely, right down to the user data. Probably not much use, but it's there...90 //91 // .replaceTerrain takes integer oldTerrain, integer terrain92 // Swaps all terrain of type oldTerrain for type terrain. Credits to Romek for this method.93 //94 // .setPathing takes pathingtype path, boolean on returns nothing95 // Sets the pathingtype for a rectwrap on or off.96 //97 // .iterateThrough takes IterateFunc func, real dist returns nothing.98 // Separates the rectwrap into distxdist cells and iterates through them, calling func with99 // that cell's center x and y as arguments.100 //101 // .groupEnum takes group g, boolexpr filter returns nothing102 // GroupEnumUnitsInRect without the rect.103 //104 // .createWeather takes integer id returns weathereffect105 // AddWeatherEffect without the rect.106 //107 // .addFog takes player p, fogstate f, boolean b1, boolean b2 returns fogmodifier108 // CreateFogModifierRect without the rect.109 //110 // .enumDestructables takes boolexpr filter, code enum returns nothing111 // EnumDestructablesInRect without the rect.112 //113 // .enumItems takes boolexpr filter, code enum returns nothing114 // EnumItemsInRect without the rect.115 //116 // .setBlight takes player p, boolean b returns nothing117 // SetBlight without the rect.118 //119 // .setDoodadAnimation takes integer i, string s, boolean b returns nothing120 // SetDoodadAnimationRect without the rect.121 //122 // .setFogState takes player p, fogstate f, boolean b returns nothing123 // SetFogStateRect without the rect.124 //125 // .coordsInRect takes real x, real y returns boolean126 // Returns whether the given coordinates are within the rect or not.127 //128 //129 // Thanks:130 // - Jesus4Lyf: For his Event struct and TriggerExecCount attachment method.131 //132 // - Troll Brain: For discovering a grave bug.133 //134 // - Romek: For letting me duplicate his ReplaceTerrain script.135 //136 // - Darkfeet (Darthfett): For giving me the idea.137 //138 // - Skrarnaks: Spotting ANOTHER grave bug139 //140 //141 // How to import:142 // - Create a trigger named Rectwraps.143 // - Convert it to custom text and replace all the trigger text with this.144 //145 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~146 147 //Hack libraries to allow CamelCase library requirement.148 //Yes, even I wanted to be able to do that.149 library Rectwrap requires rectwrap
150 endlibrary151 library Rectwraps requires rectwrap
152 endlibrary153 library RectWrap requires rectwrap
154 endlibrary155 library RectWraps requires rectwrap
156 endlibrary157 158 library rectwrap159 160 globals161 private rectwrap TrigRec = 0
162 endglobals163 164 //This is to simulate an event response.165 constant function GetTriggeringRectwrap takes nothing returns rectwrap
166 return TrigRec167 endfunction168
169 //Jesus4Lyf's Event170 private struct Event
171 private trigger trig
172 private Event next173 static method create takes nothing returns Event
174 local Event this=Event.allocate()
175 set this.next=0
176 return this
177 endmethod178 private static Event current
179 private static trigger t
180 method fire takes nothing returns nothing
181 local Event curr182 // this = last.183 loop184 set curr=this.next
185 exitwhen curr==0
186 set .t=curr.trig
187 if IsTriggerEnabled(.t) then
188 set .current=curr
189 if TriggerEvaluate(.t) then
190 call TriggerExecute(.t)
191 endif192 set this=curr
193 else194 call EnableTrigger(.t) // Was trigger destroyed?
195 if IsTriggerEnabled(.t) then
196 call DisableTrigger(.t)
197 set this=curr
198 else // If trigger destroyed...
199 set .current.trig=null
200 set this.next=curr.next
201 call curr.destroy()
202 endif203 endif204 endloop205 endmethod206 method register takes trigger t returns nothing
207 local Event new=Event.allocate()
208 set new.next=this.next
209 set new.trig=t
210 set this.next=new
211 endmethod212 method chainDestroy takes nothing returns nothing
213 loop214 call this.destroy()
215 set this=this.next
216 exitwhen this==0
217 set this.trig=null
218 endloop219 endmethod220 endstruct221 222 private function interface IterateFilter takes real x, real y returns nothing
223 224 struct rectwrap225
226 //This was privatized because I don't want you touching it. Satisfied?227 private rect theRect
228 private region reg
229
230 private real minXR
231 private real maxXR
232 private real minYR
233 private real maxYR
234 private real cenXR
235 private real cenYR
236
237 //If you ever find yourself needing more of this, don't add more variables.238 //Use the struct directly as an index in an array.239 integer userData = 0
240
241 static constant method getTriggering takes nothing returns thistype
242 return TrigRec243 endmethod244
245 //***********************246 //* Rectwrap properties *247 //***********************248 //! textmacro Rectwrap__Property takes NAME, CODE249 method operator $NAME$ takes nothing returns real
250 return .$NAME$R
251 endmethod252
253 method operator $NAME$= takes real r returns nothing
254 call RegionClearRect(.reg, .theRect)
255 call SetRect(.theRect, $CODE$)
256 call RegionAddRect(.reg, .theRect)
257 set .minXR = GetRectMinX(.theRect)
258 set .minYR = GetRectMaxX(.theRect)
259 set .maxXR = GetRectMinY(.theRect)
260 set .maxYR = GetRectMaxY(.theRect)
261 set .cenXR = .minXR + (.maxXR - .minXR) / 2
262 set .cenYR = .minYR + (.maxYR - .minYR) / 2
263 endmethod264 //! endtextmacro265
266 //! runtextmacro Rectwrap__Property("minX", "r, .minYR, .maxXR, .maxYR")267 //! runtextmacro Rectwrap__Property("maxX", ".minXR, .minYR, r, .maxYR")268 //! runtextmacro Rectwrap__Property("minY", ".minXR, r, .maxXR, .maxYR")269 //! runtextmacro Rectwrap__Property("maxY", ".minXR, .minYR, .maxXR, r")270
271 method operator cenX takes nothing returns real
272 return .cenXR
273 endmethod274
275 method operator cenY takes nothing returns real
276 return .cenYR
277 endmethod278
279 //.cenX=, .cenY=. What a hack!280 method operator cenX= takes real r returns nothing
281 call RegionClearRect(.reg, .theRect)
282 call MoveRectTo(.theRect, r, .cenY)
283 call RegionAddRect(.reg, .theRect)
284 set .minXR = GetRectMinX(.theRect)
285 set .minYR = GetRectMaxX(.theRect)
286 set .maxXR = GetRectMinY(.theRect)
287 set .maxYR = GetRectMaxY(.theRect)
288 set .cenXR = .minXR + (.maxXR - .minXR) / 2
289 set .cenYR = .minYR + (.maxYR - .minYR) / 2
290 endmethod291
292 method operator cenY= takes real r returns nothing
293 call RegionClearRect(.reg, .theRect)
294 call MoveRectTo(.theRect, .cenXR, r)
295 call RegionAddRect(.reg, .theRect)
296 set .minXR = GetRectMinX(.theRect)
297 set .minYR = GetRectMaxX(.theRect)
298 set .maxXR = GetRectMinY(.theRect)
299 set .maxYR = GetRectMaxY(.theRect)
300 set .cenXR = .minXR + (.maxXR - .minXR) / 2
301 set .cenYR = .minYR + (.maxYR - .minYR) / 2
302 endmethod303
304 //****************************305 //* Various rectish methods. *306 //****************************307
308 //Wrap an existing rect. Purely for gg_rct_ rects.309 static method wrap takes rect which returns thistype
310 local thistype this = thistype.allocate()
311 set .minXR = GetRectMinX(which)
312 set .minYR = GetRectMinY(which)
313 set .maxXR = GetRectMaxX(which)
314 set .maxYR = GetRectMaxY(which)
315 set .cenXR = .minXR + (.maxXR - .minXR) / 2
316 set .cenYR = .minYR + (.maxYR - .minYR) / 2
317 if .theRect == null then
318 set .theRect = Rect(.minXR, .minYR, .maxXR, .maxYR)
319 set .reg = CreateRegion()
320 call RegionAddRect(.reg, .theRect)
321 else322 call RegionClearRect(.reg, .theRect)
323 call SetRect(.theRect, .minXR, .minYR, .maxXR, .maxYR)
324 call RegionAddRect(.reg, .theRect)
325 endif326 return this
327 endmethod328
329 //Creates a rectwrap out of nowhere. Uses recycled rects to minimize waste.330 static method create takes real x1, real y1, real x2, real y2 returns thistype
331 local thistype this = thistype.allocate()
332 if .theRect == null then
333 set .theRect = Rect(x1, y1, x2, y2)
334 set .reg = CreateRegion()
335 call RegionAddRect(.reg, .theRect)
336 else337 call RegionClearRect(.reg, .theRect)
338 call SetRect(.theRect, x1, y1, x2, y2)
339 call RegionAddRect(.reg, .theRect)
340 endif341 set .minXR = GetRectMinX(.theRect)
342 set .minYR = GetRectMinY(.theRect)
343 set .maxXR = GetRectMaxX(.theRect)
344 set .maxYR = GetRectMaxY(.theRect)
345 set .cenXR = .minXR + (.maxXR - .minXR) / 2
346 set .cenYR = .minYR + (.maxYR - .minYR) / 2
347 return this
348 endmethod349
350 //Creates a rectwrap from a point, using given width and height.351 static method createFromPoint takes real x, real y, real width, real height returns thistype
352 local thistype this = thistype.allocate()
353 set width = width / 2
354 set height = height / 2
355 if .theRect == null then
356 set .theRect = Rect(x - width, y - height, x + width, y + height)
357 set .reg = CreateRegion()
358 call RegionAddRect(.reg, .theRect)
359 else360 call RegionClearRect(.reg, .theRect)
361 call SetRect(.theRect, x - width, y - height, x + width, y + height)
362 call RegionAddRect(.reg, .theRect)
363 endif364 set .minXR = GetRectMinX(.theRect)
365 set .minYR = GetRectMinY(.theRect)
366 set .maxXR = GetRectMaxX(.theRect)
367 set .maxYR = GetRectMaxY(.theRect)
368 set .cenXR = .minXR + (.maxXR - .minXR) / 2
369 set .cenYR = .minYR + (.maxYR - .minYR) / 2
370 return this
371 endmethod372
373 //Copies a rectwrap. Hey, someone might actually use this. Someday.374 method copy takes nothing returns thistype
375 local thistype new = thistype.allocate()
376 if new.theRect == null then
377 set new.theRect = Rect(.minX, .minY, .maxX, .maxY)
378 set .reg = CreateRegion()
379 call RegionAddRect(.reg, .theRect)
380 else381 call RegionClearRect(.reg, .theRect)
382 call SetRect(new.theRect, .minX, .minY, .maxX, .maxY)
383 call RegionAddRect(.reg, .theRect)
384 endif385 set new.minXR = .minXR
386 set new.minYR = .minYR
387 set new.maxXR = .maxXR
388 set new.maxYR = .maxYR
389 set new.cenXR = .cenXR
390 set new.cenYR = .cenYR
391 set new.userData = .userData
392 return new393 endmethod394
395 //Sets a rectwrap to an area, changing dimensions.396 method setTo takes real x1, real y1, real x2, real y2 returns nothing
397 call RegionClearRect(.reg, .theRect)
398 call SetRect(.theRect, x1, y1, x2, y2)
399 call RegionAddRect(.reg, .theRect)
400 set .minXR = GetRectMinX(.theRect)
401 set .minYR = GetRectMinY(.theRect)
402 set .maxXR = GetRectMaxX(.theRect)
403 set .maxYR = GetRectMaxY(.theRect)
404 set .cenXR = .minXR + (.maxXR - .minXR) / 2
405 set .cenYR = .minYR + (.maxYR - .minYR) / 2
406 endmethod407
408 //Moves a rectwrap, without changing dimensions.409 method moveTo takes real x, real y returns nothing
410 call RegionClearRect(.reg, .theRect)
411 call MoveRectTo(.theRect, x, y)
412 call RegionAddRect(.reg, .theRect)
413 set .minXR = GetRectMinX(.theRect)
414 set .minYR = GetRectMinY(.theRect)
415 set .maxXR = GetRectMaxX(.theRect)
416 set .maxYR = GetRectMaxY(.theRect)
417 set .cenXR = .minXR + (.maxXR - .minXR) / 2
418 set .cenYR = .minYR + (.maxYR - .minYR) / 2
419 endmethod420
421 //Iteration methods (credits to Romek for the original ReplaceTerrain)422
423 //These three variables are to be shared with the other iteration methods.424 private static real curX
425 private static real curY
426 private static thistype tempRW
427
428 private static integer old
429 private static integer new
430
431 private static method ReplaceTerrainB takes nothing returns nothing
432 loop433 if .old == 0 or GetTerrainType(.curX, .curY) == .old then
434 call SetTerrainType(.curX, .curY, .new, -1, 1, 1)
435 endif436 set .curX = .curX + 128
437 exitwhen .curX > .tempRW.maxX
438 endloop439 endmethod440
441 private static method ReplaceTerrainA takes nothing returns nothing
442 loop443 set .curX = .tempRW.minX + 64
444 call ReplaceTerrainB.execute()
445 set .curY = .curY + 128
446 exitwhen .curY > .tempRW.maxY
447 endloop448 endmethod449
450 method replaceTerrain takes integer oldTerrain, integer terrain returns nothing
451 set .old = oldTerrain
452 set .new = terrain
453 set .curX = .minX + 64
454 set .curY = .minY + 64 //Magic numbers for the win.
455 set .tempRW = this
456 call ReplaceTerrainA.execute()
457 endmethod458
459 //SetPathing methods460 private static pathingtype path
461 private static boolean pathOn
462
463 private static method SetPathingB takes nothing returns nothing
464 loop465 call SetTerrainPathable(.curX, .curY, .path, .pathOn)
466 set .curX = .curX + 32
467 exitwhen .curX > .tempRW.maxX
468 endloop469 endmethod470
471 private static method SetPathingA takes nothing returns nothing
472 loop473 set .curX = .tempRW.minX + 16
474 call SetPathingB.execute()
475 set .curY = .curY + 32
476 exitwhen .curY > .tempRW.maxY
477 endloop478 endmethod479
480 method setPathing takes pathingtype path, boolean on returns nothing
481 set .path = path
482 set .pathOn = on
483 set .curX = .minX + 16
484 set .curY = .minY + 16 //Magic numbers for the win.
485 set .tempRW = this
486 call SetPathingA.execute()
487 endmethod488
489 //Iteration methods490
491 private static real iterateDist
492 private static IterateFilter iterateFunc
493
494 private static method IterateThroughB takes nothing returns nothing
495 loop496 call iterateFunc.execute(.curX, .curY)
497 set .curX = .curX + .tempRW.iterateDist
498 exitwhen .curX > .tempRW.maxX
499 endloop500 endmethod501
502 private static method IterateThroughA takes nothing returns nothing
503 loop504 set .curX = .tempRW.minX + .tempRW.iterateDist / 2
505 call IterateThroughB.execute()
506 set .curY = .curY + .tempRW.iterateDist
507 exitwhen .curY > .tempRW.maxY
508 endloop509 endmethod510
511 method iterateThrough takes IterateFilter func, real dist returns nothing
512 set .iterateFunc = func
513 set .iterateDist = dist
514 set .curX = .minX + dist / 2
515 set .curY = .minY + dist / 2
516 set .tempRW = this
517 call IterateThroughA.execute()
518 endmethod519
520 //! textmacro Rectwraps__wrapperMethod takes NAME, ARGS, RETURNS, CODE521 method $NAME$ takes $ARGS$ returns $RETURNS$
522 $CODE$
523 endmethod524 //! endtextmacro525
526 //BJlike, shorter to type wrapper methods.527 //! runtextmacro Rectwraps__wrapperMethod("groupEnum", "group g, boolexpr b", "nothing", "call GroupEnumUnitsInRect(g, .theRect, b)")528 //! runtextmacro Rectwraps__wrapperMethod("createWeather", "integer i", "weathereffect", "return AddWeatherEffect(.theRect, i)")529 //! runtextmacro Rectwraps__wrapperMethod("addFog", "player p, fogstate f, boolean b1, boolean b2", "fogmodifier", "return CreateFogModifierRect(p, f, .theRect, b1, b2)")530 //! runtextmacro Rectwraps__wrapperMethod("enumDestructables","boolexpr filter, code enum","nothing","call EnumDestructablesInRect(.theRect, filter, enum)")531 //! runtextmacro Rectwraps__wrapperMethod("enumItems","boolexpr filter, code enum","nothing","call EnumItemsInRect(.theRect, filter, enum)")532 //! runtextmacro Rectwraps__wrapperMethod("setBlight","player p, boolean b","nothing","call SetBlightRect(p, .theRect, b)")533 //! runtextmacro Rectwraps__wrapperMethod("setDoodadAnimation","integer i, string s, boolean b","nothing","call SetDoodadAnimationRect(.theRect, i, s, b)")534 //! runtextmacro Rectwraps__wrapperMethod("setFogState","player p, fogstate f, boolean b","nothing","call SetFogStateRect(p, f, .theRect, b)")535 //! runtextmacro Rectwraps__wrapperMethod("coordsInRect","real x, real y","boolean","return x >= .minXR and x <= .maxXR and y >= .minYR and y <= .maxYR")536 //! runtextmacro Rectwraps__wrapperMethod("isPointOn","real x, real y","boolean","return IsPointInRegion(.reg, x, y)")537 //! runtextmacro Rectwraps__wrapperMethod("isUnitOn","unit u","boolean","return IsUnitInRegion(.reg, u)")538
539 //***************************************************540 //* Onto the nasty stuff (regions, triggers, etc.). *541 //***************************************************542
543 private Event EnEv544 private Event ExEv545
546 private trigger EnTrig
547 private trigger ExTrig
548
549
550 private static boolexpr OnEnter
551 private static boolexpr OnExit
552
553 //The function fired when a unit enters the rectwrap.554 private static method OnEnterFunc takes nothing returns boolean
555 set TrigRec = GetTriggerExecCount(GetTriggeringTrigger())
556 call TrigRec.EnEv.fire()
557 set TrigRec = 0
558 return false
559 endmethod560
561 //Same as above, but when the unit leaves.562 private static method OnExitFunc takes nothing returns boolean
563 set TrigRec = GetTriggerExecCount(GetTriggeringTrigger())
564 call TrigRec.ExEv.fire()
565 set TrigRec = 0
566 return false
567 endmethod568
569 private static method SetTrigData takes trigger t, integer i returns nothing
570 loop571 exitwhen i == 0
572 call TriggerExecute(t)
573 set i = i - 1
574 endloop575 endmethod576
577 //Readies a trigger to fire when the rectwrap is entered.578 method registerEnter takes trigger whichTrigger returns trigger
579 if .EnEv == 0 then
580 set .EnEv = Event.create()
581 endif582 if .EnTrig == null then
583 set .EnTrig = CreateTrigger()
584 call thistype.SetTrigData.execute(.EnTrig, this)
585 call TriggerRegisterEnterRegion(.EnTrig, .reg, null)
586 call TriggerAddCondition(.EnTrig, .OnEnter)
587 elseif not IsTriggerEnabled(.EnTrig) then
588 call EnableTrigger(.EnTrig)
589 endif590 call .EnEv.register(whichTrigger)
591 return whichTrigger592 endmethod593
594 //Does the same as above, but for when a unit leaves.595 method registerExit takes trigger whichTrigger returns trigger
596 if .ExEv == 0 then
597 set .ExEv = Event.create()
598 endif599 if .ExTrig == null then
600 set .ExTrig = CreateTrigger()
601 call thistype.SetTrigData.execute(.ExTrig, this)
602 call TriggerRegisterLeaveRegion(.ExTrig, .reg, null)
603 call TriggerAddCondition(.ExTrig, .OnExit)
604 elseif not IsTriggerEnabled(.ExTrig) then
605 call EnableTrigger(.ExTrig)
606 endif607 call .ExEv.register(whichTrigger)
608 return whichTrigger609 endmethod610
611 //registerCode methods. They return the trigger in case the user wants to destroy it.612 private static trigger tempTrig
613
614 method registerEnterCode takes code c returns trigger
615 set .tempTrig = CreateTrigger()
616 call TriggerAddCondition(.registerEnter(.tempTrig), Condition(c))
617 return .tempTrig
618 endmethod619
620 method registerExitCode takes code c returns trigger
621 set .tempTrig = CreateTrigger()
622 call TriggerAddCondition(.registerExit(.tempTrig), Condition(c))
623 return .tempTrig
624 endmethod625
626 //Now, we clean everything up in the event that the rectwrap is destroyed.627 method onDestroy takes nothing returns nothing
628 if .EnEv != 0 then
629 call .EnEv.chainDestroy()
630 set .EnEv = 0
631 endif632 if .ExEv != 0 then
633 call .ExEv.chainDestroy()
634 set .ExEv = 0
635 endif636 if .EnTrig != null then
637 call DisableTrigger(.EnTrig)
638 endif639 if .ExTrig != null then
640 call DisableTrigger(.ExTrig)
641 endif642 //The rects, regions, and triggers are not destroyed.643 //They are recycled.644 endmethod645
646 //*************************647 //* Struct initialization *648 //*************************649
650 private static method onInit takes nothing returns nothing
651 set .OnEnter = Filter(function thistype.OnEnterFunc)
652 set .OnExit = Filter(function thistype.OnExitFunc)
653 endmethod654
655 endstruct656 657 endlibrary