| 11-05-2009, 08:34 AM | #1 |
Edit: Submitted as a resource here. End of Edit. I was bored, so I coded Board. Board is a fancy decorator library for multiboards, to hopefully make them easier to work with. I use the word "Decorator" because I think it will create less of a "Burn him!" reaction than the word "wrapper". Any of the [] operators accept out-of-bounds values. they will grow the multiboard to a size that will include the refered to index. (This doesn't work for < 0, of course...) Because of some magic hackery, you never have to destroy BoardRow, BoardColumn, or BoardItem structs. You simply have to destroy the Board struct that created them. Rows, items, and columns are not affected by the 8190 limit, so spam multiboards to your hearts content. (Though, this limits what features I can add to the system... possibly. Hashtables may come to the rescue.) The convenient list of methods/properties in the library is the only documentation this has for now. Enough of me blathering on, barring this: Please, post questions/comments/concerns/criticism! :) The library: (Requires ARGB) Board:/* Board: Board.create() -> Board board.col[x] -> BoardColumn board.col.count -> integer board.col.count = integer board.row[y] -> BoardRow board.row.count -> integer board.row.count = integer board.[x][y] -> BoardItem board.title = string board.titleColor = ARGB board.visible = boolean board.clear() BoardColumn: bc[y] -> BoardItem bc.position -> integer bc.text = string bc.color = ARGB bc.icon = string bc.width = real bc.setDisplay(boolean text, boolean icon) BoardRow: br[x] -> BoardItem br.position -> integer br.text = string br.color = ARGB br.icon = string br.width = real br.setDisplay(boolean text, boolean icon) BoardItem: bi.x -> integer bi.y -> integer bi.text = string bi.color = ARGB bi.icon = string bi.width = real bi.setDisplay(boolean text, boolean icon) */ /* Notes on how it works... Not actual proper documentation. i = brd * 10000 + row * 100 + col k = (i % 10000) col = (i % 10000) % 100 row = (k - (k % 100)) / 100 brd = (i - (i % 10000)) / 10000 ---------- first number * 10000 + second number second number = Mod(whole,10000) first number = (whole-Mod(whole,10000))/10000 */ library Board requires ARGB // Hopefully this will be linlined one day... private constant function Mod takes integer dividend, integer divisor returns integer return dividend - (dividend / divisor) * divisor endfunction private function ErrorMsg takes string what, string error returns nothing debug call BJDebugMsg("Board Error: " + what + ": " + error) endfunction // ============================================================ // Private keywords // ============================================================ private keyword bBoard private keyword bColCount private keyword bRowCount private keyword bTempCol // ============================================================ // Item Struct // ============================================================ struct BoardItem extends array // row = (Mod(integer(this), 10000) - Mod(Mod(integer(this), 10000), 100)) / 100 // col = Mod(Mod(integer(this), 10000), 100) // board = (integer(this) - Mod(integer(this), 10000)) / 10000 public method operator x takes nothing returns integer return Mod(Mod(integer(this), 10000), 100) endmethod public method operator y takes nothing returns integer return (Mod(integer(this), 10000) - Mod(Mod(integer(this), 10000), 100)) / 100 endmethod // ============== //! textmacro BoardItem_Setter local integer k = Mod(integer(this), 10000) local integer row = (k - Mod(k, 100)) / 100 local integer col = Mod(k, 100) local Board board = Board((integer(this) - k) / 10000) //! endtextmacro public method operator text= takes string val returns nothing //! runtextmacro BoardItem_Setter() call MultiboardSetItemValue(MultiboardGetItem(board.bBoard, row, col), val) endmethod public method operator icon= takes string val returns nothing //! runtextmacro BoardItem_Setter() call MultiboardSetItemIcon(MultiboardGetItem(board.bBoard, row, col), val) endmethod public method operator color= takes ARGB c returns nothing //! runtextmacro BoardItem_Setter() call MultiboardSetItemValueColor(MultiboardGetItem(board.bBoard, row, col), c.red, c.green, c.blue, c.alpha) endmethod public method operator width= takes real r returns nothing //! runtextmacro BoardItem_Setter() call MultiboardSetItemWidth(MultiboardGetItem(board.bBoard, row, col), r) endmethod public method setDisplay takes boolean text, boolean icon returns nothing //! runtextmacro BoardItem_Setter() call MultiboardSetItemStyle(MultiboardGetItem(board.bBoard, row, col), text, icon) endmethod endstruct // ============================================================ // Row Struct // ============================================================ struct BoardRow extends array // row = Mod(integer(this), 100) // board = (integer(this) - Mod(integer(this), 100)) / 100 // ============== public method operator [] takes integer col returns BoardItem // board * 10000 + row * 100 + col = BoardItem local Board b = ((integer(this) - Mod(integer(this), 100)) / 100) if col >= b.bColCount then call MultiboardSetColumnCount(b.bBoard, col + 1) set b.bColCount = col + 1 endif return integer(b) * 10000 + Mod(integer(this), 100) * 100 + col endmethod public method operator position takes nothing returns integer return Mod(integer(this), 100) endmethod // ============== //! textmacro BoardRow_Set_Start local integer row = Mod(integer(this), 100) local Board board = (integer(this) - Mod(integer(this), 100)) / 100 local integer i = 0 loop exitwhen i == board.bColCount //! endtextmacro //! textmacro BoardRow_Set_End set i = i + 1 endloop //! endtextmacro public method operator text= takes string val returns nothing //! runtextmacro BoardRow_Set_Start() call MultiboardSetItemValue(MultiboardGetItem(board.bBoard, row, i), val) //! runtextmacro BoardRow_Set_End() endmethod public method operator icon= takes string val returns nothing //! runtextmacro BoardRow_Set_Start() call MultiboardSetItemIcon(MultiboardGetItem(board.bBoard, row, i), val) //! runtextmacro BoardRow_Set_End() endmethod public method operator color= takes ARGB c returns nothing //! runtextmacro BoardRow_Set_Start() call MultiboardSetItemValueColor(MultiboardGetItem(board.bBoard, row, i), c.red, c.green, c.blue, c.alpha) //! runtextmacro BoardRow_Set_End() endmethod public method operator width= takes real r returns nothing //! runtextmacro BoardRow_Set_Start() call MultiboardSetItemWidth(MultiboardGetItem(board.bBoard, row, i), r) //! runtextmacro BoardRow_Set_End() endmethod public method setDisplay takes boolean text, boolean icon returns nothing //! runtextmacro BoardRow_Set_Start() call MultiboardSetItemStyle(MultiboardGetItem(board.bBoard, row, i), text, icon) //! runtextmacro BoardRow_Set_End() endmethod endstruct // ============================================================ // Column Struct // ============================================================ struct BoardColumn extends array // col = Mod(integer(this), 100) // board = (integer(this) - Mod(integer(this), 100)) / 100 // ============== public method operator [] takes integer row returns BoardItem // board * 10000 + row * 100 + col = BoardItem local Board b = ((integer(this) - Mod(integer(this), 100)) / 100) if row >= b.bRowCount then call MultiboardSetRowCount(b.bBoard, row + 1) set b.bRowCount = row + 1 endif return integer(b) * 10000 + row * 100 + Mod(integer(this), 100) endmethod public method operator position takes nothing returns integer return Mod(integer(this), 100) endmethod // ============== //! textmacro BoardColumn_Set_Start local integer col = Mod(integer(this), 100) local Board board = (integer(this) - Mod(integer(this), 100)) / 100 local integer i = 0 loop exitwhen i == board.bRowCount //! endtextmacro //! textmacro BoardColumn_Set_End set i = i + 1 endloop //! endtextmacro public method operator text= takes string val returns nothing //! runtextmacro BoardColumn_Set_Start() call MultiboardSetItemValue(MultiboardGetItem(board.bBoard, i, col), val) //! runtextmacro BoardColumn_Set_End() endmethod public method operator icon= takes string val returns nothing //! runtextmacro BoardColumn_Set_Start() call MultiboardSetItemIcon(MultiboardGetItem(board.bBoard, i, col), val) //! runtextmacro BoardColumn_Set_End() endmethod public method operator color= takes ARGB c returns nothing //! runtextmacro BoardColumn_Set_Start() call MultiboardSetItemValueColor(MultiboardGetItem(board.bBoard, i, col), c.red, c.green, c.blue, c.alpha) //! runtextmacro BoardColumn_Set_End() endmethod public method operator width= takes real r returns nothing //! runtextmacro BoardColumn_Set_Start() call MultiboardSetItemWidth(MultiboardGetItem(board.bBoard, i, col), r) //! runtextmacro BoardColumn_Set_End() endmethod public method setDisplay takes boolean text, boolean icon returns nothing //! runtextmacro BoardColumn_Set_Start() call MultiboardSetItemStyle(MultiboardGetItem(board.bBoard, i, col), text, icon) //! runtextmacro BoardColumn_Set_End() endmethod endstruct // ============================================================ // Helper Structs (For [][], .col[], .row[]) // ============================================================ private struct ItemHelper extends array public method operator[] takes integer row returns BoardItem local integer col = Board(this).bTempCol static if DEBUG_MODE then if row < 0 then call ErrorMsg("Board.[" + I2S(col) + "][" + I2S(row) + "]", "Given row id is less than 0") endif if col < 0 then call ErrorMsg("Board.[" + I2S(col) + "][" + I2S(row) + "]", "Given col id is less than 0") endif endif //i = brd * 10000 + row * 100 + col if col >= Board(this).bColCount then call MultiboardSetColumnCount(Board(this).bBoard, col + 1) set Board(this).bColCount = col + 1 endif if row >= Board(this).bRowCount then call MultiboardSetRowCount(Board(this).bBoard, row + 1) set Board(this).bRowCount = row + 1 endif return integer(this) * 10000 + row * 100 + Board(this).bTempCol endmethod endstruct private struct RowHelper extends array public method operator count takes nothing returns integer return Board(this).bRowCount endmethod public method operator count= takes integer i returns nothing call MultiboardSetRowCount(Board(this).bBoard, i + 1) set Board(this).bRowCount = i + 1 endmethod public method operator[] takes integer row returns BoardRow static if DEBUG_MODE then if row < 0 then call ErrorMsg("Board.row[" + I2S(row) + "]", "Given row id is less than 0") endif endif if row >= Board(this).bRowCount then call MultiboardSetRowCount(Board(this).bBoard, row + 1) set Board(this).bRowCount = row + 1 endif if Board(this).bColCount < 1 then call MultiboardSetColumnCount(Board(this).bBoard, 1) set Board(this).bColCount = 1 endif return BoardRow(row + integer(this) * 100) endmethod endstruct private struct ColumnHelper extends array public method operator count takes nothing returns integer return Board(this).bColCount endmethod public method operator count= takes integer i returns nothing call MultiboardSetColumnCount(Board(this).bBoard, i + 1) set Board(this).bColCount = i + 1 endmethod public method operator[] takes integer col returns BoardColumn static if DEBUG_MODE then if col < 0 then call ErrorMsg("Board.col[" + I2S(col) + "]", "Given column id is less than 0") endif endif if col >= Board(this).bColCount then call MultiboardSetColumnCount(Board(this).bBoard, col + 1) set Board(this).bColCount = col + 1 endif if Board(this).bRowCount < 1 then call MultiboardSetRowCount(Board(this).bBoard, 1) set Board(this).bRowCount = 1 endif return BoardColumn(col + integer(this) * 100) endmethod endstruct // ============================================================ // Board Struct // ============================================================ struct Board multiboard bBoard integer bColCount = 0 integer bRowCount = 0 integer bTempCol public static method create takes nothing returns thistype local thistype this = allocate() set bBoard = CreateMultiboard() call MultiboardSetItemsWidth(bBoard, 0) call MultiboardSetItemsStyle(bBoard, true, false) return this endmethod private method onDestroy takes nothing returns nothing call DestroyMultiboard(bBoard) set bBoard = null endmethod //================== public method operator[] takes integer column returns ItemHelper set bTempCol = column return ItemHelper(this) endmethod public method operator col takes nothing returns ColumnHelper return ColumnHelper(this) endmethod public method operator row takes nothing returns RowHelper return RowHelper(this) endmethod //================== public method operator title= takes string value returns nothing call MultiboardSetTitleText(bBoard, value) endmethod public method operator titleColor= takes ARGB color returns nothing call MultiboardSetTitleTextColor(bBoard, color.red, color.green, color.blue, color.alpha) endmethod public method operator visible= takes boolean b returns nothing call MultiboardDisplay(bBoard, b) endmethod public method clear takes nothing returns nothing call MultiboardClear(bBoard) endmethod endstruct endlibrary Edit: Few talking points / questions: - Do you think it would be useful to be able to easily insert/remove rows and columns from the beginning and middle of a multiboard, instead of just to/from the end? (Would slow down all operations slightly.) - Should visibility per-player be handled by the system? - Should those operators in BoardItem really be named .x and .y? |
| 11-05-2009, 08:39 AM | #2 | |
Nice one thanks a lot. I actually needed this for my new AoS. (I was thinking about making the same thing, but yours is better.) Now I only need to make the generation script! :) Quote:
I find a question or such. Oh one thing: What is keyword for? I have seen it a lot but I still don't get what its used for. |
| 11-05-2009, 08:47 AM | #3 | |
Quote:
private keyword something Causes the specified keyword to be made library-private. That is to say, you can not use those things outside of the library. It is also used to fix a shortcoming in JASS Helper: you can not use a private variable/function/etc before it is declared. You can fix this by declaring it as a private keyword above where you use it. |
| 11-05-2009, 08:50 AM | #4 |
I see, thanks alot. One thing though: How can you allow the user to call functions without the librarys name? (While these functions are inside the library). |
| 11-05-2009, 09:00 AM | #5 | |
Quote:
"public" for functions, globals, and I think struct name as well, makes them available outside the library, but only if they are prefixed with the libraries name followed by an underscore. "private" makes them no available outside the library. no "public" or "private" makes them available outside the library, without prefixing them. Within a struct (that is, for methods and members of a struct) "public" means the same as a lack of "public" or "private". (There is no prefixing within structs, as that would make no sense.) If that's what you where asking. It can be hard to tell <.< |
| 11-05-2009, 09:05 AM | #6 | |||||
JASS:library test function stuff takes nothing returns nothing endfunction endlibrary Quote:
Quote:
Quote:
Quote:
Quote:
|
| 11-05-2009, 11:04 AM | #7 | |
Just a quick comment on the documentation: Quote:
|
| 11-05-2009, 11:18 AM | #8 | |
Quote:
Yes. Yes it is. Also, I forgot that multiboard items are retarded in that MultiboardGetItem() returns a new handle on every invocation, even if an item for that cell exists... also, the items aren't cleaned up with the board... soo, that will be fixed in my next revision. |
| 11-05-2009, 01:45 PM | #9 | |
Quote:
JASS:board[x][y].item = "53" board[x][y].icon = "ReplaceableTextures//..." Also, write serious documentation and submit this shit. Call it "MultiboardHelper" and you're gold. |
| 11-05-2009, 02:23 PM | #10 | |
Quote:
JASS:set board[x][y].icon = "ReplaceableTextures//..." set board[x][y].text = "foo" set board[x][y].color = 0xFFFFFFFF set board[x][y].width = 0.12 call board[x][y].setDisplay(true, true) Hmm, maybe the setDisplay method could be replaced by textShow and iconShow boolean operators instead to match the rest of the syntax? |
| 11-05-2009, 02:24 PM | #11 |
Oh, okay, so it uses .text, fair enough. I must've missed that. |
| 11-05-2009, 08:24 PM | #12 | ||
Quote:
Problem is that doing that would require storing both those booleans somehow, as setting one requires setting the other, and there is no getter function. As-is, nothing can be stored, as all the structs are by-value. Though, I have been thinking about ways to store data for items in a hashtable... So it's still a possibility. Quote:
|
| 11-05-2009, 08:44 PM | #13 |
Awesome system! |
| 11-05-2009, 08:48 PM | #14 | |
Quote:
|
| 11-05-2009, 11:57 PM | #15 |
Definately allow local stuff, it is useful quite often Same with removing and adding rows to middle x&y are fine names |
