AttributePool: Add JSDoc comments
parent
c98b521539
commit
de3dfb5ce2
|
@ -23,19 +23,83 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/**
|
||||||
An AttributePool maintains a mapping from [key,value] Pairs called
|
* A `[key, value]` pair of strings describing a text attribute.
|
||||||
Attributes to Numbers (unsigened integers) and vice versa. These numbers are
|
*
|
||||||
used to reference Attributes in Changesets.
|
* @typedef {[string, string]} Attribute
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maps an attribute's identifier to the attribute.
|
||||||
|
*
|
||||||
|
* @typedef {Object.<number, Attribute>} NumToAttrib
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An intermediate representation of the contents of an attribute pool, suitable for serialization
|
||||||
|
* via `JSON.stringify` and transmission to another user.
|
||||||
|
*
|
||||||
|
* @typedef {Object} Jsonable
|
||||||
|
* @property {NumToAttrib} numToAttrib - The pool's attributes and their identifiers.
|
||||||
|
* @property {number} nextNum - The attribute ID to assign to the next new attribute.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents an attribute pool, which is a collection of attributes (pairs of key and value
|
||||||
|
* strings) along with their identifiers (non-negative integers).
|
||||||
|
*
|
||||||
|
* The attribute pool enables attribute interning: rather than including the key and value strings
|
||||||
|
* in changesets, changesets reference attributes by their identifiers.
|
||||||
|
*
|
||||||
|
* There is one attribute pool per pad, and it includes every current and historical attribute used
|
||||||
|
* in the pad.
|
||||||
|
*/
|
||||||
class AttributePool {
|
class AttributePool {
|
||||||
constructor() {
|
constructor() {
|
||||||
|
/**
|
||||||
|
* Maps an attribute identifier to the attribute's `[key, value]` string pair.
|
||||||
|
*
|
||||||
|
* TODO: Rename to `_numToAttrib` once all users have been migrated to call `getAttrib` instead
|
||||||
|
* of accessing this directly.
|
||||||
|
* @private
|
||||||
|
* TODO: Convert to an array.
|
||||||
|
* @type {NumToAttrib}
|
||||||
|
*/
|
||||||
this.numToAttrib = {}; // e.g. {0: ['foo','bar']}
|
this.numToAttrib = {}; // e.g. {0: ['foo','bar']}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maps the string representation of an attribute (`String([key, value])`) to its non-negative
|
||||||
|
* identifier.
|
||||||
|
*
|
||||||
|
* TODO: Rename to `_attribToNum` once all users have been migrated to use `putAttrib` instead
|
||||||
|
* of accessing this directly.
|
||||||
|
* @private
|
||||||
|
* TODO: Convert to a `Map` object.
|
||||||
|
* @type {Object.<string, number>}
|
||||||
|
*/
|
||||||
this.attribToNum = {}; // e.g. {'foo,bar': 0}
|
this.attribToNum = {}; // e.g. {'foo,bar': 0}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The attribute ID to assign to the next new attribute.
|
||||||
|
*
|
||||||
|
* TODO: This property will not be necessary once `numToAttrib` is converted to an array (just
|
||||||
|
* push onto the array).
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @type {number}
|
||||||
|
*/
|
||||||
this.nextNum = 0;
|
this.nextNum = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add an attribute to the attribute set, or query for an existing attribute identifier.
|
||||||
|
*
|
||||||
|
* @param {Attribute} attrib - The attribute's `[key, value]` pair of strings.
|
||||||
|
* @param {boolean} [dontAddIfAbsent=false] - If true, do not insert the attribute into the pool
|
||||||
|
* if the attribute does not already exist in the pool. This can be used to test for
|
||||||
|
* membership in the pool without mutating the pool.
|
||||||
|
* @returns {number} The attribute's identifier, or -1 if the attribute is not in the pool.
|
||||||
|
*/
|
||||||
putAttrib(attrib, dontAddIfAbsent = false) {
|
putAttrib(attrib, dontAddIfAbsent = false) {
|
||||||
const str = String(attrib);
|
const str = String(attrib);
|
||||||
if (str in this.attribToNum) {
|
if (str in this.attribToNum) {
|
||||||
|
@ -50,6 +114,11 @@ class AttributePool {
|
||||||
return num;
|
return num;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {number} num - The identifier of the attribute to fetch.
|
||||||
|
* @returns {Attribute} The attribute with the given identifier, or nullish if there is no such
|
||||||
|
* attribute.
|
||||||
|
*/
|
||||||
getAttrib(num) {
|
getAttrib(num) {
|
||||||
const pair = this.numToAttrib[num];
|
const pair = this.numToAttrib[num];
|
||||||
if (!pair) {
|
if (!pair) {
|
||||||
|
@ -58,18 +127,34 @@ class AttributePool {
|
||||||
return [pair[0], pair[1]]; // return a mutable copy
|
return [pair[0], pair[1]]; // return a mutable copy
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {number} num - The identifier of the attribute to fetch.
|
||||||
|
* @returns {string} Eqivalent to `getAttrib(num)[0]` if the attribute exists, otherwise the empty
|
||||||
|
* string.
|
||||||
|
*/
|
||||||
getAttribKey(num) {
|
getAttribKey(num) {
|
||||||
const pair = this.numToAttrib[num];
|
const pair = this.numToAttrib[num];
|
||||||
if (!pair) return '';
|
if (!pair) return '';
|
||||||
return pair[0];
|
return pair[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {number} num - The identifier of the attribute to fetch.
|
||||||
|
* @returns {string} Eqivalent to `getAttrib(num)[1]` if the attribute exists, otherwise the empty
|
||||||
|
* string.
|
||||||
|
*/
|
||||||
getAttribValue(num) {
|
getAttribValue(num) {
|
||||||
const pair = this.numToAttrib[num];
|
const pair = this.numToAttrib[num];
|
||||||
if (!pair) return '';
|
if (!pair) return '';
|
||||||
return pair[1];
|
return pair[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Executes a callback for each attribute in the pool.
|
||||||
|
*
|
||||||
|
* @param {Function} func - Callback to call with two arguments: key and value. Its return value
|
||||||
|
* is ignored.
|
||||||
|
*/
|
||||||
eachAttrib(func) {
|
eachAttrib(func) {
|
||||||
for (const n of Object.keys(this.numToAttrib)) {
|
for (const n of Object.keys(this.numToAttrib)) {
|
||||||
const pair = this.numToAttrib[n];
|
const pair = this.numToAttrib[n];
|
||||||
|
@ -77,6 +162,10 @@ class AttributePool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns {Jsonable} An object that can be passed to `fromJsonable` to reconstruct this
|
||||||
|
* attribute pool. The returned object can be converted to JSON.
|
||||||
|
*/
|
||||||
toJsonable() {
|
toJsonable() {
|
||||||
return {
|
return {
|
||||||
numToAttrib: this.numToAttrib,
|
numToAttrib: this.numToAttrib,
|
||||||
|
@ -84,6 +173,12 @@ class AttributePool {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replace the contents of this attribute pool with values from a previous call to `toJsonable`.
|
||||||
|
*
|
||||||
|
* @param {Jsonable} obj - Object returned by `toJsonable` containing the attributes and their
|
||||||
|
* identifiers.
|
||||||
|
*/
|
||||||
fromJsonable(obj) {
|
fromJsonable(obj) {
|
||||||
this.numToAttrib = obj.numToAttrib;
|
this.numToAttrib = obj.numToAttrib;
|
||||||
this.nextNum = obj.nextNum;
|
this.nextNum = obj.nextNum;
|
||||||
|
|
Loading…
Reference in New Issue