ChipMaster's trial hacks on C++CMS starting with v1.2.1. Not sure I'll follow on with the v2 since it looks to be breaking and mostly frivolous.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

249 lines
6.6 KiB

  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (C) 2008-2012 Artyom Beilis (Tonkikh) <artyomtnk@yahoo.com>
  4. //
  5. // See accompanying file COPYING.TXT file for licensing details.
  6. //
  7. ///////////////////////////////////////////////////////////////////////////////
  8. #ifndef CPPCMS_VIEWS_POOL_H
  9. #define CPPCMS_VIEWS_POOL_H
  10. #include <cppcms/defs.h>
  11. #include <booster/noncopyable.h>
  12. #include <cppcms/base_view.h>
  13. #include <cppcms/cppcms_error.h>
  14. #include <booster/auto_ptr_inc.h>
  15. #include <map>
  16. #include <vector>
  17. #include <ostream>
  18. namespace cppcms {
  19. namespace json { class value; }
  20. ///
  21. /// \brief this namespace holds all classes used for rendering CppCMS views.
  22. ///
  23. namespace views {
  24. ///
  25. /// \brief The class that represents a single skin and generates its views.
  26. ///
  27. /// Usually used by templates compiler
  28. ///
  29. class CPPCMS_API generator : public booster::noncopyable {
  30. public:
  31. /// The callback that creates a single view
  32. typedef std::auto_ptr<base_view> view_factory_type(std::ostream &,base_content *c);
  33. generator();
  34. ~generator();
  35. ///
  36. /// Add a single view of type \a View that uses content of type \a Content
  37. /// Using name \a view_name.
  38. ///
  39. /// If \a safe is true that dynamic cast is used to ensure that content has proper type
  40. /// otherwise static cast.
  41. ///
  42. /// Usually used by templates generator
  43. ///
  44. template<typename View,typename Content>
  45. void add_view(std::string const &view_name,bool safe = true)
  46. {
  47. view_factory_type *factory = 0;
  48. if(safe)
  49. factory = view_builder<View,Content>;
  50. else
  51. factory = unsafe_view_builder<View,Content>;
  52. add_factory(view_name,factory);
  53. }
  54. ///
  55. /// Add a view that uses a callback
  56. ///
  57. void add_factory(std::string const &name,view_factory_type *factory);
  58. ///
  59. /// Get skin name
  60. ///
  61. std::string name() const;
  62. ///
  63. /// Set skin name
  64. ///
  65. void name(std::string const &n);
  66. ///
  67. /// Create a view by its name that writes that data to \a outout using
  68. /// a content \a content.
  69. ///
  70. std::auto_ptr<base_view> create(std::string const &view_name,
  71. std::ostream &output,
  72. base_content *content) const;
  73. ///
  74. /// Enumerate view names
  75. ///
  76. std::vector<std::string> enumerate() const;
  77. private:
  78. template<typename View,typename Content>
  79. static std::auto_ptr<base_view> view_builder(std::ostream &stream,base_content *c)
  80. {
  81. std::auto_ptr<base_view> p;
  82. try {
  83. p.reset(new View(stream,dynamic_cast<Content &>(*c)));
  84. }
  85. catch(std::bad_cast const &) {
  86. throw cppcms_error("cppcms::views::generator: an attempt to use content of invalid type");
  87. }
  88. return p;
  89. }
  90. template<typename View,typename Content>
  91. static std::auto_ptr<base_view> unsafe_view_builder(std::ostream &stream,base_content *c)
  92. {
  93. std::auto_ptr<base_view> p(new View(stream,static_cast<Content &>(*c)));
  94. return p;
  95. }
  96. struct data;
  97. typedef std::map<std::string,view_factory_type *> views_type;
  98. views_type views_;
  99. std::string name_;
  100. booster::hold_ptr<data> d;
  101. };
  102. ///
  103. /// \brief A class that allows to use the view withing the internal lock used inside pool class
  104. ///
  105. /// It is similar in its operation in creating the view class similarly to pool::render() but
  106. /// not calling base_view::render member function.
  107. ///
  108. /// It is used with `<% using ... from ... %>` CppCMS template
  109. ///
  110. /// \ver{v1_2}
  111. class CPPCMS_API view_lock : public booster::noncopyable {
  112. public:
  113. ///
  114. /// Create a view and lock pool's internal lock
  115. ///
  116. view_lock(std::string const &skin,std::string const &template_name,std::ostream &out,base_content &content);
  117. ///
  118. /// Delete the view and unlock the pool's lock
  119. ///
  120. ~view_lock();
  121. ///
  122. /// Shortcut to dynamic_cast<View &>(view())
  123. ///
  124. template<typename View>
  125. View &use_view()
  126. {
  127. return dynamic_cast<View &>(view());
  128. }
  129. ///
  130. /// Get the underlying view object
  131. ///
  132. base_view &view();
  133. private:
  134. struct _data;
  135. booster::hold_ptr<base_view> view_;
  136. booster::hold_ptr<_data> d;
  137. };
  138. ///
  139. /// \brief This is a singleton object that holds all views in the process. Any view
  140. /// is registered and unregistered via this object.
  141. ///
  142. /// It is usually not used directly
  143. ///
  144. class CPPCMS_API pool : public booster::noncopyable {
  145. public:
  146. ///
  147. /// Add new skin to pool
  148. ///
  149. /// This function is thread safe
  150. ///
  151. void add(generator const &generator);
  152. ///
  153. /// Remove the skin from pool
  154. ///
  155. /// This function is thread safe
  156. ///
  157. void remove(generator const &generator);
  158. ///
  159. /// Render Skin
  160. ///
  161. /// This member function is used to render templates. Generally you should not use
  162. /// it directly, unless you have very good reasons.
  163. ///
  164. /// \param skin - the name of the skin that should be used
  165. /// \param template_name - the name of template (class) that should be rendered.
  166. /// \param out - the output stream into which the view should be rendered
  167. /// \param content - the content that should be rendered using this view.
  168. ///
  169. /// This function is thread safe
  170. ///
  171. void render(std::string const &skin,std::string const &template_name,std::ostream &out,base_content &content);
  172. ///
  173. /// Get all loaded views
  174. ///
  175. /// This function is thread safe
  176. ///
  177. /// \ver{v1_2}
  178. std::vector<std::string> enumerate();
  179. ///
  180. /// Get the singleton instance of the views pool
  181. ///
  182. static pool &instance();
  183. private:
  184. friend class view_lock;
  185. void lock();
  186. void unlock();
  187. // called on locked object
  188. base_view *create_view(std::string const &skin,std::string const &template_name,std::ostream &out,base_content &content);
  189. pool();
  190. ~pool();
  191. struct data;
  192. booster::hold_ptr<data> d;
  193. };
  194. ///
  195. /// \brief This class controls the views used my application it knows to load them dynamically
  196. /// and reload if needed
  197. ///
  198. class CPPCMS_API manager : public booster::noncopyable {
  199. public:
  200. ///
  201. /// Create new views manager
  202. ///
  203. /// Usually created by cppcms::service()
  204. ///
  205. manager(json::value const &settings);
  206. ~manager();
  207. ///
  208. /// Render a template in a skin. Checks if any of shared objects/dlls should be reloaded
  209. ///
  210. void render(std::string const &skin,std::string const &template_name,std::ostream &out,base_content &content);
  211. ///
  212. /// Get default skin
  213. ///
  214. std::string default_skin();
  215. private:
  216. struct data;
  217. booster::hold_ptr<data> d;
  218. };
  219. } // views
  220. }
  221. #endif