next up previous
Next: Querying and updating populations Up: The Neosim interface [ Previous: An entity can construct

Interacting with entities - the query/response technique

 Entities can be physically distributed on different computers, and their simulation times may also be staggered. Because of this, it is not possible for an entity to directly access the internal state of another entity; instead entities refer to other entities using an opaque EntityID (an integer which uniquely identifies another entity for the course of a simulation). Entities can interact with other entities by sending timestamped events containing data and possibly methods.

Low level event based programming can become complex, so support is built in for the common operations, such as updating and querying the state of other entities. This comes in the form of two interfaces; the EntityUpdate and the EntityQuery interface. These let the user provide methods update() and query() which are called by the remote entity when the event arrives, and have access to the entity internals.

    interface EntityUpdate { void  update( Entity e ); }
    interface EntityQuery  { Object query( Entity e ); }

The simplest way to interact with entities uses the ScriptReader interface, e.g.:

    EntityID e = lookupEntity("layer1/granule123");
    class GetPos implements EntityQuery { 
      Object query(Entity e) { return e.getPos(); } 
    Object pos = queryEntity( e, GetPos );

The queryEntity() call blocks until the results return. The underlying implementation works as follows: The script reader despatches an event containing the GetPos object to the entity being queried. This event is handled by the entity's default event handler, which sends a response event back to the script reader. This response event wakes up the script reader thread, returning the result of the query to the queryEntity call.

Updates can also be performed with a similar interface:

    class SetPos extends EntityUpdate { 
      SetPos(Pos p) {this.p=p;}
      void update(Entity e) { e.setPos(p); } 
    updateEntity( e, new SetPos( new Pos(1,2,3) ) );

The event handler of an entity is not permitted to block, so if an entity needs to query another entity it has to specify a callback:

    interface Callback { void callback( Entity e, Object o ); }

The result of the query is passed in the Object o argument for the callback() function, which has access to the internals of the entity. An example which queries another entity's position and prints it is:

    class PrintIt implements Callback { 
       void callback( Entity e, Object o ) {
          System.out.println( e.getName() +" got back "+(Pos)o);
    e = // handle of entity to query 
    t = // >= local time + min output delay
    queryEntity( t, e, GetPos, PrintIt ) );

next up previous
Next: Querying and updating populations Up: The Neosim interface [ Previous: An entity can construct
Fred Howell