import {MemoryUtil} from '../MemoryUtil'; import {RuntimeUtil} from '../RuntimeUtil'; import {Base} from './Base'; import {LooperEntry} from './LooperEntry'; import {StringBuffer} from './StringBuffer'; //========================================================== // 自循环链表。 // // @tool // @author maocy // @version 150110 //========================================================== export class Looper extends Base { // 总数 _count: number = 0; // 记录数 _recordCount: number = 0; // 当前位置 _current: any = null; //========================================================== // 内部增加一个节点。 // // @method // @param entry:SLooperEntry 节点 //========================================================== public innerPush(entry) { var o = this; var current = o._current; if (current) { var prior = current.prior; entry.prior = prior; entry.next = current; prior.next = entry; current.prior = entry; } else { entry.prior = entry; entry.next = entry; o._current = entry; } o._count++; } //========================================================== // 内部移除一个节点。 // // @method // @param entry:SLooperEntry 节点 //========================================================== public innerRemove(entry) { var o = this; // 删除入口 var prior = entry.prior; var next = entry.next; prior.next = next; next.prior = prior; // 设置数据 o._count--; if (o._count > 0) { o._current = next; } else { o._current = null; } // 释放入口 MemoryUtil.free(entry); } //========================================================== // 内部移除当前节点。 // // @method // @return Object 对象 //========================================================== public innerRemoveCurrent() { var o = this; var value = null; if (o._count > 0) { // 获得内容 var current = o._current; value = current.value; // 移除节点 o.innerRemove(current); } return value; } //========================================================== // 内部移除指定对象的节点。 // // @method // @param value:Object 对象 //========================================================== public innerRemoveValue(value) { var o = this; if (o._count > 0) { // 删除首个对象 if (o._current.value == value) { o.innerRemoveCurrent(); return; } // 删除其他对象 var current = o._current; var entry = current.next; while (entry != current) { if (entry.value == value) { o.innerRemove(entry); // 重置到原始位置 o._current = current; return; } entry = entry.next; } } } //========================================================== // 判断是否为空。 // // @method // @return 是否为空 //========================================================== public isEmpty() { return this._count == 0; } //========================================================== // 获得总数。 // // @method // @return Integer 总数 //========================================================== public count() { return this._count; } //========================================================== // 记录当前刻录点。 // // @method //========================================================== public record() { var o = this; o._recordCount = o._count; } //========================================================== // 消除当前刻录点。 // // @method //========================================================== public unrecord(v) { this._recordCount = -1; } //========================================================== // 判断是否含有指定对象。 // // @method // @param value:Object 对象 // @return Boolean 是否含有 //========================================================== public contains(value) { var o = this; if (o._current) { var entry = o._current; var count = o._count; for (var i = 0; i < count; i++) { if (entry.value == value) { return true; } entry = entry.next; } } return false; } //========================================================== // 获得当前对象。 // // @method // @return Object 对象 //========================================================== public current() { var entry = this._current; return entry ? entry.value : null; } //========================================================== // 获得下个对象。 // // @method // @return Object 对象 //========================================================== public next() { var o = this; // 移动当前点 if (o._current) { o._current = o._current.next; } // 检查刻录点(当只有一个元素时,刻录点无效) var count = o._recordCount; if (count > 0) { o._recordCount--; } else if (count == 0) { return null; } // 返回内容 return o._current ? o._current.value : null; } //========================================================== // 增加一个对象到尾部。 // // @method // @param value:Object 对象 //========================================================== public push(value) { var entry = MemoryUtil.alloc(LooperEntry); entry.value = value; this.innerPush(entry); } //========================================================== // 插入一个唯一内容到尾部。 // // @method // @param value:Object 对象 //========================================================== public pushUnique(value) { var o = this; if (!o.contains(value)) { o.push(value); } } //========================================================== // 移除当前的节点,并返回该元素的对象。 // // @method // @return Object 对象 //========================================================== public removeCurrent() { return this.innerRemoveCurrent(); } //========================================================== // 移除所有指定对象。 // // @method // @param p:value:Object 对象 //========================================================== public remove(p) { this.innerRemoveValue(p); } //========================================================== // 清除所有内容。 // // @method //========================================================== public clear() { var o = this; // 释放所有节点 var entry = o._current; if (entry) { entry.prior.next = null; while (entry) { var next = entry.next; MemoryUtil.free(next); entry = next; } } // 释放属性 o._count = 0; o._current = null; } //========================================================== // 释放处理。 // // @method //========================================================== public dispose() { this.clear(); } //========================================================== // 获得运行时信息。 // // @method // @return String 运行字符串 //========================================================== public dump() { var o = this; var count = o._count; var result: StringBuffer = new StringBuffer(); result.append(RuntimeUtil.className(this), ': ', count); if (count > 0) { var entry = o._current; for (var i = 0; i < count; i++) { result.append(' [', entry.value, ']'); entry = entry.next; } } return result.flush(); } }