1. #ifndef __ENTRUSTOBSERVER_H__
2. #define __ENTRUSTOBSERVER_H__
3. #include "rtthread.h"
4. #include "finsh.h"
5. //根據類名和類裡面項的名,獲得類的入口句柄
6. #define ClassEntry(node, type, member) \
7. ((type *)((char *)(node) - (unsigned long)(&((type *)0)->member)))
8. //LIST數組
9. typedef struct _List List;
10. struct _List
11. {
12. void **pListPointArray; //LIST數組指針
13. int Total; //元素個數
14. void (*Add)(List *pList, void *pListPoint); //添加
15. void (*Remove)(List *pList, void *pListPoint); //移除
16. void (*Delete)(void *pList); //析構
17. };
18. //List類的析構函數
19. static void ListDelete(void *pList)
20. {
21. if(((List *)pList)->pListPointArray != RT_NULL) //先釋放指針數組
22. {
23. rt_free(((List *)pList)->pListPointArray);
24. }
25. rt_free(pList); //再釋放整個List類
26. }
27. //元素增加函數
28. static void ListAdd(List *pList, void *pListPoint)
29. {
30. void **tListPointArray = rt_malloc(sizeof(int *) * (pList->Total + 1)); //申請比原來大一個存儲單元的內存
31. int pListIndex;
32. for(pListIndex = 0; pListIndex < pList->Total; pListIndex++) //拷貝
33. {
34. if(pList->pListPointArray[pListIndex] == pListPoint) //判斷,如果有相同的元素存在
35. {
36. rt_free(tListPointArray); //釋放現申請的內存
37. return; //返回
38. }
39. tListPointArray[pListIndex] = pList->pListPointArray[pListIndex]; //拷貝
40. }
41. tListPointArray[pList->Total] = pListPoint; //將添加的元素放到最後一個存儲單元中
42. pList->Total += 1; //總數加1
43. if(pList->pListPointArray != RT_NULL) rt_free(pList->pListPointArray); //釋放原來的內存
44. pList->pListPointArray = tListPointArray; //將新的句柄替換原句柄
45. }
46. //元素移除函數
47. static void ListRemove(List *pList, void *pListPoint)
48. {
49. int pListIndex, tListIndex;
50. void **tListPointArray;
51. void **FreePointArray;
52. void **SavePointArray;
53. if(pList->Total == 0) return; //總數為0時退出
54. tListPointArray = rt_malloc(sizeof(int) * (pList->Total - 1)); //申請比原來小一個存儲單元的內存
55. FreePointArray = tListPointArray; //將剛申請的內存空間作為默認的釋放空間
56. SavePointArray = pList->pListPointArray; //將已有的內存空間作為默認的存儲空間
57. for(pListIndex = 0, tListIndex= 0; pListIndex < pList->Total; pListIndex++) //查找移除點
58. {
59. if(pList->pListPointArray[pListIndex] == pListPoint) //當前點是移除點
60. {
61. FreePointArray = pList->pListPointArray; //改變釋放內存指針
62. SavePointArray = tListPointArray; //改變保留內存指針
63. continue; //結束本次循環
64. }
65. if(tListIndex < (pList->Total -1)) //如果當前點不是移除點,拷貝序號小於總量減1
66. {
67. tListPointArray[tListIndex] = pList->pListPointArray[pListIndex]; //拷貝
68. tListIndex++; //拷貝序號加1
69. }
70. }
71. pList->Total = (SavePointArray == tListPointArray) ? pList->Total - 1 : pList->Total; //根據保留的內存塊改變總數的值
72. if(FreePointArray != RT_NULL) rt_free(FreePointArray); //釋放該釋放的不用的內存塊
73. pList->pListPointArray = SavePointArray; //保留該保留的
74. }
75. //List構造函數
76. static List *ListCreate(void)
77. {
78. List *pList = (List *)rt_malloc(sizeof(List));
79. pList->Total = 0;
80. pList->pListPointArray = RT_NULL;
81. pList->Add = ListAdd;
82. pList->Remove = ListRemove;
83. pList->Delete = ListDelete;
84. return pList;
85. }
86. //委托類
87. typedef void (*Event)(void *);
88. typedef struct _Entrust Entrust;
89. struct _Entrust
90. {
91. List *FunArray;
92. void (*Add)(void *pEntrust, void *pObject);
93. void (*Remove)(void *pEntrust, void *pObject);
94. void (*Update)(void *pEntrust);
95. void (*Delete)(void *pEntrust);
96. };
97. static void EntrustAdd(void *pEntrust, void *pFun)
98. {
99. List *pList = ((Entrust *)pEntrust)->FunArray;
100. pList->Add(pList, pFun);
101. }
102. static void EntrustRemove(void *pEntrust, void *pFun)
103. {
104. List *pList = ((Entrust *)pEntrust)->FunArray;
105. pList->Remove(pList, pFun);
106. }
107. static void EntrustUpdate(void *pEntrust)
108. {
109. List *pListFun = ((Entrust *)pEntrust)->FunArray;
110. int i;
111. int FunAddress;
112. if(pListFun->Total == 0) return;
113. for(i = 0; i < pListFun->Total; i++)
114. {
115. FunAddress = (int)(*(pListFun->pListPointArray + i));
116. //先將整型變量轉換成一個整形指針,再將該指針指向的內容轉換成Event函數指針
117. (*(Event)(*(int *)FunAddress))(pListFun->pListPointArray[i]);
118. }
119. }
120. static void EntrustDelete(void *pEntrust)
121. {
122. List *pList = ((Entrust *)pEntrust)->FunArray;
123. pList->Delete(pList);
124. rt_free(pEntrust);
125. }
126. static Entrust *EntrustCreate(rt_size_t Size)
127. {
128. Entrust *pEntrust = (Entrust *)rt_malloc(Size);
129. pEntrust->FunArray = (List *)ListCreate();
130. pEntrust->Add = EntrustAdd;
131. pEntrust->Remove = EntrustRemove;
132. pEntrust->Update = EntrustUpdate;
133. pEntrust->Delete = EntrustDelete;
134. return pEntrust;
135. }
136. //具體通知者
137. //通知者:老板
138. typedef struct _Boss Boss;
139. struct _Boss
140. {
141. Entrust *pEntrust; //添加一個委托類
142. char *Action;
143. char *(*GetSubjectState)(void *pBoss);
144. void (*SetSubjectState)(void *pBoss, char *pBossState);
145. void (*Notify)(void *pBoss);
146. void (*Delete)(void *pBoss);
147. };
148. static char *BossGetSubjectState(void *pBoss)
149. {
150. return ((Boss *)pBoss)->Action;
151. }
152. static void BossSetSubjectState(void *pBoss, char *pBossState)
153. {
154. ((Boss *)pBoss)->Action = pBossState;
155. }
156. static void BossNotify(void *pBoss)
157. {
158. Entrust *pEntrust = ((Boss *)pBoss)->pEntrust;
159. pEntrust->Update(pEntrust);
160. }
161. static void BossDelete(void *pBoss)
162. {
163. Entrust *pEntrust = ((Boss *)pBoss)->pEntrust;
164. pEntrust->Delete(pEntrust);
165. rt_free(pBoss);
166. }
167. static Boss *BossCreate(rt_size_t Size)
168. {
169. Boss *pBoss = (Boss *)rt_malloc(Size);
170. pBoss->pEntrust = EntrustCreate(sizeof(Entrust));
171. //重寫函數
172. pBoss->GetSubjectState = BossGetSubjectState;
173. pBoss->SetSubjectState = BossSetSubjectState;
174. pBoss->Notify = BossNotify;
175. pBoss->Delete = BossDelete;
176. return pBoss;
177. }
178. //具體觀察者
179. //看股票的同事
180. typedef struct _StockObserver StockObserver;
181. struct _StockObserver
182. {
183. char *Name;
184. Boss *pSub;
185. void (*CloseStock)(void *pObserver);
186. void (*Delete)(void *pObserver);
187. };
188. static void CloseStock(void *pCloseStock)
189. {
190. StockObserver *pStockObserver = ClassEntry(pCloseStock, StockObserver, CloseStock);
191. Boss *pSub = pStockObserver->pSub;
192. rt_kprintf(" %s,%s關閉股票行情,繼續工作\n", pSub->GetSubjectState(pSub), pStockObserver->Name);
193. }
194. static void StockObserverDelete(void *pStockObserver)
195. {
196. rt_free(pStockObserver);
197. }
198. static StockObserver *StockObserverCreate(char *Name, void *pSub, rt_size_t Size)
199. {
200. StockObserver *pStockObserver = (StockObserver *)rt_malloc(Size);
201. pStockObserver->Name = Name;
202. pStockObserver->pSub = pSub;
203. pStockObserver->CloseStock = CloseStock;
204. pStockObserver->Delete = StockObserverDelete;
205. return pStockObserver;
206. }
207. //看NBA的同事
208. typedef struct _NBAObserver NBAObserver;
209. struct _NBAObserver
210. {
211. char *Name;
212. Boss *pSub;
213. void (*CloseNBA)(void *pObserver);
214. void (*Delete)(void *pObserver);
215. };
216. static void CloseNBA(void *pCloseNBA)
217. {
218. NBAObserver *pNBAObserver = ClassEntry(pCloseNBA, NBAObserver, CloseNBA);
219. Boss *pSub = pNBAObserver->pSub;
220. rt_kprintf(" %s,%s關閉NBA轉播,繼續工作\n", pSub->GetSubjectState(pSub), pNBAObserver->Name);
221. }
222. static void NBAObserverDelete(void *pNBAObserver)
223. {
224. rt_free(pNBAObserver);
225. }
226. static NBAObserver *NBAObserverCreate(char *Name, void *pSub, rt_size_t Size)
227. {
228. NBAObserver *pNBAObserver = (NBAObserver *)rt_malloc(Size);
229. pNBAObserver->Name = Name;
230. pNBAObserver->pSub = pSub;
231. pNBAObserver->CloseNBA = CloseNBA;
232. pNBAObserver->Delete = NBAObserverDelete;
233. return pNBAObserver;
234. }
235.
236. #endif
237.
238.
239.
240. #include "EntrustObserver.h"
241. //客戶端
242. void EntrustObs(void)
243. {
244. Boss *huhasan = BossCreate(sizeof(Boss));
245. StockObserver *tongshi1 = StockObserverCreate("魏關姹", huhasan, sizeof(StockObserver));
246. NBAObserver *tongshi2 = NBAObserverCreate("易管查", huhasan, sizeof(NBAObserver));
247. //在委托裡添加事件功能 www.2cto.com
248. huhasan->pEntrust->Add(huhasan->pEntrust, &(tongshi1->CloseStock));
249. huhasan->pEntrust->Add(huhasan->pEntrust, &(tongshi2->CloseNBA));
250. //改變通知者狀態
251. huhasan->SetSubjectState(huhasan, "我胡漢三回來啦");
252. //通知者通知
253. huhasan->Notify(huhasan);
254.
255. huhasan->Delete(huhasan);
256. tongshi1->Delete(tongshi1);
257. tongshi2->Delete(tongshi2);
258. }
259. FINSH_FUNCTION_EXPORT(EntrustObs, Entrust Observer Modle);