Promise Keeper - Silverfeelin/Starbound-MessageHandling-Demo GitHub Wiki

The PromiseKeeper class can be used to keep track of RpcPromise objects.

Whenever a message is sent using world.sendEntityMessage, it will take a while before the message handler responds with a value. The RpcPromise returned by this function allows us to keep track of this response.

The goal of the PromiseKeeper is to hide the busy work of checking promises, so you can focus on handling the results.

The promise keeper class can be found in the messageutil script. To access it, simply require the script in your code.

require "/scripts/messageutil.lua"

Functions

• PromiseKeeper.new()

Description

Creates and returns a new PromiseKeeper. You'll generally only need one.

By requiring the messageutil script, a global PromiseKeeper named promises is made for you. This means for most use cases you won't need to create a new PromiseKeeper.

All functions from now on should be called on this object, by using : instead of ..
See Programming in Lua : 16 - Object-Oriented Programming if you don't know what this does.

Return value

Empty PromiseKeeper object.


• PromiseKeeper:update()

Description

Updates the promise keeper, handling any finished promises. The promise keeper will automatically clean up finished promises and call the onSuccess or onError callback (see PromiseKeeper:add).

You'll generally want to update the promise keeper inside your update function.


• PromiseKeeper:add(promise, onSuccess, onError)

Description

Adds a new RpcPromise to keep track of. The onSuccess and onError will fire after the promise has finished, based on the promise result.

Arguments
  • promise

Unfinished RpcPromise to start tracking. This is the value returned by world.sendEntityMessage (see Sending Messages).

  • onSuccess

Function to call when the promise has finished and succeeded. The results of the message handler are passed to the onSuccess function (if any) (see [Message Handler]]).

  • onError

Function to call when the promise has finished due to an error. The error message is passed to the onError function.


• PromiseKeeper:empty()

Description

Checks if the PromiseKeeper is holding any unfinished RpcPromise.

Return value

True if the PromiseKeeper has no pending RpcPromise objects, false otherwise. If there are unhandled but finished promises (usually a result of not calling promiseKeeper:update() in a timely manner), this will still return false.


Example

require "/scripts/messageutil.lua"

local promiseKeeper = promises -- We use the promise keeper created by requiring messageutil.

-- Update the promise keeper periodically.
function update()
  -- This check for emptiness isn't necessary, and is only here to show that it works.
  if not promiseKeeper:empty() then
    promiseKeeper:update()
  end
end

-- Under some condition (not init), send the messages and wait for the answer.
function sendMessages()
  askMultiply(3, 3)
  askMultiply(5, 10)
  askMultiply(5, 20)
end

-- Send a message to multiply a with b.
function askMultiply(a, b)
  -- By defining the functions inline, we can match the numbers known in this function together with the answer.
  -- If we set onMultiply and onMultiplyFailed as the callbacks, we could only see the answer or error message.
  promiseKeeper:add(
    world.sendEntityMessage(entity.id(), "multiply", a, b), -- promise
    function(answer) -- onSuccess
      onMultiply(a, b, answer)
    end,
    function(err) -- onError
      onMultiplyFailed(a, b, err)
    end
  )
end

-- Log answer
function onMultiply(a, b, answer)
  sb.logInfo("%s * %s = %s", a, b, answer)
end

-- Log error message
function onMultiplyFailed(a, b, err)
  sb.logWarn("Multiplying %s by %s failed: %s", a, b, err)
end
⚠️ **GitHub.com Fallback** ⚠️