Sending multiple strings in a single event

There may come a time during development when you wish to send multiple strings as part of an event payload.

There are a few ways this can be achieved.

One is by packing multiple 1s0's together like in this example:

--- @param gre#context mapargs
function CBTestMultipleStrings(mapargs)
  local event = {}
  event.name = "MultipleStrings"
  event.format = "1s0 FirstName 1s0 LastName"
  event.data = {FirstName="Daniel", LastName="Gonzalez"}
  gre.send_event(event)
end


--- @param gre#context mapargs
function ReceiveMultipleStrings(mapargs)
  local event_data = mapargs.context_event_data
  for k,v in pairs(event_data) do
    print(k,v)
  end
end

This will print:

FirstName	Daniel
LastName	Gonzalez

However, strings don't always need to be defined as 1s0's.

For example, If you know that your strings will not exceed a certain size, you can simply specify that maximum size. e.g. if none of your strings will exceed 32 bytes, you can simply change them to 1s32 instead.

Another, more streamlined approach would be to pack all of the strings into a single 1s0. From there you can easily parse the string in Lua to separate the individual strings out again. 

This approach enables the use of certain utilities like JSON to perform this action for you. But it is entirely up to you how you wish to approach it.

 

 

 

0

Comments

2 comments
  • Official comment

    To expand on the idea of sending multiple data points using a single 1s0 value, here is an example of using Lua to serialize tables into readable strings. 

    Let's say we have an application that is sending over some cooking data. This data can include multiple strings and number values.

         cook_mode = { title = "Bake", level = "Low", temp = 350}

    With a simple serialize utility function, we can pass this table in and have it return as a formatted string. 

    function serialize(tb)
      local serialized_tb = {}

      for k,v in pairs(tb) do     
        table.insert(serialized_tb, string.format('%s = [[%s]]', k, v))
      end

      table.sort(serialized_tb)
      return string.format("{ %s }", table.concat(serialized_tb,", ") )
    end

    Passing our cook_mode table into serialize() will return: "{ level = [[Low]], temp = [[350]], title = [[Bake]] }"

    This string can then be sent with SBIO as a single 1s0 data point: 
    gre.send_event_data("set_cook_mode", "1s0 mode_data", { mode_data = serialize(cook_mode), "backend"})

    On the receiving end, we can use Lua to unpack these strings and convert them back to table format.

    loadstring("incoming_cook = " .. mapargs.context_event_data.mode_data)()

    In Storyboard, I can now use the elements in incoming_cook as I would with any other Lua table.

    gre.set_value("screen.title_control.text", incoming_cook.title)

    This will set the text variable in your application as "Bake".

    If you have multiple strings to send over in one event, this method might be one to explore. As mentioned in the post up above, leveraging JSON with a similar workflow would also be an effective strategy for sending multiple data points.

  • Furthermore, some users may need to define custom events that contain fixed length strings (e.g. 1s32) within Storyboard Designer's Custom Events dialog. This allows you to more easily incorporate these invents into your Designer workflow and test using utilities like IO Connector.

    This is actually quite simple to do so let's take a look.

    When creating a new variable in the New Event dialog, at the bottom of the New Storyboard IO Data Element dialog there is an option called Array Size:


     
    Here I've set the size to 32, and as you can see I can then select the 8-bit Signed Integer - 1s32 as an option.
     
    Then if I wish to send this event in the IOConnector, I can right click the data type "1s32" and select "Text Box" to change the formatting:


     
    And I can do this for multiple strings and send them:

    1

Please sign in to leave a comment.

Didn't find what you were looking for?

New post