Recent Changes - Search:

edit SideBar

Mutable

What is a Mutable Accessor?

A mutableAccessor can change its behavior, while preserving the same interface declaration. It has the ability to dynamically change its behavior by substituting a reified accessor X by another reified accessor Y. Behavior change allow for dynamic substitution. Therefore, during its lifetime, a mutableAccessor can be equivalent to one of the following:

  • an interface definition
  • an accessor X (such that X is a reification of Mutable Accessor (MA))
  • another accessor Y (such that Y is a reification of MA)
  • ...

Challenge

The mutableAccessor is a way to answer the question: Using accessors, can I turn the light on, whatever the available bulb is (Philips Hue, Lifx…)?

Therefore, the mutableAccessor should provide mechanisms for:

  • describing the functionality,
  • declaring a union of all possible inputs,
  • and declaring an intersection of all possible outputs.

Implementation

MutableAccessors are implemented as a particular type of composite accessors. When instantiated, it is equivalent to an interface definition (but with a bunch of additional/configuration options). Every accessor passing the reification test is stored in an array within the mutableAccessor. When reifying an accessor X, the mutableAccessor will connect to X, making it equivalent to X itself. This is enabled by the composition mechanism that is performed on runtime.

Accessor specification Revision

Interface definition: The Accessor’s interface definition has been extended to contain more information about:

  • if the accessor is mutable or not
  • and the realized features.

For this, the exports.setup() function can invoke, in addition to input, output, parameter, implement and extend, the following functions:

  • mutable: if the passed parameter is 'true', then the accessor is a mutable one.
Accessor.prototype.mutable = function (value)
  • realize: it specifies the realized functions.
Accessor.prototype.realize = function (name, options)

The last information is particularly useful in the case of mutableAccessors. It enables a kind of functionality compatibility check with the possible reifying accessors.

Reification check

The prototype function reifiableBy() evaluates if the mutableAccessor is reifiable by the accessor given as parameter. This means also that mutableAccessor’s interface is a type refinement of the accessor’s interface.

Accessor.prototype.reifiableBy = function (accessor, options, strict)

Where the parameters in commonHost.js are declared as follows:

 *  @param accessor An instantiated Accessor object                                                                      
 *  @param options An optional parameter that describes additional information about the                                  
 *   accessor, such as its location, IPAddress, ...                                                                      
 *   FIXME: options is to be detailed!!!                                                                                  
 *  @param strict An optional parameter that selects if the accessor parameters can be                                    
 *   mapped to available mutableAccessor inputs.

Recall that mutableAccessors and accessors each define a set of functionality that they realize. This functionality is typically a concept like light, camera or gain. The realizes are stored in a realizesList array or realizes object). (FIXME: somewhere we should discuss why there are two storage methods)

First of all, the mutableAccessor realizes (contents of realizesList array and realizes object) should be checked against the realizes of the accessor. Note: For the moment, this test is reduced to an equality check. It must be improved later with ontologies support.

Then, the interface type refinement checking is performed. Reification conditions are the following:

  • the set of inputs of the accessor are included in the set of inputs of the mutableAccessor
  • and the set of outputs of the mutableAccessor are included in the set of outputs of the accessor.

For an inclusion to hold, the following conditions are checked:

  • Same port name
  • If the ports contain an attribute called 'type', then they need to be checked for equality.

Note: Aligned with realize, these conditions must be improved as well by the support of ontology.

An alternative for dealing with the accessor parameters is to consider them, from the mutableAccessor view, as inputs. If the value of strict parameter is true, then the reifiableBy() function looks for mapping the non-mapped mutableAcessor inputs to the accessor parameters.

If all previous conditions are met, the accessor can be used to reify the mutableAccessor. All reifying candidates are stores in an array reifyingAccessorsList, with their respective mapping objects and options. The mapping objects: inputsMap, outputsMap and parametersMap, store the connections configuration between the mutableAccessor and the accessor.

Reify

If the accessor reifies the mutableAccessor, then the inputs and outputs Map objects are used to establish the connections between both objects. This function calls the connect() function.

Accessor.prototype.reify = function (accessor)

Removing reification

Removing reification of the mutableAccessor consists in disconnecting both objects.

Accessor.prototype.removeReification = function ()

disconnect() function has the opposite effect of connect() function prototype.

Accessor.prototype.disconnect = function (a, b, c, d)

Instantiation

Using the new interface definition and mutable function, it is possible to instantiate a mutatbleAccessor by calling instantiate. This removes the previous restriction of instantiating mutableAccessors only on Node host.

Example

This example instantiates a mutableAccessor that has two possible gain implementations. One provides only one output (the gain), the other provides two outputs, the gain and the negative gain:

bash-3.2$ cd accessors/web/mutable/demo/simpleMutable
bash-3.2$ node simpleMutable.js
Instantiated accessor ma with class ./mutable/MutableTestGain.js
Instantiated accessor a1 with class ./mutable/TestGain1.js
Instantiated accessor a2 with class ./mutable/TestGain2.js

In the above, we use node to run the example, which create the mutuableAccessor (ma) and the two different implementations (a1 and a2). a1 gain parameter is set to 2 and a2 gain parameter is set to 4.

The mutableAccessor ma can be reified by the accessor a1

The above is the result of the reification test of a1. After proceeding with reification, the mutableAccessor reacts twice to two different inputs (1 and 6), as shown below.

TestGain: inputHandler: input: 1 gain: 2
Latest output of ma reified by a1: 2
TestGain: inputHandler: input: 6 gain: 2
Latest output of ma reified by a1: 12

For whatever reason, it is possible to remove the reification by the accessor a1, and decide to go for another one. The first line below shows the result of calling removeReification() function on ma. The line after illustrates the result of the reification test of a2.

Successfully removed previous reification. Go for substitution...
The mutableAccessor ma can be reified by the accessor a2

After reifying by a2, ma reacts twice to different inputs. Below is the first reaction. Note that the reifying accessor a2 prints its both outputs (scaled and opScaled).

TestGain2: inputHandler: input: 6 gain: 4
TestGain2: scaled: 24 opScaled: -24
Latest output of ma reified by a2: 24

We show below the monitoring information of all accessors. At this point, notice that a1 is considered as a composite accessor while a1 is topLevel.

{ ma:
   { type: 'mutable',
     monitoringInformation:
      { initialize: [Object],
        react: [Object],
        wrapup: [Object],
        reify: [Object] } },
  a1:
   { type: 'topLevel',
     monitoringInformation: { initialize: [Object], react: [Object], wrapup: [Object] } },
  a2:
   { type: 'composite',
     monitoringInformation: { initialize: [Object], react: [Object], wrapup: [Object] } } }

After a second react call on ma (first 3 lines below) and removing the reification, we show again the monitoring information. Now both accessors a1 and a2 are seen as topLevel. Therefore, at the end, wrapup is invoked on all 3 accessors separately.

TestGain2: inputHandler: input: 11 gain: 4
TestGain2: scaled: 44 opScaled: -44
Latest output of ma reified by a2: 44
{ ma:
   { type: 'mutable',
     monitoringInformation:
      { initialize: [Object],
        react: [Object],
        wrapup: [Object],
        reify: [Object] } },
  a1:
   { type: 'topLevel',
     monitoringInformation: { initialize: [Object], react: [Object], wrapup: [Object] } },
  a2:
   { type: 'topLevel',
     monitoringInformation: { initialize: [Object], react: [Object], wrapup: [Object] } } }
That's all folks!
commonHost.js: invoking wrapup() for accessor: ma
commonHost.js: invoking wrapup() for accessor: a1
commonHost.js: invoking wrapup() for accessor: a2
bash-3.2$
Edit - History - Print - Recent Changes - Search
Page last modified on December 14, 2020, at 06:07 PM