- Joined
- Apr 30, 2011
- Messages
- 359
JASS:
//========================================================================================
//
// Region Utilities
// -*- overcold_ice -*-
//
// -[*] Requirements:
// - JNGP
// - latest version of JassHelper
//
// -[*] Optional Requirements:
// - /*New*/ Table hiveworkshop.com/forums/showthread.php?t=188084
//
// For your region-manipulating needs
// This system provides easier and dynamic region-handling.
// Besides providing easy to use APIs to create/add/destroy regions, this library
// also stores what it contains (rects and cells).
//
// -[*] API:
//
// struct Region extends array
// static method create takes nothing returns Region
// creates an empty region
//
// static method operator fromRect takes rect r returns Region
// creates a region and adds rect r to it
//
// method operator addRect takes rect r returns Region
// adds a rect to the region
//
// static method fromCell takes real x, real y returns Region
// creates a region and adds cell [x, y] to it
//
// method addCell takes real x, real y returns Region
// adds a cell [x, y] to the region
//
// method operator region takes nothing returns region
// returns the 'real' region
//
// method operator rect[] takes integer i returns rect
// returns a rect from given rect id
//
// method rect.getId takes rect r returns integer
// returns the rect id of rect r
//
// method operator cell.x[] takes integer i returns real
// method operator cell.y[] takes integer i returns real
// returns the x coordinate of a cell from given cell number
//
// method cell.getId takes real x, real y returns integer
// returns the cell number of cell [x, y]
//
// method clearRectById takes integer i returns nothing
// removes a rect of given rect id from the region
//
// method clearCellById takes integer i returns nothing
// removes a cell of given cell id from the region
//
// method clear takes nothing returns nothing
// clears the regions from all rects and cells
//
// method destroy takes nothing returns nothing
// destroys the region
//
// -[*] Required Example:
//
// local Region reg1 = Region.fromCell(x1, y1).addCell(x2, y2).addCell(x3, y3)
// local Region reg2
// set reg1 = reg1.addRect(r1).addRect(r2).addRect(r3).addRect(r4).addRect(r5).addRect(r6)
// set reg2 = Region.fromRect(r1).addCell(x1, y1).addRect(r2).addRect(r3).addCell(x2, y2).addCell(x3, y3)
//
// List of rect/cell numbers:
// NUM RECT CELL
// reg1:
// 1 r1 x1y1
// 2 r2 x2y2
// 3 r3 x3y3
// 4 r4
// 5 r5
// 6 r6
// reg2:
// 1 r1 x1y1
// 2 r2 x2y2
// 3 r3 x3y3
//
//========================================================================================
library RegionUtils requires optional /*New*/Table
static if not LIBRARY_Table then
private struct T extends array
static hashtable t = InitHashtable()
endstruct
endif
private struct RectV extends array
integer c
static if LIBRARY_Table then
Table t
endif
method register takes rect r returns nothing
set this.c = this.c + 1
static if LIBRARY_Table then
if this.t == 0 then
set this.t = Table.create()
endif
set this.t.rect [this.c] = r
else
call SaveRectHandle(T.t, this, this.c, r)
endif
endmethod
method unregister takes integer i returns nothing
local integer m = this.c
call RemoveRect(this.t.rect [i])
loop
exitwhen i == m
static if LIBRARY_Table then
set this.t.rect [i] = this.t.rect [i + 1]
else
call SaveRectHandle(T.t, this, i, LoadRectHandle(t, this, i + 1))
endif
set i = i + 1
endloop
call RemoveRect(this.t.rect [m])
set this.c = this.c - 1
static if LIBRARY_Table then
call this.t.handle.remove(m)
if this.c == 0 then
call this.t.destroy()
endif
else
call RemoveSavedHandle(T.t, this, m)
endif
endmethod
endstruct
private struct RectO extends array
method operator [] takes integer i returns rect
static if LIBRARY_Table then
return RectV(this).t.rect [i]
else
return LoadRectHandle(T.t, this, i)
endif
endmethod
method getId takes rect r returns integer
local integer l = 1
loop
exitwhen l == RectV(this).c
if this [l] == r then
return l
endif
set l = l + 1
endloop
return 0
endmethod
endstruct
private struct CellV extends array
integer c
static if LIBRARY_Table then
TableArray t
endif
method register takes real x, real y returns nothing
set this.c = this.c + 1
static if LIBRARY_Table then
if this.t == 0 then
set this.t = TableArray [2]
endif
set this.t [1].real [this.c] = x
set this.t [2].real [this.c] = y
else
call SaveReal(T.t, this + 8192, this.c, x)
call SaveReal(T.t, this + 16384, this.c, y)
endif
endmethod
method unregister takes integer i returns nothing
local integer m = this.c
loop
exitwhen i == m
static if LIBRARY_Table then
set this.t [1].real [i] = this.t [1].real [i + 1]
set this.t [2].real [i] = this.t [2].real [i + 1]
else
call SaveReal(T.t, this + 8192, i, LoadReal(t, this + 8192, i + 1))
call SaveReal(T.t, this + 16384, i, LoadReal(t, this + 16384, i + 1))
endif
set i = i + 1
endloop
set this.c = this.c - 1
static if LIBRARY_Table then
call this.t [1].real.remove(m)
call this.t [2].real.remove(m)
if this.c == 0 then
call this.t.destroy()
endif
else
call RemoveSavedReal(T.t, this + 8192, m)
call RemoveSavedReal(T.t, this + 16384, m)
endif
endmethod
endstruct
private struct CellX extends array
method operator [] takes integer i returns real
static if LIBRARY_Table then
return CellV(this).t [1].real [i]
else
return LoadReal(T.t, this + 8192, i)
endif
endmethod
endstruct
private struct CellY extends array
method operator [] takes integer i returns real
static if LIBRARY_Table then
return CellV(this).t [2].real [i]
else
return LoadReal(T.t, this + 16384, i)
endif
endmethod
endstruct
private struct CellO extends array
method operator x takes nothing returns CellX
return this
endmethod
method operator y takes nothing returns CellY
return this
endmethod
method getId takes real x, real y returns integer
local integer l = 1
loop
exitwhen l == CellV(this).c
if this.x [l] == x and this.y [l] == y then
return l
endif
set l = l + 1
endloop
return 0
endmethod
endstruct
struct Region extends array
private thistype ir
private static thistype ic
readonly region region
static method create takes nothing returns thistype
local thistype this = thistype(0).ir
if this == 0 then
set .ic = .ic + 1
set this = .ic
else
set thistype(0).ir = this.ir
endif
set this.region = CreateRegion()
return this
endmethod
method addRect takes rect r returns thistype
call RegionAddRect(this.region, r)
call RectV(this).register(r)
return this
endmethod
static method fromRect takes rect r returns thistype
return Region.create().addRect(r)
endmethod
method addCell takes real x, real y returns thistype
call RegionAddCell(this.region, x, y)
call CellV(this).register(x, y)
return this
endmethod
static method fromCell takes real x, real y returns thistype
return Region.create().addCell(x, y)
endmethod
method operator rect takes nothing returns RectO
return this
endmethod
method operator cell takes nothing returns CellO
return this
endmethod
method clearRectById takes integer i returns nothing
call RegionClearRect(this.region, this.rect [i])
call RectV(this).unregister(i)
endmethod
method clearCellById takes integer i returns nothing
call RegionClearCell(this.region, this.cell.x [i], this.cell.y [i])
call CellV(this).unregister(i)
endmethod
method clear takes nothing returns nothing
local RectV r = RectV(this)
local CellV c = CellV(this)
loop
exitwhen r.c == 0
call this.clearRectById(r.c)
set r.c = r.c - 1
endloop
loop
exitwhen c.c == 0
call this.clearCellById(c.c)
set c.c = c.c - 1
endloop
endmethod
method destroy takes nothing returns nothing
local RectV r = RectV(this)
local CellV c = CellV(this)
loop
exitwhen r.c == 0
call r.unregister(r.c)
set r.c = r.c - 1
endloop
loop
exitwhen c.c == 0
call c.unregister(c.c)
set c.c = c.c - 1
endloop
call RemoveRegion(this.region)
set this.ir = thistype(0).ir
set thistype(0).ir = this
endmethod
endstruct
endlibrary
Last edited: