heli-agri
Version:
HeliAgri is a high-performance, feature-packed library for creating interactive maps on the web. It can display map tiles, vector data and markers loaded from any source on any web page. OpenLayers has been developed to further the use of geographic infor
260 lines (236 loc) • 5.46 kB
JavaScript
/**
* @module ol/structs/LinkedList
*/
/**
* @typedef {Object} Item
* @property {Item} [prev] Previous.
* @property {Item} [next] Next.
* @property {?} data Data.
*/
/**
* @classdesc
* Creates an empty linked list structure.
*/
class LinkedList {
/**
* @param {boolean} [circular] The last item is connected to the first one,
* and the first item to the last one. Default is true.
*/
constructor(circular) {
/**
* @private
* @type {Item|undefined}
*/
this.first_;
/**
* @private
* @type {Item|undefined}
*/
this.last_;
/**
* @private
* @type {Item|undefined}
*/
this.head_;
/**
* @private
* @type {boolean}
*/
this.circular_ = circular === undefined ? true : circular;
/**
* @private
* @type {number}
*/
this.length_ = 0;
}
/**
* Inserts an item into the linked list right after the current one.
*
* @param {?} data Item data.
*/
insertItem(data) {
/** @type {Item} */
const item = {
prev: undefined,
next: undefined,
data: data,
};
const head = this.head_;
//Initialize the list.
if (!head) {
this.first_ = item;
this.last_ = item;
if (this.circular_) {
item.next = item;
item.prev = item;
}
} else {
//Link the new item to the adjacent ones.
const next = head.next;
item.prev = head;
item.next = next;
head.next = item;
if (next) {
next.prev = item;
}
if (head === this.last_) {
this.last_ = item;
}
}
this.head_ = item;
this.length_++;
}
/**
* Removes the current item from the list. Sets the cursor to the next item,
* if possible.
*/
removeItem() {
const head = this.head_;
if (head) {
const next = head.next;
const prev = head.prev;
if (next) {
next.prev = prev;
}
if (prev) {
prev.next = next;
}
this.head_ = next || prev;
if (this.first_ === this.last_) {
this.head_ = undefined;
this.first_ = undefined;
this.last_ = undefined;
} else if (this.first_ === head) {
this.first_ = this.head_;
} else if (this.last_ === head) {
this.last_ = prev ? this.head_.prev : this.head_;
}
this.length_--;
}
}
/**
* Sets the cursor to the first item, and returns the associated data.
*
* @return {?} Item data.
*/
firstItem() {
this.head_ = this.first_;
if (this.head_) {
return this.head_.data;
}
return undefined;
}
/**
* Sets the cursor to the last item, and returns the associated data.
*
* @return {?} Item data.
*/
lastItem() {
this.head_ = this.last_;
if (this.head_) {
return this.head_.data;
}
return undefined;
}
/**
* Sets the cursor to the next item, and returns the associated data.
*
* @return {?} Item data.
*/
nextItem() {
if (this.head_ && this.head_.next) {
this.head_ = this.head_.next;
return this.head_.data;
}
return undefined;
}
/**
* Returns the next item's data without moving the cursor.
*
* @return {?} Item data.
*/
getNextItem() {
if (this.head_ && this.head_.next) {
return this.head_.next.data;
}
return undefined;
}
/**
* Sets the cursor to the previous item, and returns the associated data.
*
* @return {?} Item data.
*/
prevItem() {
if (this.head_ && this.head_.prev) {
this.head_ = this.head_.prev;
return this.head_.data;
}
return undefined;
}
/**
* Returns the previous item's data without moving the cursor.
*
* @return {?} Item data.
*/
getPrevItem() {
if (this.head_ && this.head_.prev) {
return this.head_.prev.data;
}
return undefined;
}
/**
* Returns the current item's data.
*
* @return {?} Item data.
*/
getCurrItem() {
if (this.head_) {
return this.head_.data;
}
return undefined;
}
/**
* Sets the first item of the list. This only works for circular lists, and sets
* the last item accordingly.
*/
setFirstItem() {
if (this.circular_ && this.head_) {
this.first_ = this.head_;
this.last_ = this.head_.prev;
}
}
/**
* Concatenates two lists.
* @param {LinkedList} list List to merge into the current list.
*/
concat(list) {
if (list.head_) {
if (this.head_) {
const end = this.head_.next;
this.head_.next = list.first_;
list.first_.prev = this.head_;
end.prev = list.last_;
list.last_.next = end;
this.length_ += list.length_;
} else {
this.head_ = list.head_;
this.first_ = list.first_;
this.last_ = list.last_;
this.length_ = list.length_;
}
list.head_ = undefined;
list.first_ = undefined;
list.last_ = undefined;
list.length_ = 0;
}
}
/**
* Returns the current length of the list.
*
* @return {number} Length.
*/
getLength() {
return this.length_;
}
}
export default LinkedList;