/**
* @copyright 2015 Tridium, Inc. All Rights Reserved.
* @author Gareth Johnson
*/
/**
* Defines {@link baja.Simple}.
*
* @module baja/obj/Simple
*/
define(["bajaScript/sys",
"bajaScript/baja/obj/Value"], function (
baja,
Value) {
'use strict';
var subclass = baja.subclass,
callSuper = baja.callSuper,
bajaHasType = baja.hasType;
/**
* Represents `baja:Simple` in BajaScript.
*
* `Simple`s are immutable and represent primitive data types in Niagara.
* They are the basic building blocks of the architecture. Simples contain
* no slots themselves but do contain an implicit data value that can be
* encoded and decoded in a `String` format.
*
* `Simple`s must be immutable and under no circumstances should there be
* any attempt to modify the contents of a Simple.
*
* All `Simple`s must conform to the following conventions...
*
* * Define a `DEFAULT` instance on the `Simple` constructor.
* * Define a `make` method.
* * Define a `decodeFromString` method on the Object's instance that takes a
* `String` and returns an instance of the `Simple`.
* * Define an `encodeToString` method on the Object's instance that encodes
* the value to a `String`.
*
* Since this Constructor represents an abstract class, it should never
* be directly used to create a new object.
*
* @class
* @alias baja.Simple
* @extends baja.Value
*/
var Simple = function Simple() {
callSuper(Simple, this, arguments);
};
subclass(Simple, Value);
/**
* Equality test.
*
* @param obj
* @returns {Boolean}
*/
Simple.prototype.equals = function (obj) {
// Comparing in via encodeToString is ok because most Simples
// lazily cache their string encoding (since they're all immutable)
return bajaHasType(obj) &&
obj.getType().equals(this.getType()) &&
obj.encodeToString() === this.encodeToString();
};
/**
* Returns the String representation of this object.
*
* @see baja.Object#toString
*
* @param {Object} [cx] optional context information to be used when
* formatting the string
*
* @returns {String|Promise.<String>} a string (if no context passed), or
* either a string or a Promise (if context passed).
*/
Simple.prototype.toString = function (cx) {
return this.encodeToString();
};
/**
* The string encoding of certain Simples may include Type information, or
* other data that may be require asynchronous operations to decode. BOX is
* designed to handle these situations when decoding data from the station,
* but when user code needs to decode string-encoded Simples directly, prefer
* this method as it gives the individual Simple a chance to import Types,
* etc. to ensure that the decoded Simple is fully correct.
*
* The default implementation just returns `decodeFromString` directly.
*
* @param {string} str
* @param {baja.comm.Batch} [batch] optional batch to use
* @returns {baja.Simple|Promise.<baja.Simple>} may return the Simple instance
* directly, or a Promise resolving to same - so wrap in `Promise.resolve()`
* if unsure.
*/
Simple.prototype.decodeAsync = function (str, batch) {
return this.decodeFromString(str);
};
/**
* @returns {String} the string encoding of the Simple, by default
*/
Simple.prototype.valueOf = function () {
return this.encodeToString();
};
/**
* Every Simple implementation must have an `encodeToString` function.
*
* @function
* @name baja.Simple#encodeToString
* @abstract
* @returns {string}
*/
/**
* Every Simple implementation must have a `decodeFromString` function.
*
* @function
* @name baja.Simple#decodeFromString
* @abstract
* @param {string} str
* @returns {baja.Simple}
*/
/**
* Every Simple implementation must have a `make` function. It can take
* any arbitrary arguments. When constructing the Simple with `baja.$`, any
* additional arguments will be passed to `make()`, with the following special
* cases:
*
* - When _no_ arguments are passed, `baja.$` will return the `DEFAULT`
* instance.
* - When _one_ argument is passed and it is a string, `baja.$` will use
* `decodeFromString()` to create the instance.
*
* @function
* @name baja.Simple#make
* @abstract
* @returns {baja.Simple}
* @example
* //in the Simple declaration:
* MySimple.prototype.make = function (a, b, c) {
* var mySimple = new MySimple();
* mySimple.a = a;
* mySimple.b = b;
* mySimple.c = c;
* return mySimple;
* };
*
* //when constructing:
* var mySimple = baja.$('myModule:MySimple', 'a', 'b', 'c');
*/
return Simple;
});