JSoarOutput - soartech/jsoar GitHub Wiki

See also JSoarEvents, JSoarOutput

Introduction

JSoar has convenience classes that allow users to listen for specific types of WMEs that appear on the output link.

General API

The output link can be read via the general WME api.

  • Register for OutputEvent (see also JSoarEvents)
  • When the event fires, get output commands from InputOutput.getPendingCommands() (or handle WME changes in OutputEvent directly)
  • Use Wmes.matcher() to extract data from the output command working memory structures.

Handling Output Commands with SoarBeans

JSoar has built-in support for automatically converting working memory to Java object, called SoarBeans. The basic idea is that you define a Java class, the bean, and then register an output command handler with SoarBeanOutputManager. When an output command is detected, the Soar working memory elements will be converted to an instance of your class and passed to a handler method you provide.

An example will make this clearer. Suppose you have a command called move-to-point which takes speed and location parameters:

^output-link
   ^move-to-point
      ^speed 2
      ^location
         ^x 45
         ^y 99

Processing this output command with Wmes.matcher() isn't too, bad, but is still tedious. With SoarBeans, we'll add a new class:

import java.awt.Point;

public class MoveToPoint
{
    public int speed;
    public Point location = new Point();
}

and then construct an output manager and register a handler:

final SoarBeanOutputManager manager = new SoarBeanOutputManager(agent.getEvents());
final SoarBeanOutputHandler<MoveToPoint> handler = new SoarBeanOutputHandler<MoveToPoint>() {

    @Override
    public void handleOutputCommand(SoarBeanOutputContext context, MoveToPoint bean)
    {
        // ... do something with bean.speed, bean.location.x, etc ...
        context.setStatus("complete");
    }};
manager.registerHandler("move-to-point", handler, MoveToPoint.class);

That's it. Some other random facts:

  • Beans can consist of primitive types, arrays, or other beans. Cycles and shared structure are supported.
  • A bean must have a public, no-arg constructor.
  • A bean property must either be public, or provide a setter method.
  • SoarBeans makes an effort to autoconvert, e.g. int to string, etc.
  • Simple name conversion is supported, e.g. my-name in Soar, becomes myName in Java.

Output Commands API

JSoar has built-in support for reading "command"-style WMEs that appear on the output link. This API is useful for quick one-off command registrations that don't warrant writing a full Java bean class, or for handling structural cases (such as circular references) not handled by the SoarBeans API.

For example, to register for the move-to-point command above, attach a new OutputCommandManager to an agent and register a new OutputCommandHandler that listens for the command:

OutputCommandManager outputManager = new OutputCommandManager(agent.getEvents());
OutputCommandHandler handler = new OutputCommandHandler()
{
    @Override
    public void onCommandRemoved(String commandName, Identifier commandId)
    {
        // Called when "move-to" commands are removed from the output link.
    }

    @Override
    public void onCommandAdded(String commandName, Identifier commandId)
    {
        // Called when "move-to" commands are added to the output link.
    }
};
outputManager.registerHandler("move-to", handler);