RpcPromise - Silverfeelin/Starbound-MessageHandling-Demo GitHub Wiki

The RpcPromise object keeps track of your request (message), and will update itself automagically.

The reason we work with promises in entity messages is that we can't expect a response immediately, especially when sending messages across the network to other clients (or the server).

When working with promises, it's important not to freeze up your code waiting for a response. You can accomplish this by checking your promise(s) once every update call, until a promise finishes.

Local messages

When a message is sent locally, the message will be handled immediately. Unlike remote messages, this means your code won't continue until the message handler finishes. The function promise:finished() will return true immediately.

This means that for local messaging (see localHandler) there's no need to poll the RpcPromise object.

Functions

• promise:finished()

Used to check whether the message handler has finished. If the entity or message handler isn't available, the promise will still finish.

Return Value

Returns a bool indicating whether the promise has finished.


• promise:succeeded()

Used to check whether the message was successfully sent and handled.

Return Value

Returns a bool indicating whether the promise has succeeded.

Reasons for the promise not succeeding may be:

  • The entity id or UUID could not be found.
  • The entity can not handle messages.
  • The entity does not handle the given message.
  • Whatever scenarios I couldn't think of.

• promise:result()

Used to obtain the result to a successful promise.

This value should only be accessed if promise:finished() and promise:succeeded() return true.

Return Value

Returns the result of the RpcPromise. This is the (serializable) data returned by the message handler.

The message handler can only return up to one value, but multiple values may be encapsulated in a Lua table.

Possible results: 5.25, nil, "hello", { foo = "bar" }


• promise:error()

Used to obtain the error message for an unsuccessful promise.

This value should only be accessed if promise:finished() returns true and promise:succeeded() returns false.

Return Value

Returns the error message.

Known error messages:

  • "Message not handled by entity"
  • "Unknown entity"

Example

-- Send message and store RpcPromise
myTable.mathPromise = world.sendEntityMessage(entity.id(), "multiply", 10, 20)

-- In update: check for result
local promise = myTable.mathPromise
if promise and promise:finished() then
  -- Now that we know the promise finished, we can see whether it succeeded or not.
  if promise:succeeded() then
    -- On success, use promise:result()
    local result = promise:result()
    sb.logInfo("Received response. No more homework for me!\nResponse: %s", result)
  else
    -- On error, use promise:error()
    local err = promise:error()
    sb.logInfo("Didn't receive a response. Guess I'll have to use my own brain.\nError: %s", err)
  end

  -- To prevent handling the result multiple times, we stop tracking the promise.
  myTable.mathPromise = nil
end