Skip to content

State Management

newk5 edited this page Jan 26, 2021 · 7 revisions

The state of your GUI is usually dependant on the state and values of your variables. When your code grows, it can become hard to manage all your different variables and keep your GUI in sync with the values of your variables. For example, if you have a score variable that receives its value from the server every few minutes and you want to show that on the screen with a label, you would need to have some code like:

    if (scoreWasReceivedFromServer){
        //save the value you received from the server in the client as you might need it to perform some client side validations
        score = scoreFromServer;
        //get the label that shows the score on the screen
       UI.Label("scoreLabel").Text = score;
    }

The code above is perfectly valid, but if you have alot of client side variables that are tied to GUI Elements, then every time you update the value of a variable you need to update their corresponding GUI Element aswell. You need to constantly keep your variable in sync with the GUI. This is error prone and time consuming.

DecUI provides utilities to manage state for you. The concept is simple:

You create 1 variable, and during the GUIElement creation you bind it to the element. From there on, every time you change the value of your variable, the GUIElement will change too, automatically, to the new value inside your variable. So here's how we do this,

1. Create your data store

UI.Data({
   score = 0
   anotherVar = "hello"
   aTableVar =  { data = 54 }
   anArrayvar =  [ "a", "b", "c" ]
})

You can also insert your variables one by one if you wish using:

UI.newData("score",0);
UI.newData("anotherVar","hello");
UI.newData("aTableVar",{ data = 54 });

You should create all your variables inside the data store. DecUI will provide you with methods to mutate this data and even subscribe to various change events.

2. Bind your variable to your GUIElement

You can only do this when you are creating your GUIElement and you do it by specifying a "bindTo" property

UI.Label({
   id = "scoreLabel"
   bindTo = "score" //here you can specify the name of any variable inside your data store (if your variable is inside a table you use dotted notation like "aTableVar.data")
})

3. Updating the value of your variable

UI.setData("score", 1);

When you change the value of a variable using an update operador (like UI.setData...) DecUI will check if this "score" variable is binded to any GUIElement, and if it is, it will change that GUIElement too. In the example above, the .Text property of the "scoreLabel" we created will be changed to "1" too because we binded the label to the "score" variable.

Accessing your variable

To access a variable inside the data store you use:

local value= UI.getData("score");

You can access nested fields inside a table with dotted notation

local value= UI.getData("aTableVar.data");

There's currently 3 read operators you can use:

  • UI.getData(<key>) - returns data
  • UI.indexOfData(<key>, <item>) - returns the index of <item> in the array
  • UI.eachData(<key>, <function(item)> ) - iterates array and calls <function(item)> for each item in the array

The "key" is your variable name inside the data store.

Updating your variable

The most common way to update your data would be with the .setData operator:

UI.setData("score", 1);

At the moment there's a total of 5 update operators

  • UI.setData(<key>, <value>) - sets/replaces value
  • UI.pushData(<key>, <value>) - pushes <value> to the end of the array
  • UI.popData(<key>, (optional) <position> ) - removes the first element of the array if <position> is not specified, otherwise remove the element on the specified position
  • UI.incData(<key>, (optional) <amount>) - increments by 1 if <amount> is not specified, otherwise, increments by the amount specified
  • UI.decData(<key>, (optional) <amount>) - decrements by 1 if <amount> is not specified, otherwise, decrements by the amount specified

Subscribing to events

There's currently 5 change events you can subscribe to:

  • onChange(oldValue, newValue) - When a value is changed
  • onPush(valueAdded) - When an array is added to
  • onPop(valueRemoved) - When an array value is removed
  • onIncrement(increasedAmount) - When a value is incremented
  • onDecrement(decreasedAmount) - When a value is decremented

You can subscribe to them like this:

UI.Subscribe("score", {
    onChange = function(oldValue, newValue) {
    
    },
    onIncrement = function(increasedAmount) {
    
    }

});

You can subscribe to all 5 events at once if you wish. However keep in mind that the onPop and onPush events are only for arrays and the onIncrement and onDecrement events are only for integers and floats.

Suported elements and components

  • GUILabels
  • GUIEditboxes
  • GUIListboxes
  • GUICheckboxes
  • GUIProgressBars
  • GUIButton
  • Comboboxes
  • Datatables
  • Memoboxes