The bp Object

The bp object is a gateway to the Behavioral Programming infrastructure underlying the model. Among other things, it contains methods for creating events and event sets, a central data store, and a logger.

Methods

Event(name, [data])

Create an event with a name and a possible data object.

name

Name of event. String.

data

Additional event data. Optional object.

EventSet(name, predicate)

Create an event set: basically a named predicate that accepts events and returns true if and only if the passed event is a member of the set.

name

Optional String. Name of the event set.

predicate

The set membership predicate. Function that takes one parameter (event) and returns a boolean: true for events that are members of the event set, and false otherwise.

bp.fork()

Splits the calling bthread to two identical bthreads. On the "parent" bthread, fork returns 0. On the child bthread, it returns 1. Similar to fork in, e.g., C, except that the construct being forked is a bthread, not an operating system process.

Properties

bp.log

Provides access to a logger. The logger has 4 log levels: Fine, Info, Warn, Off.

bp.log.warn( formatString, objects…​)

Prints a message to the log at the Warn level.

bp.log.info( formatString, objects…​)

Prints a message to the log at the Info level.

bp.log.fine( formatString, objects…​)

Prints a message to the log at the Fine level.

bp.log.setLevel( levelName );

Sets the level of the log.

levelName

String. One of: "Fine", "Info", "Warn", "Off".

Message Formatting

The BPjs logger formats messages using Java’s MessageFormat. Under the hood, JavaScript objects are printed using a special formatter, which gives more information that the default cryptic [object object]. The code below contains some formatting examples:

const obj = {hello: "World", idioms:["request","waitFor","block"]};
const stuff = new Set();
stuff.add("thing 1");
stuff.add("thing 2");
stuff.add("thing 42");

bp.log.info("Here is field hello: {0} of object {1}", obj.hello, obj);
// prints:
//   [BP][Info] Here is field hello: World of object {JS_Obj hello:"World", idioms:[JS_Array 0:"request" | 1:"waitFor" | 2:"block"]}
bp.log.info("Here is are some {1}: {0}", stuff, "stuff");
// prints:
//   [BP][Info] Here is are some stuff: {JS_Set "thing 1", "thing 2", "thing 42"}
bp.log.info("I have a {0,number} reasons to block this event.", 1000000);
// prints: [BP][Info] I have a 1,000,000 reasons to block this event.
bp.log.info("{0} {0,number,#.##} {0,number,#.####}", 3.14159);
// prints: [BP][Info] 3.142 3.14 3.1416
Array Ambiguity

When using message formatting and passing a single array variable, the system auto-spreads the array, and only the first item of the array is printed. So the following code behaves somewhat unexpectedly:

bp.registerBThread("t1",function(){
    bp.log.info("array:{0}", ["x","y","z"]);
});
// prints: [BP][Info] array:x

To work around this, either include a dummy variable, or wrap the array in another array:

bp.log.info("array:{0}", [["x","y","z"]]);
bp.log.info("array:{0}", ["x","y","z"], "dummy val");

bp.store

The bp.store object is a key-value map. Keys are always strings, while values can be of any type. bp.store can be used for transferring data between bthreads, especially in cases where one bthread needs to record information that will be used by later bthreads, possibly after the recoding bthread terminated.

Modifications to the bp.store are transactional: They are initially visible only to the bthread that made them, and become visible to the rest of the bthreads at the next synchronization point.
Since bp.store is transactional, a model may try to perform conflicting changes to it during synchronization. For example, one bthread might call bp.put("puppyName","Toy"), while another bthread has called bp.store("puppyName","Sky"). Such conflicting changes terminate the specification with an informative message; normally, this type of error signifies conflicts in the requirements, specifications, or user stories.

bp.store.get(key)

Returns the value associated with key, or null if no such value exists.

bp.store.has(key)

Returns true if the store has a value associated with key, and false otherwise.

bp.store.keys()

Returns the keys currently in the store, as a Set of Strings.

bp.store.put(key, value)

Puts value in the store, and associates it with key.

bp.store.remove(key)

Removes the value associated with key, and the key itself. This is the opposite of bp.store.put(key, value).

bp.store.reset()

Resets the changes done by the calling bthread since the last synchronization.

bp.store.size()

Returns the how many values are currently stored in the in the store.

bp.store.values()

Returns a collection of all values currently in store.