CbkDispatcher.h
上传用户:smh666999
上传日期:2007-01-14
资源大小:553k
文件大小:4k
源码类别:

BREW编程

开发平台:

Visual C++

  1. #ifndef _CBK_DISPATCHER_h_
  2. #define _CBK_DISPATCHER_h_
  3. #include "AEEError.h"
  4. #include "BrewVector.h"
  5. class IRelease
  6. {
  7. public:
  8. virtual void releaseResource() = 0;
  9. virtual int getUID() = 0;
  10. virtual ~IRelease() {};
  11. protected:
  12. IRelease(){};
  13. private:
  14. IRelease( const IRelease &value );
  15. const IRelease &operator = ( const IRelease &rhs );
  16. };
  17. class IExecute
  18. {
  19. public:
  20. virtual void onCbk() = 0;
  21. protected:
  22. IExecute(){};
  23. virtual ~IExecute() {};
  24. private:
  25. IExecute( const IExecute &value );
  26. const IExecute &operator = ( const IExecute &rhs );
  27. };
  28. class ResourceRegistry
  29. {
  30. public:
  31. void registerResource(IRelease* resource)
  32. {
  33. for(int i = resources_.size() - 1; i >= 0; --i)
  34. {
  35. if (resources_[i] && resources_[i] == resource)
  36. {
  37. return;
  38. }
  39. }
  40. resources_.append(resource);
  41. if (resources_.size() > swapLimit_)
  42. swap();
  43. }
  44. bool unregisterResource(IRelease* resource)
  45. {
  46. for(int i = resources_.size() - 1; i >= 0; --i)
  47. {
  48. IRelease* t = resources_[i];
  49. if (t && t == resource)
  50. {
  51. resources_.setAt(0,i) ;
  52. return true;
  53. }
  54. }
  55. return false;
  56. }
  57. IRelease* getRegistered(int uid) 
  58. {
  59. for(int i = resources_.size() - 1; i >= 0; --i)
  60. {
  61. IRelease* t = resources_[i];
  62. if (t && (uid == t->getUID()))
  63. {
  64. return t;
  65. }
  66. }
  67. return 0;
  68. }
  69. ~ResourceRegistry() //unusable if using cppapp - manual destruction
  70. {
  71. unregisterResources();
  72. }
  73. ResourceRegistry(int swapLimit): swapLimit_(swapLimit)
  74. {}
  75. private:
  76. void unregisterResources()
  77. {
  78. for(int i=0, sz = resources_.size(); i < sz; ++i)
  79. {
  80. IRelease* t = (resources_[i]);
  81. if (t)
  82. {
  83. t->releaseResource();
  84. resources_.setAt(0,i) ;
  85. }
  86. }
  87. }
  88. void swap()
  89. {
  90. BrewPVector<IRelease> v;
  91. for(int i=0, sz = resources_.size(); i < sz; ++i)
  92. {
  93. if (resources_[i])
  94. {
  95. v.append(resources_[i]);
  96. }
  97. }
  98. BrewPVector<IRelease> resources_;
  99. resources_.ensureCapacity(v.size());
  100. for(int j=0, szj = v.size(); j < szj; ++j)
  101. {
  102. if (v[j])
  103. {
  104. resources_.append(v[j]);
  105. }
  106. }
  107. }
  108. private:
  109. BrewPVector<IRelease> resources_;
  110. int swapLimit_;
  111. private:
  112. ResourceRegistry( const ResourceRegistry &value );
  113. const ResourceRegistry &operator = ( const ResourceRegistry &rhs );
  114. };
  115. template <class P, class T, class U, class W, class R = ResourceRegistry>
  116. class CbkDispatcher : public IRelease, public IExecute
  117. {
  118. public: 
  119. virtual void onCbk( ) 
  120. {
  121. p_();
  122. close();
  123. }
  124. virtual void releaseResource( ) 
  125. {
  126. delete this;
  127. }
  128. virtual int getUID( ) 
  129. {
  130. return W::getID() + 10;
  131. }
  132. static int getID()
  133. {
  134. return W::getID() + 10;
  135. }
  136. static int getDispatcher(IShell* shell, R*  r, P& p, W* w)
  137. {
  138. CbkDispatcher* hd = 0;
  139. if (T::isReusable())
  140. {
  141. hd = static_cast<CbkDispatcher*>(r->getRegistered(CbkDispatcher::getID()));
  142. }
  143. if (!hd)
  144. {
  145. hd = new CbkDispatcher(shell,  r, p);
  146. }
  147. int err = hd->initRequest(w);
  148. if (err != SUCCESS)
  149. {
  150. delete hd;
  151. }
  152. return err;
  153. }
  154. ~CbkDispatcher()
  155. {
  156. releaseResources();
  157. }
  158. private:
  159. CbkDispatcher(  IShell* shell, R*  r, P& p): 
  160. shell_(shell),
  161. u_(0),
  162. p_(p),
  163. r_(r)
  164. {
  165. void releaseResources()
  166. {
  167. releasePipe();
  168. r_->unregisterResource(this);
  169. }
  170. void releasePipe()
  171. {
  172. delete u_;
  173. u_ = 0;
  174. }
  175. void close() const
  176. {
  177. if (! T::isReusable())
  178. delete this;
  179. else
  180. u_->reset();
  181. }
  182. int initRequest(W* w) 
  183. {
  184. int err = SUCCESS;
  185. bool isFresh = false;
  186. if (!u_)
  187. {
  188. isFresh = true;
  189. u_ = new U(shell_, this,  w );
  190. if ((err = u_->init()) != SUCCESS)
  191. {
  192. releasePipe();
  193. return err;
  194. }
  195. err = u_->initConnection();
  196. if (err != SUCCESS)
  197. {
  198. releasePipe();
  199. return err;
  200. }
  201. if (isFresh)
  202. r_->registerResource(this);
  203. return err;
  204. }
  205. private:
  206. IShell* shell_;
  207. U* u_;
  208. P& p_;
  209. R* r_;
  210. private:
  211. CbkDispatcher( const CbkDispatcher &Value );
  212. const CbkDispatcher & operator = ( const CbkDispatcher &Rhs );
  213. //CbkDispatcher(){};
  214. };
  215. #endif