Skip to content

Commit

Permalink
Moved the event selection strategy back into the bprogram
Browse files Browse the repository at this point in the history
  • Loading branch information
michbarsinai committed Jul 5, 2017
1 parent a1dd3a7 commit 52b8f57
Show file tree
Hide file tree
Showing 12 changed files with 74 additions and 34 deletions.
2 changes: 1 addition & 1 deletion docs/source/_static/css/custom.css
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ h3 {
}

.note {
background-color: rgba(128,255,128,.4);
background-color: #4ecb96;
}

.tip {
Expand Down
Binary file added docs/source/_static/css/custom.pdf
Binary file not shown.
29 changes: 21 additions & 8 deletions docs/source/embed-bpjs.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ The BP code (top layer) is the BPjs code, written in Javascript. It can interact
the BPjs runtime using the :doc:`BPjsTutorial/bp-object`. The host application can make
other Java objects available to the Javascript code, as will be explained later.

The BPjs layer serves as a runtime environment to the BProgram. The host application has
The BPjs layer serves as a runtime environment for the BProgram. The host application has
to instantiate a ``BProgram`` object, and pass it to a ``BProgramRunner``. The host application
can listen to events of the running b-program (such as start, end, b-thread added, and - of course - b-event selected).
Additionally, the host application can provide custom event selection strategy, in case
Expand All @@ -38,8 +38,8 @@ the default one it not good enough.
:align: center

Class diagram describing the strucutre of an embedded b-program. The client code
generates a BProgram and a BProgramRunner. The runner object consults its event
selection strategy when selecting events for the b-program it runs. A list of
generates a BProgram and a BProgramRunner. The runner object consults the b-program's
event selection strategy when selecting events for the b-program it runs. A list of
listener objects are informed whenever an event of interest, such as b-thread
addition or b-event selection, occures.
*Some methods and properties have been omitted for brevity.*
Expand All @@ -60,18 +60,26 @@ Steps for B-Program Embedding
Code setup
~~~~~~~~~~

* Add BPjs to your classpath. See :doc:`install-bpjs`.
* Decide which ``BProgram`` subclass you need. `BProgram`_ is an abstract class. Its concrete sub-classes differ on how they obtain their source code. `SingleResourceBProgram`_ reads the code from a resource included with the code (typlically, a .js file bundled in the project's .jars). `StringBProgram`_, on the other hand, takes a Java String as source. Of course, ``BProgram`` can be directly extended as needed.
* Write the BPjs code. The code will interact with the runtime using th ``bp`` object. Additional Java classes can be made available to it by using Rhino's `import directives`_, or by adding Java objects to the program's scope (see below).
Add BPjs to your classpath.

See :doc:`install-bpjs`.

Decide which ``BProgram`` subclass you need.

`BProgram`_ is an abstract class. Its concrete sub-classes differ on how they obtain their source code. `SingleResourceBProgram`_ reads the code from a resource included with the code (typlically, a .js file bundled in the project's .jars). `StringBProgram`_, on the other hand, takes a Java String as source. Of course, ``BProgram`` can be directly extended as needed.

Write the BPjs code.

The code will interact with the runtime using the ``bp`` object. Additional Java classes can be made available to it by using Rhino's `import directives`_, or by adding Java objects to the program's scope (see below).

At Runtime
~~~~~~~~~~

* Instantiate the proper ``BProgram`` sub-class, and supply it with the source BPjs code.
* If needed, set a new ``EventSelectionStrategy``. When no strategy is supplied, SimpleEventSelectionStrategy_ will by used. This strategy randomly selects an event from the set of events that are requested and not blocked.
* If needed, add Java objects to the global b-program scope using `putInGlobalScope`_.
* Instantiate a ``BProgramRunner`` object, and supply it with the ``BProgram`` instance.
* If needed, set a new EventSelectionStrategy
* Add listeners
* Add listeners to the runner.
* In the common case when the program needs to wait for external events (such as GUI interactions), set the ``isDaemon`` property of the ``BProgram`` to ``true``.
* Call ``BProgramRunner::start()``.

Expand All @@ -80,10 +88,15 @@ The BProgram will start running. Lifecycle and behavioral events will be passed
.. tip::
BPjs' source code contains many examples of embedded BPjs programs - most of the unit tests that involve a b-program. For a more complete example, refer to the `RunFile`_ class, which implements the command-line tool for running BPjs code.

.. tip::
SampleBPjsProject_ can serve as a template project for embedding BPjs in a Java application. You can fork it on GitHub and start building your application from there.

.. _import directives: https://developer.mozilla.org/en-US/docs/Mozilla/Projects/Rhino/Scripting_Java
.. _BProgram: http://static.javadoc.io/com.github.bthink-bgu/BPjs/0.8.4/il/ac/bgu/cs/bp/bpjs/bprogram/runtimeengine/BProgram.html
.. _SingleResourceBProgram: http://static.javadoc.io/com.github.bthink-bgu/BPjs/0.8.4/il/ac/bgu/cs/bp/bpjs/bprogram/runtimeengine/SingleResourceBProgram.html
.. _StringBProgram: http://static.javadoc.io/com.github.bthink-bgu/BPjs/0.8.4/il/ac/bgu/cs/bp/bpjs/bprogram/runtimeengine/StringBProgram.html
.. _putInGlobalScope: http://static.javadoc.io/com.github.bthink-bgu/BPjs/0.8.4/il/ac/bgu/cs/bp/bpjs/bprogram/runtimeengine/BProgram.html#putInGlobalScope-java.lang.String-java.lang.Object-
.. _enqueueExternalEvent: http://static.javadoc.io/com.github.bthink-bgu/BPjs/0.8.4/il/ac/bgu/cs/bp/bpjs/bprogram/runtimeengine/BProgram.html#enqueueExternalEvent-il.ac.bgu.cs.bp.bpjs.events.BEvent-
.. _RunFile: https://github.com/bThink-BGU/BPjs/blob/develop/src/main/java/il/ac/bgu/cs/bp/bpjs/mains/RunFile.java
.. _SimpleEventSelectionStrategy: http://static.javadoc.io/com.github.bthink-bgu/BPjs/0.8.4/il/ac/bgu/cs/bp/bpjs/eventselection/SimpleEventSelectionStrategy.html
.. _SampleBPjsProject: https://github.com/bThink-BGU/SampleBPjsProject
Binary file modified docs/source/images/bprogram-running.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion docs/source/images/bprogram-running.puml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ interface BProgramListener {

clientCode .right.> BProgramRunner : manages
BProgramRunner "1" *--> "1" BProgram
BProgramRunner "1" *--> "1" EventSelectionStrategy
BProgram "1" *--> "1" EventSelectionStrategy
BProgramRunner o--> "0..*" BProgramListener

@enduml
1 change: 0 additions & 1 deletion docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,4 @@ Indices and tables
==================

* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import il.ac.bgu.cs.bp.bpjs.bprogram.runtimeengine.jsproxy.BProgramJsProxy;
import il.ac.bgu.cs.bp.bpjs.events.BEvent;
import il.ac.bgu.cs.bp.bpjs.eventselection.EventSelectionStrategy;
import il.ac.bgu.cs.bp.bpjs.eventselection.SimpleEventSelectionStrategy;

import java.util.*;
import java.util.concurrent.*;
Expand Down Expand Up @@ -79,21 +81,41 @@ public interface BProgramCallback {

protected Scriptable programScope;

private EventSelectionStrategy eventSelectionStrategy;

/**
* Objects that client code wishes to put in scope before the scope is
* initialized are collected here.
*/
protected Map<String,Object> initialScopeValues = new HashMap<>();

private Optional<BProgramCallback> addBThreadCallback = Optional.empty();


/**
* Constructs a BProgram with a default name, guaranteed to be unique within
* a given run.
*/
public BProgram() {
this("BProgram-" + INSTANCE_COUNTER.incrementAndGet());
}

/**
* Constructs a BProgram with a specific name.
* @param aName name for the new BProgram.
*/
public BProgram(String aName) {
name = aName;
}

/**
* Creates a BProgram with a specific name and an event selection strategy.
* @param aName Name for the program.
* @param anEss Event selection strategy.
*/
public BProgram( String aName, EventSelectionStrategy anEss ) {
name = aName;
eventSelectionStrategy = anEss;
}

/**
* Loads a Javascript resource (a file that's included in the .jar).
Expand Down Expand Up @@ -198,6 +220,10 @@ public BProgramSyncSnapshot setup() {
}
Set<BThreadSyncSnapshot> bthreads = drainRecentlyRegisteredBthreads();

if ( eventSelectionStrategy==null ) {
eventSelectionStrategy = new SimpleEventSelectionStrategy();
}

try {
Context cx = ContextFactory.getGlobal().enterContext();
cx.setOptimizationLevel(-1); // must use interpreter mode
Expand All @@ -206,6 +232,7 @@ public BProgramSyncSnapshot setup() {
} finally {
Context.exit();
}

started = true;
return new BProgramSyncSnapshot(this, bthreads, Collections.emptyList());
}
Expand Down Expand Up @@ -358,6 +385,14 @@ List<BEvent> drainEnqueuedExternalEvents() {
public void setAddBThreadCallback(BProgramCallback anAddBThreadCallback) {
addBThreadCallback = Optional.ofNullable(anAddBThreadCallback);
}

public EventSelectionStrategy getEventSelectionStrategy() {
return eventSelectionStrategy;
}

public void setEventSelectionStrategy(EventSelectionStrategy eventSelectionStrategy) {
this.eventSelectionStrategy = eventSelectionStrategy;
}

@Override
public String toString() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
import il.ac.bgu.cs.bp.bpjs.events.BEvent;
import il.ac.bgu.cs.bp.bpjs.eventselection.EventSelectionResult;
import il.ac.bgu.cs.bp.bpjs.eventselection.EventSelectionStrategy;
import il.ac.bgu.cs.bp.bpjs.eventselection.SimpleEventSelectionStrategy;
import java.util.ArrayList;
import static java.util.Collections.reverseOrder;
import java.util.List;
Expand All @@ -43,19 +42,13 @@
public class BProgramRunner {

private BProgram bprog = null;
private EventSelectionStrategy eventSelectionStrategy;
private final List<BProgramListener> listeners = new ArrayList<>();

public BProgramRunner(){
this(null);
}
public BProgramRunner(BProgram aBProgram) {
this( aBProgram, new SimpleEventSelectionStrategy() );
}

public BProgramRunner(BProgram aBProgram, EventSelectionStrategy ess) {
bprog = aBProgram;
eventSelectionStrategy = ess;
if ( bprog!=null ) {
bprog.setAddBThreadCallback( (bp,bt)->listeners.forEach(l->l.bthreadAdded(bp, bt)));
}
Expand All @@ -81,7 +74,7 @@ public void start() throws InterruptedException {
}

// see which events are selectable
Set<BEvent> possibleEvents = eventSelectionStrategy.selectableEvents(cur.getStatements(), cur.getExternalEvents());
Set<BEvent> possibleEvents = bprog.getEventSelectionStrategy().selectableEvents(cur.getStatements(), cur.getExternalEvents());
if ( possibleEvents.isEmpty() ) {
// No events available or selection. Terminate or wait for external one (in daemon mode).
if ( bprog.isDaemonMode() ) {
Expand All @@ -101,7 +94,7 @@ public void start() throws InterruptedException {

} else {
// we can select some events - select one and advance.
Optional<EventSelectionResult> res = eventSelectionStrategy.select(cur.getStatements(), cur.getExternalEvents(), possibleEvents);
Optional<EventSelectionResult> res = bprog.getEventSelectionStrategy().select(cur.getStatements(), cur.getExternalEvents(), possibleEvents);

if ( res.isPresent() ) {
EventSelectionResult esr = res.get();
Expand Down Expand Up @@ -156,12 +149,4 @@ public void removeListener(BProgramListener aListener) {
listeners.remove(aListener);
}

public EventSelectionStrategy getEventSelectionStrategy() {
return eventSelectionStrategy;
}

public void setEventSelectionStrategy(EventSelectionStrategy eventSelectionStrategy) {
this.eventSelectionStrategy = eventSelectionStrategy;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
*/
package il.ac.bgu.cs.bp.bpjs.bprogram.runtimeengine;

import il.ac.bgu.cs.bp.bpjs.eventselection.EventSelectionStrategy;
import java.net.URL;
import org.mozilla.javascript.Scriptable;

Expand All @@ -28,6 +29,11 @@ public SingleResourceBProgram(String aResourceName, String aName) {
super(aName);
resourceName = aResourceName;
}

public SingleResourceBProgram(String aResourceName, String aName, EventSelectionStrategy ess) {
super(aName, ess);
resourceName = aResourceName;
}

@Override
protected void setupProgramScope(Scriptable scope) {
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/il/ac/bgu/cs/bp/bpjs/mains/RunFile.java
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,9 @@ private void logScriptExceptionAndQuit(EvaluatorException ee, String arg) {
SimpleEventSelectionStrategy sess = new SimpleEventSelectionStrategy();
EventSelectionStrategy ess = switchPresent("-v", args) ? new LoggingEventSelectionStrategyDecorator(sess) : sess;

System.out.println(ess);
bpp.setEventSelectionStrategy(ess);

BProgramRunner bpr = new BProgramRunner(bpp, ess);
BProgramRunner bpr = new BProgramRunner(bpp);
if ( ! switchPresent("-v", args) ) {
bpr.addListener(new StreamLoggerListener());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ public class LoggingEventSelectionStrategyDecoratorTest {
public void superStepTest() throws InterruptedException {
StringWriter strOut = new StringWriter();
LoggingEventSelectionStrategyDecorator sut = new LoggingEventSelectionStrategyDecorator(new SimpleEventSelectionStrategy(), new PrintWriter(strOut));
BProgramRunner runner = new BProgramRunner(new SingleResourceBProgram("HotNCold.js"), sut);
SingleResourceBProgram bp = new SingleResourceBProgram("HotNCold.js");
bp.setEventSelectionStrategy(sut);
BProgramRunner runner = new BProgramRunner(bp);
runner.addListener( new StreamLoggerListener() );
InMemoryEventLoggingListener eventLogger = runner.addListener( new InMemoryEventLoggingListener() );

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ public class EventsWithDataTest {

@Test
public void testEventsWithData() throws Exception {
BProgram bpr = new SingleResourceBProgram( "EventsWithData.js", "programName" );
BProgramRunner rnr = new BProgramRunner(bpr, new SimpleEventSelectionStrategy(99l));
BProgram bpr = new SingleResourceBProgram( "EventsWithData.js", "programName", new SimpleEventSelectionStrategy(99l) );
BProgramRunner rnr = new BProgramRunner(bpr);
rnr.addListener( new StreamLoggerListener() );
InMemoryEventLoggingListener events = rnr.addListener( new InMemoryEventLoggingListener() );

Expand Down

0 comments on commit 52b8f57

Please sign in to comment.