Modules /
MutableWhat 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:
ChallengeThe 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:
ImplementationMutableAccessors 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 RevisionInterface definition: The Accessor’s interface definition has been extended to contain more information about:
For this, the exports.setup() function can invoke, in addition to
Accessor.prototype.mutable = function (value)
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 checkThe 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:
For an inclusion to hold, the following conditions are checked:
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 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. ReifyIf 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 reificationRemoving 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) InstantiationUsing the new interface definition and ExampleThis 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 ( The mutableAccessor ma can be reified by the accessor a1 The above is the result of the reification test of 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 Successfully removed previous reification. Go for substitution... The mutableAccessor ma can be reified by the accessor a2 After reifying by 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 { 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 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$ |