System Multiboard (Wrapper)

Darthfett

Aerospace/Cybersecurity Software Engineer
Reaction score
615
Multiboard
Created By: Darthfett

vJASS
Leakless


What is Multiboard?

The Multiboard wrapper system is simply an easier way to work with Multiboards. It keeps track of all the multiboarditems and provides a few useful functions, as well as all of the original multiboard functions (many will inline, or cost little more than a function call and a few comparisons).

Why Use Multiboard?

To understand why you might use Multiboard, you should first look at the problems with native multiboard use:

  • Forced to use multiboarditems
  • Ugly, sometimes inefficient BJ functions
  • multiboarditems leak if they are not released.

This is what the vJASS Multiboard gives to you:

  • Removes the need to work with multiboarditems individually.
  • Has an improved algorithm when modifying multiple rows or columns.
  • Will automatically recycle multiboarditems and remove them when no longer needed
  • Simplistic O.O. syntax.

How do I Use Multiboard?

Using the Multiboard wrapper is relatively simple. Methods are named according to what they replace. For example, to create a multiboard, simply do this:

JASS:
local Multiboard mb = Multiboard.create(COLUMN_COUNT,ROW_COUNT)


Or, to set an item (or items) value, simply use the setItemValue method. See the following tips when working with the "setItem___" methods:

  • Columns always come before Rows
  • Columns and Rows start at 0
  • Use -1 to refer to all columns or rows

All functions which are not documented are equivalent to the function they call inside. They will also inline.

functions that modify a multiboarditem, such as setItemValue, replace the singular MultiboardSetItemValue, the MultiboardSetItemsValue, as well as the MultiboardSetItemValueBJ function.

Function list:

JASS:
    static method create takes integer columnCount, integer rowCount returns Multiboard
    //Creates a new Multiboard and sets up the columns and rows.
    
    method destroy takes nothing returns nothing
    //Cleans up the Multiboard and related items
    
    method clear takes nothing returns nothing
    //Clears the multiboard
    
//======================================================================================
//======================================================================================
    
    method display takes boolean flag returns nothing
    //Displays the multiboard to all players
    
    method displayToPlayer takes player whichPlayer, boolean flag returns nothing
    //Displays the multiboard to a specified player.
    
    method minimize takes boolean flag returns nothing
    //Minimizes the multiboard for all players
    
    method minimizeForPlayer takes player whichPlayer, boolean flag returns nothing
    //Minimizes the multiboard for a specified player
    
    static method suppress takes boolean flag returns nothing
    //Suppresses all multiboards for all players
    
    static method suppressForPlayer takes player p, boolean flag returns nothing
    //Suppresses all multiboards for a specified player
    
//======================================================================================

    method setColumnCount takes integer count returns nothing
    //Changes the specified amount of columns.  Does not need to be run on Multiboard Init.
    //If the amount is less than the previous amount, it will clean up leaks
    
    method getColumnCount takes nothing returns integer
    //Number of columns in the multiboard
    
    method setRowCount takes integer count returns nothing
    //Changes the specified amount of rows.  Does not need to be run on Multiboard Init.
    //If the amount is less than the previous amount, it will clean up leaks
    
    method getRowCount takes nothing returns integer
    //Number of rows in the multiboard
    
//======================================================================================

    method setTitleText takes string label returns nothing
    //Sets the title's text
    
    method setTitleTextColor takes integer red, integer green, integer blue, integer alpha returns nothing
    //Sets the title's text color
    
    method setItemValue takes integer column, integer row, string val returns nothing
    //sets the specified item's value.  If -1 is used for column or row, it will set all of them.
    //Using a Column or Row higher than the current max will result in the function not doing anything.

    method setItemColor takes integer column, integer row, integer red, integer green, integer blue, integer alpha returns nothing
    //sets the specified item's color.  If -1 is used for column or row, it will set all of them.
    //Using a Column or Row higher than the current max will result in the function not doing anything.
    
    method setItemWidth takes integer column, integer row, real width returns nothing
    //sets the specified item's width.  If -1 is used for column or row, it will set all of them.
    //Using a Column or Row higher than the current max will result in the function not doing anything.
    
    method setItemIcon takes integer column, integer row, string iconFileName returns nothing
    //sets the specified item's icon.  If -1 is used for column or row, it will set all of them.
    //Using a Column or Row higher than the current max will result in the function not doing anything.
    
    method setItemStyle takes integer column, integer row, boolean showValue, boolean showIcon returns nothing
    //sets the specified item's style.  If -1 is used for column or row, it will set all of them.
    //Using a Column or Row higher than the current max will result in the function not doing anything.
    
//======================================================================================
//======================================================================================
//======================================================================================
    
    method isDisplayed takes nothing returns boolean
    //returns whether the multiboard is being displayed 
    //Beware when using this with displayToPlayer, it can cause desyncs.
    
    method isMinimized takes nothing returns boolean
    //returns whether "this" is minimized
    //Beware when using this with minimizeForPlayer, it can cause desyncs.


Now for the System:

JASS:
library Multiboard

//Configurables:
globals
    private constant integer MAX_COLUMN_COUNT = 16
    private constant integer MAX_ROW_COUNT    = 16
endglobals

//======================================================================================

globals
    private constant integer MAX_COUNT = MAX_COLUMN_COUNT * MAX_ROW_COUNT //Don't Touch
endglobals

struct Multiboard
    private multiboard which

    private multiboarditem array MBIZ[MAX_COUNT] //MultiBoardItemZ (Z stands for Array)
    
    private integer columnCount
    private integer rowCount
    
//======================================================================================
//======================================================================================
    
    static method create takes integer columnCount, integer rowCount returns Multiboard
    //Creates a new Multiboard and sets up the columns and rows.
        local Multiboard this = Multiboard.allocate()
        local integer i = 0
        local integer j = 0
        set .which = CreateMultiboard()
        set .columnCount = columnCount
        set .rowCount = rowCount
        call MultiboardSetColumnCount(.which,columnCount)
        call MultiboardSetRowCount(.which,rowCount)
        loop
            exitwhen i > .columnCount
            loop
                exitwhen j > .rowCount
                set .MBIZ[i * MAX_ROW_COUNT + j] = MultiboardGetItem(.which,j,i)
                set j = j + 1
            endloop
            set j = 0
            set i = i + 1
        endloop
        return this
    endmethod
    
    private method onDestroy takes nothing returns nothing
    //Cleans up the Multiboard and related items
        local integer i = 0
        local integer j
        loop
            exitwhen i > .columnCount
            set j = 0
            loop
                exitwhen j > .rowCount
                call MultiboardReleaseItem(.MBIZ[i * MAX_ROW_COUNT + j])
                set j = j + 1
            endloop
            set i = i + 1
        endloop
        call MultiboardClear(.which)
        call DestroyMultiboard(.which)
    endmethod    
    
    method clear takes nothing returns nothing
        call MultiboardClear(.which)
    endmethod
    
//======================================================================================
//======================================================================================
    
    method display takes boolean flag returns nothing
        call MultiboardDisplay(.which,flag)
    endmethod
    
    method displayToPlayer takes player whichPlayer, boolean flag returns nothing
    //Displays the multiboard to a specified player.
        call MultiboardDisplay(.which,(GetLocalPlayer() == whichPlayer) and flag)
    endmethod
    
    method minimize takes boolean flag returns nothing
        call MultiboardMinimize(.which,flag)
    endmethod
    
    method minimizeForPlayer takes player whichPlayer, boolean flag returns nothing
    //Minimizes the multiboard for a specified player.
        call MultiboardMinimize(.which,(GetLocalPlayer() == whichPlayer) and flag)
    endmethod
    
    static method suppress takes boolean flag returns nothing
        call MultiboardSuppressDisplay(flag)
    endmethod
    
    static method suppressForPlayer takes player p, boolean flag returns nothing
    //Suppresses all multiboards for a specified player
        call MultiboardSuppressDisplay((GetLocalPlayer() == p) and flag)
    endmethod
    
//======================================================================================

    method setColumnCount takes integer count returns nothing
    //Changes the specified amount of columns.  Does not need to be run on Multiboard Init.
    //If the amount is less than the previous amount, it will clean up leaks
        local integer i
        local integer j = 0
        if count > MAX_COLUMN_COUNT then
            set count = MAX_COLUMN_COUNT
        endif
        call MultiboardSetColumnCount(.which,count)
        if count < .columnCount then
            loop
                exitwhen j > .rowCount
                set i = count
                loop
                    exitwhen i > .columnCount
                    call MultiboardReleaseItem(.MBIZ[i * MAX_ROW_COUNT + j])
                    set i = i + 1
                endloop
                set j = j + 1
            endloop
        endif
        set .columnCount = count
    endmethod
    
    method getColumnCount takes nothing returns integer
        return .columnCount
    endmethod
    
    method setRowCount takes integer count returns nothing
    //Changes the specified amount of rows.  Does not need to be run on Multiboard Init.
    //If the amount is less than the previous amount, it will clean up leaks
        local integer i = 0
        local integer j
        if count > MAX_ROW_COUNT then
            set count = MAX_ROW_COUNT
        endif
        call MultiboardSetRowCount(.which,count)
        if count < .rowCount then
            loop
                exitwhen i > .columnCount
                set j = count
                loop
                    exitwhen j > .rowCount
                    call MultiboardReleaseItem(.MBIZ[i * MAX_ROW_COUNT + j])
                    set j = j + 1
                endloop
                set i = i + 1
            endloop
        endif
        set .rowCount = count
    endmethod
    
    method getRowCount takes nothing returns integer
        return .rowCount
    endmethod
    
//======================================================================================

    method setTitleText takes string label returns nothing
        call MultiboardSetTitleText(.which,label)
    endmethod
    
    method setTitleTextColor takes integer red, integer green, integer blue, integer alpha returns nothing
        call MultiboardSetTitleTextColor(.which,red,green,blue,alpha)
    endmethod
    
    method setItemValue takes integer column, integer row, string val returns nothing
    //Works similar to the MultiboardSetItem* functions.
    //However, a value of 0 refers to the first column/row, -1 refers to all columns/rows
    //Using a Column or Row higher than the current max will result in the function not doing anything.
        local integer curCol = 0
        local integer curRow = 0
        if column > .columnCount or row > .rowCount then
            return
        endif
        if column == -1 or row == -1 then
            if column == -1 and row == -1 then
                call MultiboardSetItemsValue(.which,val)
                return
            elseif column == -1 then
                loop
                    exitwhen curCol > .columnCount
                    call MultiboardSetItemValue(.MBIZ[curCol * MAX_ROW_COUNT + row],val)
                    set curCol = curCol + 1
                endloop
                return
            else
                loop
                    exitwhen curRow > .rowCount
                    call MultiboardSetItemValue(.MBIZ[column * MAX_ROW_COUNT + curRow],val)
                    set curRow = curRow + 1
                endloop
                return
            endif
        endif
        call MultiboardSetItemValue(.MBIZ[column * MAX_ROW_COUNT + row],val)
    endmethod

    method setItemColor takes integer column, integer row, integer red, integer green, integer blue, integer alpha returns nothing
    //Works similar to the MultiboardSetItem* functions.
    //However, a value of 0 refers to the first column/row, -1 refers to all columns/rows
    //Using a Column or Row higher than the current max will result in the function not doing anything.
        local integer curCol = 0
        local integer curRow = 0
        if column > .columnCount or row > .rowCount then
            return
        endif
        if column == -1 or row == -1 then
            if column == -1 and row == -1 then
                call MultiboardSetItemsValueColor(.which,red,green,blue,alpha)
                return
            elseif column == -1 then
                loop
                    exitwhen curCol > .columnCount
                    call MultiboardSetItemValueColor(.MBIZ[curCol * MAX_ROW_COUNT + row],red,green,blue,alpha)
                    set curCol = curCol + 1
                endloop
                return
            else
                loop
                    exitwhen curRow > .rowCount
                    call MultiboardSetItemValueColor(.MBIZ[column * MAX_ROW_COUNT + curRow],red,green,blue,alpha)
                    set curRow = curRow + 1
                endloop
                return
            endif
        endif
        call MultiboardSetItemValueColor(.MBIZ[column * MAX_ROW_COUNT + row],red,green,blue,alpha)
    endmethod
    
    method setItemWidth takes integer column, integer row, real width returns nothing
    //Works similar to the MultiboardSetItem* functions.
    //However, a value of 0 refers to the first column/row, -1 refers to all columns/rows
    //Using a Column or Row higher than the current max will result in the function not doing anything.
        local integer curCol = 0
        local integer curRow = 0
        if column > .columnCount or row > .rowCount then
            return
        endif
        if column == -1 or row == -1 then
            if column == -1 and row == -1 then
                call MultiboardSetItemsWidth(.which,width)
                return
            elseif column == -1 then
                loop
                    exitwhen curCol > .columnCount
                    call MultiboardSetItemWidth(.MBIZ[curCol * MAX_ROW_COUNT + row],width)
                    set curCol = curCol + 1
                endloop
                return
            else
                loop
                    exitwhen curRow > .rowCount
                    call MultiboardSetItemWidth(.MBIZ[column * MAX_ROW_COUNT + curRow],width)
                    set curRow = curRow + 1
                endloop
                return
            endif
        endif
        call MultiboardSetItemWidth(.MBIZ[column * MAX_ROW_COUNT + row],width)
    endmethod
    
    method setItemIcon takes integer column, integer row, string iconFileName returns nothing
    //Works similar to the MultiboardSetItem* functions.
    //However, a value of 0 refers to the first column/row, -1 refers to all columns/rows
    //Using a Column or Row higher than the current max will result in the function not doing anything.
        local integer curCol = 0
        local integer curRow = 0
        if column > .columnCount or row > .rowCount then
            return
        endif
        if column == -1 or row == -1 then
            if column == -1 and row == -1 then
                call MultiboardSetItemsIcon(.which,iconFileName)
                return
            elseif column == -1 then
                loop
                    exitwhen curCol > .columnCount
                    call MultiboardSetItemIcon(.MBIZ[curCol * MAX_ROW_COUNT + row],iconFileName)
                    set curCol = curCol + 1
                endloop
                return
            else
                loop
                    exitwhen curRow > .rowCount
                    call MultiboardSetItemIcon(.MBIZ[column * MAX_ROW_COUNT + curRow],iconFileName)
                    set curRow = curRow + 1
                endloop
                return
            endif
        endif
        call MultiboardSetItemIcon(.MBIZ[column * MAX_ROW_COUNT + row],iconFileName)
    endmethod
    
    method setItemStyle takes integer column, integer row, boolean showValue, boolean showIcon returns nothing
    //Works similar to the MultiboardSetItem* functions.
    //However, a value of 0 refers to the first column/row, -1 refers to all columns/rows
    //Using a Column or Row higher than the current max will result in the function not doing anything.
        local integer curCol = 0
        local integer curRow = 0
        if column > .columnCount or row > .rowCount then
            return
        endif
        if column == -1 or row == -1 then
            if column == -1 and row == -1 then
                call MultiboardSetItemsStyle(.which,showValue,showIcon)
                return
            elseif column == -1 then
                loop
                    exitwhen curCol > .columnCount
                    call MultiboardSetItemStyle(.MBIZ[curCol * MAX_ROW_COUNT + row],showValue,showIcon)
                    set curCol = curCol + 1
                endloop
                return
            else
                loop
                    exitwhen curRow > .rowCount
                    call MultiboardSetItemStyle(.MBIZ[column * MAX_ROW_COUNT + curRow],showValue,showIcon)
                    set curRow = curRow + 1
                endloop
                return
            endif
        endif
        call MultiboardSetItemStyle(.MBIZ[column * MAX_ROW_COUNT + row],showValue,showIcon)
    endmethod
    
//======================================================================================
//======================================================================================
//======================================================================================
    
    method isDisplayed takes nothing returns boolean
        return IsMultiboardDisplayed(.which)
    endmethod
    
    method isMinimized takes nothing returns boolean
        return IsMultiboardMinimized(.which)
    endmethod
    
endstruct

endlibrary


Comments and Reviews are always appreciated! Happy Mapping.
 
Nicely done, very clean and quite useful for newer users to Multiboards.
 
Meh, and I was just going to finish mine and put it up.

But, my multiboard2 has a feature your Multiboard doesn't have. It makes it easy to make multiboards with a variable amount of columns among rows. At least, that's the illusion. ;)
It also makes it easier to make menus with button push events and that stuff but that's less important :p

Good stuff anyways.
 
I also happened to be making a multiboard system. :p
I guess you beat us all to it.

Don't worry about speed/inlining here; multiboards aren't meant for speed anyway.
 
>I also happened to be making a multiboard system.

So was I. Why must we all think alike?

I love vJassified stuff <3.
 
> I also happened to be making a multiboard system.
Lol, me too... I was using some old multiboard system by Magentix and thought it needed a remake but it seems Darth was the fastest (or maybe not that lazy).
 
Well, like the name suggests, this is not really a system but a wrapper. Which is why I suggested some features :p
 
I can't remember how struct deconstructors are handled but in your onDestroy method you have: call DestroyMultiboard(.which)

Clearly this is to destroy it, but nullification isn't necessary? Can someone clarify please, does the struct default ondestroy nullify all members?
 
I can't remember how struct deconstructors are handled but in your onDestroy method you have: call DestroyMultiboard(.which)

Clearly this is to destroy it, but nullification isn't necessary? Can someone clarify please, does the struct default ondestroy nullify all members?

You don't really need to nullify globals (struct members are globals).
 
I was also making a multiboard system. Bet yours can't detect when a player is wearing blue pants and change the colour of his name on the multiboard to that colour!

On a serious note, this is really useful, saves a shitload of time.
 
how do I call the methods that arn't static? as I can't use Multiboard.setitemstyle(etc..) for example it gives me an error that the method isn't static (sorry if it's a dumb question not alot of knowledge here with methods;))
 
how do I call the methods that arn't static? as I can't use Multiboard.setitemstyle(etc..) for example it gives me an error that the method isn't static (sorry if it's a dumb question not alot of knowledge here with methods;))

Non-static methods mean that you call it via one of the created structs, such as this:

JASS:
local Multiboard myBoard = Multiboard.create(2,2)
call myBoard.setItemStyle(-1,-1,true,false)


This would create a 2x2 multiboard named myBoard, and then change all the items in myBoard's style to show the value, but hide the icon.
 
Very cool system.. Maybe a bit to complex for me yet.
And i still dont understand how to use and implent it...
 
Non-static methods mean that you call it via one of the created structs, such as this:

JASS:

local Multiboard myBoard = Multiboard.create(2,2)
call myBoard.setItemStyle(-1,-1,true,false)


This would create a 2x2 multiboard named myBoard, and then change all the items in myBoard's style to show the value, but hide the icon.

ok thanks man;)
Edit: ok I got the above but how would I call that multiboard in another trigger? set the multiboard to a global instead of a local var?
 
General chit-chat
Help Users
  • No one is chatting at the moment.
  • Varine Varine:
    +1
  • Varine Varine:
    I've been really into this
  • Varine Varine:
    It's a musical retelling of The Odyssey
  • Varine Varine:
    Also if you want mixed drinks without alcohol, there's a handful of non-alcoholic 'spirits'. Ritual Zero and Free Spirit are the two brands I've tried and they are alright. They don't have a TON of options, but they have some gin and whiskey alternatives that are fun to play with.
  • Varine Varine:
    I got a couple bottles to make some mixy drinks around holidays when I mostly want to drink, they aren't exact replacements but they are surprisingly close.
  • Varine Varine:
    I ended up with some hop water things that I really like instead for when I want to feel like I'm participating
  • Varine Varine:
    I just got moved to unsupervised probation, so I can get away with drinking a bit now. I technically am not supposed to, but I don't think I get checked anymore. I really want to smoke weed but it scares me
  • The Helper The Helper:
    Happy Wednesday! I am not feeling it today, my teeth are bothering me, or the fragments that were left behind are coming up and it is extra painful today. Don't ever let them tell you that getting full dental implants is easy. They have to pull all your teeth to do those and apparently they are not very good at getting all the teeth out all the time.
    +1
  • The Helper The Helper:
    That is true with Dentures too. I am taking the day off and working from home. The big difference is though, I am not drinking anymore so I have a nice tea and coffee regimen set up :)
  • Varine Varine:
    I wish i had a 3D scanner
  • Varine Varine:
    That would make what I'm doing SO much easier
  • Varine Varine:
    I guess I could just take a picture of it and then use that as a reference. I have a circuit board with some weird holes I can't get measured right
  • Varine Varine:
    Oh I got a Klipper mod for my big printer! It comes with a bunch of parts and I don't totally understand what it does but apparently it's way better than Marlin, which is I think what it currently runs
    +1
  • The Helper The Helper:
    Nice!
  • Varine Varine:
    You're people in Florida safe? The only couple I know are safe but I think they evacuated.
  • The Helper The Helper:
    They are without power but safe. Flood damage and stuff alot of tornados hit east Florida. No fatalities or injuries to any of my people that I know of
  • The Helper The Helper:
    They have been through all the Florida hurricanes they are like me I have been through every texas hurricane for the last 50 years.
  • The Helper The Helper:
    Never evacuated.
  • The Helper The Helper:
    Check out this bad ass Chicken Noodle soup recipe - https://www.thehelper.net/threads/crack-chicken-noodle-soup.196687/
  • The Helper The Helper:
    Happy Saturday!
    +1

      The Helper Discord

      Members online

      No members online now.

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top