The “Magic” behind Data Binding (Part 2: Commands and Data Tree)

In the first part I talked about the basics of data binding, namely the data context and the data property, which define the data that is provided from the logic for the presentation side of your game. This makes it possible to visualize the data and react on data changes.

One part is missing though: Giving the presentation side a possibility to send desired actions into the logic, e.g. when the user clicks on a button. This feature is implemented by commands.

How to use commands

First let’s go to our data context another time. Here we can define which actions are available to be called by the presentation side by defining public void  methods:

You can use as many parameters as you like, but the command on the presentation side we create later has to provide these parameters, of course. Most of the time you won’t need any or only one.

Creating the UI and making the connection

Now that we know which actions the data context supports, we can create an interface which let’s the user call those actions. In our example we could use an input field where the user types in his message and a button with which he can send it.

Simple UI to use the button click command and the text of an input field as a parameter

You are free to create a much fancier user interface then mine, of course 😉 But the interface itself won’t do much on its own, so let’s create the connection to the data context. This is where our commands come into play.

What we want to do is call the  SubmitMessage method with the text of the input field as the parameter. Data Bind for Unity already contains a bunch of predefined commands, so we can just use the  ButtonClickCommand by adding the component to our button and choosing the path to the method we like to invoke on a click.

ButtonClickCommand connected to SubmitMessage method
ButtonClickCommand connected to SubmitMessage method

If there weren’t any parameters to the command, we would be already done. But as we don’t go the easy way, we have to provide an additional parameter for the command, otherwise it won’t work.

Providing command parameters

As we said earlier we like to send the content of the input field as a parameter when the button is clicked. Therefore we need a way to grab the text from the input field. Luckily the InputFieldGetter script does this job for us. Getters in Data Bind have two functions:

  • Update a data property when a value on presentation side changed, e.g. for input fields, sliders, toggles,…
  • Provide a generic data interface for commands and other bindings
InputFieldGetter on an input field
InputFieldGetter on an input field

All Getters derive from the DataProvider  class. This mono behaviour manages a single data value, quite similar to a data property. Other bindings can use the value and are informed when it changes.

Back to our ButtonClickCommand : The base Command  class has a member called  AdditionalArguments  where we can reference any number of data providers. In our case we need only one, the InputFieldGetter  we put on our input field. We can just drag the input field on the additional arguments list and the connection is made.

ButtonClickCommand with additional argument from InputFieldGetter
ButtonClickCommand with additional argument from InputFieldGetter

If we click the button in our game now, the current value of the provided data provider is send as a parameter to our SubmitMessage  method.

Behind the scenes

So what’s happening exactly? As you learned in part 1 there are three method the Context class provides:

  • object RegisterListener(string path, Action<object> onValueChanged)
  • void RemoveListener(string path, Action<object> onValueChanged)
  • void SetValue(string path, object value)

For our commands we use the first two, so it is not much different to register a listener for a data value. Besides we register for a method instead of a field or a property. If a path in a data context points to a method, a delegate is returned as the value of this path.

If the command detects its trigger, e.g. a button click, it uses this delegate to invoke the method on the data context and passes the additional arguments as parameters. It’s important that the number and type of the parameters match, otherwise the invocation won’t be successful.

A more detailed example of the command usage is included in the Data Bind for Unity asset, called InputFieldGetterExample. You may just dive in there if you like to see it working. If you have any detailed questions about commands, just write a comment or contact me.

Some more details about data nodes

When I read through part 1 once more, I realized that it may not have become clear how the context base class works exactly when providing the data values to the bindings.

Just think about the context as a data tree. The root node is the context itself and each node can have children on its own.

A simple example data tree: One possible path would be “SubContext.Data”

When RegisterListener  is called with a path, the context traverses this tree with the parts of the path and registers the callback at the found node.

If a value in the tree changes, the callbacks on this node are called. Furthermore the children of the node are updated as well as they may have changed by this data change, too. This way one can easily register itself for a data property of a sub context and is also informed if the whole sub context changes.

So the data nodes are really just another representation of the data provided by the context which contain additional meta information about each node for fast access and management of the callbacks from the bindings.

Part 2 summary

Good thing I split up the post, it would have been far to much for a single one. In this part you got some insights about:

  • Commands
    • How to define the actions in the data context
    • How to add them on the UI side
    • How to provide additional parameters for a command
    • How they work
  • Data nodes
    • How they look like
    • What they are good for

There are many more details about how the Data Bind asset works, but for now this should be enough to understand the basics. If you are interested in learning more, check out the documentation and the API. Let me know if a topic is of particular interest for you, then I’ll consider to write another post about it.

Our asset got its second update yesterday and its functionality grew quite a bit. As it was planned, I’ll raise the price for it with the next update soon, so be smart and grab it while it’s still 10$ if you haven’t already 🙂

Thanks for your time reading my stuff, hope you enjoyed it!

  • ChiuanWei

    I love the asset,and i am thinking about the good way to generate the Data Nodes. Its better to use Editor Window to create nodes and generate the data class automatic.