1 Queue = Queue or {}
2
3 function Queue.new()
4 local inst = {}
5 inst._cname = "lang.Queue"
6
7 local arr = {}
8 local cursor1 = 1
9 local len = 0
10
11 function inst:count()
12 return len
13 end
14
15 local function getCursor2()
16 return cursor1 + len - 1
17 end
18
19 function inst:clear()
20 for i=cursor1,getCursor2() do
21 arr[i] = nil
22 end
23 cursor1 = 1
24 len = 0
25 end
26
27 function inst:contains(v)
28 for i=cursor1,getCursor2() do
29 if arr[i] == v then
30 return true
31 end
32 end
33 return false
34 end
35
36 function inst:enqueue(v)
37 arr[cursor1 + len] = v
38 len = len + 1
39 end
40
41 function inst:dequeue()
42 local cursor2 = getCursor2()
43 assert(cursor1 <= cursor2, "Queue: dequeue: out of range")
44 local v = arr[cursor1]
45 arr[cursor1] = nil
46 cursor1 = cursor1 + 1
47 len = len - 1
48
49 if cursor1 >= 8 then --todo: 參考NetBuff
50 local j = 1
51 for i=cursor1,cursor2 do
52 arr[j] = arr[i]
53 j = j + 1
54 end
55 for i=j,cursor2 do
56 arr[i] = nil
57 end
58 cursor1 = 1
59 end
60 return v
61 end
62
63 function inst:peek()
64 local v = arr[cursor1]
65 return v
66 end
67
68 function inst:copyTo(dst)
69 assert("table" == type(dst), "copyTo: dst not table or Stack")
70 if "lang.Queue" == dst._cname then
71 for i=cursor1,getCursor2() do
72 dst:enqueue(arr[i])
73 end
74 else
75 for i=cursor1,getCursor2() do
76 table.insert(dst, arr[i])
77 end
78 end
79 end
80
81 function inst:__tostring()
82 if len <= 0 then return "" end
83 local strTb = {}
84 for i=cursor1,getCursor2() do
85 local item = arr[i]
86 table.insert(strTb, (nil == item) and "nil" or tostring(item))
87 end
88 return table.concat(strTb, ",")
89 end
90
91 function inst:__len()
92 return len
93 end
94
95 function inst:__index(k)
96 error("Queue: invalid member: " .. k)
97 end
98
99 function inst:__newindex(k, v)
100 error("Queue: add member error: " .. k)
101 end
102
103 setmetatable(inst, inst)
104 return inst
105 end
106
107 function Queue.__call()
108 return Queue.new()
109 end
110 setmetatable(Queue, Queue)
測試代碼:
1 local function Test1()
2 local q = Queue()
3 assert(0 == q:count(), "count error")
4
5 q:enqueue("one")
6 assert(1 == q:count(), "enqueue error")
7 assert("one" == q:peek(), "peek error")
8 assert(true == q:contains("one"), "contains error")
9 assert(false == q:contains("1"), "contains error")
10
11 q:enqueue("two")
12 assert(2 == q:count(), "enqueue error")
13 assert("one" == q:peek(), "peek error")
14 assert(true == q:contains("one"), "contains error")
15 assert(true == q:contains("two"), "contains error")
16 assert(false == q:contains("1"), "contains error")
17
18 assert("one" == q:dequeue(), "dequeue error")
19 assert(1 == q:count(), "enqueue error")
20 assert("two" == q:dequeue(), "dequeue error")
21 assert(0 == q:count(), "enqueue error")
22 assert(nil == q:peek(), "dequeue error")
23 --q:dequeue() --error
24
25 local q2 = Queue()
26 q2:enqueue("1")
27 q:enqueue("a")
28 q:copyTo(q2)
29 assert("1" == q2:dequeue(), "dequeue error")
30 assert(1 == q2:count(), "enqueue error")
31 assert("a" == q2:dequeue(), "dequeue error")
32 assert(0 == q2:count(), "enqueue error")
33 assert(nil == q2:peek(), "dequeue error")
34 end
35
36 Test1()