OfficeXml/utils/vba/Collection.tsf

182 lines
3.7 KiB
Plaintext

type Collection = class
public
function Create();
function Operator[](index: stringORinteger): tslobj;
function SetIgnoreCase(value: boolean);
function SetActivation(value: tslobj);
function GetActivation(): tslobj;
function CalNewName(prefix: string): string;
function AddCollection(obj: tslobj; name: string);
function RemoveCollection(index: stringORinteger);
function GetCount(): integer;
private
function CompareFunction(index: stringORinteger; data: tslobj): boolean;
private
ignorecase_: boolean; // 忽略大小写
container_: anycontainer; // 容器对象
[weakref]activation_: tslobj; // 激活的对象
[weakref]fp_; // 函数指针 -- 用来比较
end;
type LinkList = class
public
function Create();
function Add(data: tslobj);
function Remove(index: stringORinteger; fp: functionPointer);
function Size();
function Get(index: stringORinteger; fp: functionPointer);
private
function Find(index: stringORinteger; fp: functionPointer);
private
count_: integer;
head_: Node;
tail_: Node;
end;
// ============== 实现 ================= //
function Collection.Create();
begin
container_ := new LinkList();
ignorecase_ := false;
fp_ := thisFunction(CompareFunction);
end;
function Operator Collection.[](index: stringORinteger): tslobj;
begin
ret := container_.Get(index, fp_);
return ret ? ret.obj : nil;
end;
function Collection.SetIgnoreCase(value: boolean);
begin
ignorecase_ := value;
end;
function Collection.SetActivation(value: tslobj);
begin
activation_ := self[value];
end;
function Collection.GetActivation(): tslobj;
begin
return activation_;
end;
function Collection.CalNewName(prefix: string): string;
begin
len := {self.}GetCount() + 1;
name := prefix $ len;
while container_.Get(name, fp_) do
name := prefix $ ++len;
return name;
end;
function Collection.AddCollection(obj: tslobj; name: string);
begin
data := new Data();
data.obj := obj;
data.name := name;
data.index := {self.}GetCount() + 1;
container_.Add(data);
end;
function Collection.RemoveCollection(index: stringORinteger);
begin
container_.Remove(index, fp_);
end;
function Collection.GetCount(): integer;
begin
return container_.Size();
end;
function Collection.CompareFunction(index: stringORinteger; data: tslobj): boolean;
begin
return (ifNumber(index) and data.index = index) or
(ifString(index) and (data.name = index or (ignorecase_ and lowercase(data.name) = lowercase(index))));
end;
// 集合中需要记录的数据
type Data = class
obj: tslobj;
name: string;
index: integer;
end;
function LinkList.Create();
begin
head_ := new Node(nil);
tail_ := head_;
count_ := 0;
end;
function LinkList.Add(data: tslobj);
begin
node := new Node(data);
tail_.next := node;
node.prev := tail_;
tail_ := node;
count_ ++;
end;
function LinkList.Remove(index: stringORinteger; fp: functionPointer);
begin
node := Find(index, fp);
if ifnil(node) then return;
if node = tail_ then
begin
tail_ := node.prev;
node.prev.next := nil;
end
else begin
node.prev.next := node.next;
node.next.prev := node.prev;
node := nil;
end
count_--;
end;
function LinkList.Size();
begin
return count_;
end;
function LinkList.Find(index: stringORinteger; fp: functionPointer);
begin
node := head_.next;
while (node) do
begin
if (fp and fp.do(index, node.data)) or node.data = index then
return node;
node := node.next;
end
return nil;
end;
function LinkList.Get(index: stringORinteger; fp: functionPointer);
begin
node := Find(index, fp);
return ifnil(node) ? nil : node.data;
end;
type Node = class
public
function Create(value: tslobj);
begin
data := value;
prev := nil;
next := nil;
end;
data: tslobj;
[weakref]prev: Node;
next: Node;
end;