Events with Data

All events in BPjs have a name. A name alone can get you quite far, but sometimes a programmer wants to send data in a more structured way, and without to- and from- string roundtrips. For this reason, events also contain a data field, which holds a standard Javascript object. The event’s name is available through its name field. Client code can initialize an event with data like so:

var anEvent = bp.Event("answer", {value:42, scope:"everything"});
bp.log.info(anEvent.name); // logs "answer"
bp.log.info(anEvent.data.value); // logs 42
bp.log.info(anEvent.data.scope); // logs "everything"

Adding data to events allows for a more complex interaction between b-threads. The b-threads in the example (source) below collaborate in order run to count to 10.

The first b-thread requests three events: two with no data, and one with a counter type and a 0 value. Note that the use of type here is convention only; there’s no static type system in place to enforce type correctness.

1
2
3
4
5
bp.registerBThread("starter", function(){
  bp.sync({request:bp.Event("Just an Event")});
  bp.sync({request:bp.Event("withData", {type:"counter",value:0})});
  bp.sync({request:bp.Event("Just an Event")});
});

The next b-thread is responsible for increasing the counter. Note the event set in charge of detecting counter events. Code accessing the data field of an event must use caution, as that field is often null.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
bp.registerBThread("Increaser", function(){
  var counterEvents = bp.EventSet("counters", function(evt) {
    return (evt.data==null) ?
              false :
              evt.data.type && evt.data.type=="counter";
  });
  var counterEvt = bp.sync({waitFor:counterEvents});
  while (true) {
    bp.log.info( counterEvt.name + ": " + counterEvt.data.value );
    var next = bp.Event(counterEvt.name, {type:counterEvt.data.type,
                                         value:counterEvt.data.value+1});
    counterEvt = bp.sync({request:next});
  }
});

Finally, a third b-thread prevents the counter from reaching 10. Apart from the event set detecting counter events with value of 10, the body of the “Capper” b-thread consists of a single bp.sync which blocks these events. This is a common idiom in BP, in order to prevent something that “should never happen”.

1
2
3
4
5
6
7
8
bp.registerBThread("Capper", function() {
  var countersAt10 = bp.EventSet("done", function(evt) {
    return (evt.data==null) ?
            false :
            evt.data.type=="counter" && evt.data.value==10;
  });
  bp.sync({block:countersAt10});
});