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.
 

Steel

Software Engineer
Reaction score
109
Nicely done, very clean and quite useful for newer users to Multiboards.
 

quraji

zap
Reaction score
144
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.
 

Romek

Super Moderator
Reaction score
964
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.
 

Azlier

Old World Ghost
Reaction score
461
>I also happened to be making a multiboard system.

So was I. Why must we all think alike?

I love vJassified stuff <3.
 
Reaction score
91
> 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).
 

quraji

zap
Reaction score
144
Well, like the name suggests, this is not really a system but a wrapper. Which is why I suggested some features :p
 

Steel

Software Engineer
Reaction score
109
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?
 

quraji

zap
Reaction score
144
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).
 

saw792

Is known to say things. That is all.
Reaction score
280
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.
 

dudeim

New Member
Reaction score
22
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;))
 

Darthfett

Aerospace/Cybersecurity Software Engineer
Reaction score
615
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.
 

Chaos_Knight

New Member
Reaction score
39
Very cool system.. Maybe a bit to complex for me yet.
And i still dont understand how to use and implent it...
 

dudeim

New Member
Reaction score
22
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.
  • The Helper The Helper:
    I am great and it is fantastic to see you my friend!
    +1
  • The Helper The Helper:
    If you are new to the site please check out the Recipe and Food Forum https://www.thehelper.net/forums/recipes-and-food.220/
  • Monovertex Monovertex:
    How come you're so into recipes lately? Never saw this much interest in this topic in the old days of TH.net
  • Monovertex Monovertex:
    Hmm, how do I change my signature?
  • tom_mai78101 tom_mai78101:
    Signatures can be edit in your account profile. As for the old stuffs, I'm thinking it's because Blizzard is now under Microsoft, and because of Microsoft Xbox going the way it is, it's dreadful.
  • The Helper The Helper:
    I am not big on the recipes I am just promoting them - I use the site as a practice place promoting stuff
    +2
  • Monovertex Monovertex:
    @tom_mai78101 I must be blind. If I go on my profile I don't see any area to edit the signature; If I go to account details (settings) I don't see any signature area either.
  • The Helper The Helper:
    You can get there if you click the bell icon (alerts) and choose preferences from the bottom, signature will be in the menu on the left there https://www.thehelper.net/account/preferences
  • The Helper The Helper:
    I think I need to split the Sci/Tech news forum into 2 one for Science and one for Tech but I am hating all the moving of posts I would have to do
  • The Helper The Helper:
    What is up Old Mountain Shadow?
  • The Helper The Helper:
    Happy Thursday!
    +1
  • Varine Varine:
    Crazy how much 3d printing has come in the last few years. Sad that it's not as easily modifiable though
  • Varine Varine:
    I bought an Ender 3 during the pandemic and tinkered with it all the time. Just bought a Sovol, not as easy. I'm trying to make it use a different nozzle because I have a fuck ton of Volcanos, and they use what is basically a modified volcano that is just a smidge longer, and almost every part on this thing needs to be redone to make it work
  • Varine Varine:
    Luckily I have a 3d printer for that, I guess. But it's ridiculous. The regular volcanos are 21mm, these Sovol versions are about 23.5mm
  • Varine Varine:
    So, 2.5mm longer. But the thing that measures the bed is about 1.5mm above the nozzle, so if I swap it with a volcano then I'm 1mm behind it. So cool, new bracket to swap that, but THEN the fan shroud to direct air at the part is ALSO going to be .5mm to low, and so I need to redo that, but by doing that it is a little bit off where it should be blowing and it's throwing it at the heating block instead of the part, and fuck man
  • Varine Varine:
    I didn't realize they designed this entire thing to NOT be modded. I would have just got a fucking Bambu if I knew that, the whole point was I could fuck with this. And no one else makes shit for Sovol so I have to go through them, and they have... interesting pricing models. So I have a new extruder altogether that I'm taking apart and going to just design a whole new one to use my nozzles. Dumb design.
  • Varine Varine:
    Can't just buy a new heatblock, you need to get a whole hotend - so block, heater cartridge, thermistor, heatbreak, and nozzle. And they put this fucking paste in there so I can't take the thermistor or cartridge out with any ease, that's 30 dollars. Or you can get the whole extrudor with the direct driver AND that heatblock for like 50, but you still can't get any of it to come apart
  • Varine Varine:
    Partsbuilt has individual parts I found but they're expensive. I think I can get bits swapped around and make this work with generic shit though
  • Ghan Ghan:
    Heard Houston got hit pretty bad by storms last night. Hope all is well with TH.
  • The Helper The Helper:
    Power back on finally - all is good here no damage
    +2
  • V-SNES V-SNES:
    Happy Friday!
    +1
  • The Helper The Helper:
    New recipe is another summer dessert Berry and Peach Cheesecake - https://www.thehelper.net/threads/recipe-berry-and-peach-cheesecake.194169/

      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