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);