Labs/Bespin/DesignDocs/Components

From MozillaWiki
< Labs‎ | Bespin‎ | DesignDocs
Jump to navigation Jump to search

Function Calling

Current Semi-Indirect Functions

The most common way to call functions in the code at the moment, although there is confusion as to whether we should be doing this or pubsub. The semi-indirect in the title comes from the bespin.get abstraction.

Example

/* Define */
x.y = function(p1, p2) {
    // use p1, p2
    return v3;
};

/* Use */
reply = bespin.get("x").y(v1, v2);
// use reply

Advantages

  • Simple
  • Fits well with a ‘do y’ scenario, but less well with a ‘y happened’ scenario, although the distinction is blurred in places: e.g. a user request to ‘‘do y’ happened’.

Disadvantages

  • Poor abstraction
  • Do we really get any benefit from the get() redirection?)
  • It’s 1-to-1 unless we get into dojo.connect and then it’s still 1-to-{1,n}, i.e. 0 ‘listeners’ is an error
  • Is there any benefit over bespin.x.y(v1, v2)?

Current Pub/Sub

Also frequently used, although the trend is perhaps towards calling directly as above due to the disadvantages

Example

/* Define */
bespin.subscribe("x.y", function(e) {
    // use e.p1, e.p2 etc
};

/* Use */
bespin.publish("x.y", { p1:v1, p2:v2 });
// No reply

Advantages

  • Fits well with a ‘y happened’ scenario, but less well with a ‘do y’ scenario, although the distinction is blurred in places: e.g. a user request to ‘‘do y’ happened’.
  • Excellent abstraction
  • 1-to-n
  • The potential that we can use it over the net in place of a REST api (although we need to decide if this is a good idea first of all!)

Disadvantages

  • Handling return values is a huge pain - it requires a return publish and lots of messing
  • Errors are currently silent (perhaps there could be a debug option to prevent this?)
  • Does ordering of multiple publishes matter?

Pub/Sub with Maltese Extension

As above, with the addition of a callback element.

Example

/* Define */
bespin.subscribe("x.y", function(e) {
    // use e.p1, e.p2 etc
    e.callback(v3);
};

/* Use */
bespin.publish("x.y", { p1:v1, callback:function(reply) {
    // use reply - but how many times?
} });

Advantages

  • All the advantages of current pub/sub

Disadvantages

  • Errors are currently silent
  • Does ordering of multiple publishes matter?

Commands

Many events or functions are replicated as commands. We probably couldn’t replace pub/sub or functions entirely with commands because they don’t nest easily and have no return value, however a command interface is required, so it would be good to have it as easy as possible.

Example

/* Define */
bespin.cmd.commands.add({
    name: 'y',
    takes: ['p1', 'p2'],
    execute: function(commandLine, p1, p2) {
        // use p1, p2
    }
});

/* Use */
commandLine.execute('y v1 v2');
// No reply

Advantages

  • Meta-data for console built in

Disadvantages

  • No return value
  • Not sure how commands would nest
  • No current way to hide textual output

Extension Points

Eclipse uses extension points to provide extra functionality. The example below takes Kevin’s example from the mailing list and simplifies it with map() and an inline implementation, and also adds a second even more sugary version

Example

/* Define */
{
    provides: [
        name: "x.y",
        impl: function(p1, p2) {
            // use p1, p2
            return v3;
        }
    ]
}

/* Use */
var impls = bespin.extensions.get("x.y");
replies = impls.map(function(impl) {
    return impl(v1, v2);
});
// use replies

/* Use v2 */
var replies = bespin.call("x.y", v1, v2);
// use replies

Advantages

  • Meta-data for command is available. Extension points can be seen as taking the good bits from commands and pub/sub

Disadvantages

  • More verbose, although that’s perhaps a side effect of metadata?

Singleton Usage

We should change from using bespin as a global singleton, to bespin as a local to refer to the current environment so it’s possible to have more than one bespin on a page. The initial implication is rather nasty, that we would be passing the environment around everywhere.

Maybe there is a solution to simplify this:

  • A smart dojo.define - could it pick up bespin from the current scope??
  • ‘with’ - ug
  • pub/sub that adds ‘bespin’ to each event object