Lumiera  0.pre.03
»edit your freedom«
session-service-access-test.cpp
Go to the documentation of this file.
1 /*
2  SessionServiceAccess(Test) - accessing implementation level session services
3 
4  Copyright (C) Lumiera.org
5  2008, Hermann Vosseler <Ichthyostega@web.de>
6 
7  This program is free software; you can redistribute it and/or
8  modify it under the terms of the GNU General Public License as
9  published by the Free Software Foundation; either version 2 of
10  the License, or (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 
21 * *****************************************************/
22 
28 #include "lib/test/run.hpp"
30 #include "lib/meta/generator.hpp"
31 #include "lib/format-cout.hpp"
32 #include "lib/depend.hpp"
33 
34 #include <boost/lexical_cast.hpp>
35 #include <memory>
36 #include <string>
37 
38 
39 namespace steam {
40 namespace mobject {
41 namespace session {
42 namespace test {
43 
44  using lib::Depend;
45  using boost::lexical_cast;
46  using std::unique_ptr;
47  using std::string;
48 
49 
50  namespace { // what follows is a simulated (simplified) version
51  // of the complete Session + SessionManager setup.....
52 
53  using lib::meta::Types;
55 
56 
57 
58  /* === Interface level === */ //----------------corresponding-to-session.hpp
59 
60  struct TSessManager;
61  typedef TSessManager& PSess;
62 
63  struct TSession
64  {
65  virtual ~TSession () { }
66  static TSessManager& current;
67 
68  virtual void externalOperation () =0;
69  };
70 
71  struct TSessManager
72  {
74  virtual TSession* operator-> () =0;
75 
76  virtual void reset () =0;
77  virtual ~TSessManager() { };
78  };
79 
80 
81 
82 
83  /* === Service level API === */ //----------------internal-API-definition-headers
84 
86  {
87  virtual ~InternalAPI_1() {}
88  virtual uint getMagic() =0;
89 
90  static InternalAPI_1& access();
91  };
92 
94  {
95  static void invokeImplementationService();
96  };
97 
98 
99 
100  /* === Implementation level === */ //----------------corresponding-to-session-impl.hpp
101 
103  {
104  static uint magic_;
105 
106  /* ==== Session API ==== */
107  void externalOperation() ;
108 
109  /* ==== Implementation level API ==== */
110  void implementationService() ;
111 
112  /* ==== internals ==== */
113 
114  TSessionImpl();
115  operator string() const;
116  };
117 
118 
119 
120  template<class API, class IMPL>
122 
123  template<class IMPL>
125  : IMPL
126  , InternalAPI_1
127  {
128  uint
129  getMagic ()
130  {
131  return IMPL::magic_;
132  }
133  };
134 
135  template<class IMPL>
137  : IMPL
138  {
139  void
140  forwardServiceInvocation()
141  {
142  IMPL::implementationService();
143  }
144  };
145 
146  template< typename IMPS
147  , class FRONT
148  , class SESS
149  >
151  : public InstantiateChained<typename IMPS::List, TServiceAccessPoint, SESS>
152  {
153  public:
154 
155  static FRONT& current;
156 
157  template<class API>
158  API&
159  get()
160  {
161  return *this;
162  }
163  };
164 
165 
166 
167 
168 
169  /* === storage and basic session manager configuration === */
170 
171  struct TSessManagerImpl;
172 
175  , TSessionImpl
176  > SessionImplAPI;
177 
178 
179 
180  struct TSessManagerImpl : TSessManager
181  {
182  unique_ptr<SessionImplAPI> pImpl_;
183 
184  TSessManagerImpl()
185  : pImpl_{}
186  { }
187 
188  SessionImplAPI*
189  operator-> ()
190  {
191  if (!pImpl_)
192  this->reset();
193  return pImpl_.get();
194  }
195 
196 
197  /* ==== Manager API ==== */
198  void
199  reset ()
200  {
201  unique_ptr<SessionImplAPI> tmpS {new SessionImplAPI};
202  pImpl_.swap (tmpS);
203  }
204  };
205 
206 
207  uint TSessionImpl::magic_;
208 
209  TSessManager& TSession::current = Depend<TSessManagerImpl>()();
210  //note: already during static initialisation
211 
212  template<>
213  TSessManagerImpl& SessionImplAPI::current = static_cast<TSessManagerImpl&> (TSession::current);
214 
215 
216 
217 
218 
219 
220 
221 
222  /* === Implementation of service access === */ //----------------corresponding-to-session-services.cpp
223 
225  InternalAPI_1::access()
226  {
227  return SessionImplAPI::current->get<InternalAPI_1>();
228  }
229 
230  void
231  InternalAPI_2::invokeImplementationService()
232  {
233  SessionImplAPI::current->forwardServiceInvocation();
234  }
235 
236 
237 
238 
239 
240  /* === Implementation of Session internals === */ //----------------corresponding-to-session-impl.cpp
241 
242  TSessionImpl::operator string() const
243  {
244  return string("Session-Impl(")
245  + lexical_cast<string>(magic_)
246  + ")";
247  }
248 
249  TSessionImpl::TSessionImpl()
250  {
251  ++magic_;
252  cout << "creating new Session " << magic_ << endl;
253  }
254 
255  void
256  TSessionImpl::externalOperation()
257  {
258  cout << this << "::externalOperation()" << endl;
259  }
260 
261  /* ==== Implementation level API ==== */
262  inline void
263  TSessionImpl::implementationService()
264  {
265  cout << this << "::implementationService()" << endl;
266  }
267 
268 
269  } // (END) simulated session management
270 
271 
272 
273 
274 
275 
276 
277 
278 
279 
280  /***************************************************************************/
290  class SessionServiceAccess_test : public Test
291  {
292  virtual void
293  run (Arg)
294  {
295  access_defaultSession();
296  make_newSession();
297  invoke_implServices();
298  }
299 
300 
305  void
307  {
308  cout << "Session not yet used...." << endl;
309  TSession::current->externalOperation();
310  }
311 
312 
317  void
319  {
320  TSession::current.reset();
321  TSession::current->externalOperation();
322  }
323 
324 
327  uint magic() { return InternalAPI_1::access().getMagic(); }
328 
330  void
332  {
333  cout << "current Session-Impl-ID = " << magic() << endl;
334  InternalAPI_2::invokeImplementationService();
335 
336  cout << "now resetting this session." << endl;
337  TSession::current.reset();
338 
339  InternalAPI_2::invokeImplementationService(); // invocation creates new session as side effect
340  cout << "current Session-Impl-ID = " << magic() << endl;
341  }
342  };
343 
344 
346  LAUNCHER (SessionServiceAccess_test, "function session");
347 
348 
349 
350 }}}} // namespace steam::mobject::session::test
Automatically use custom string conversion in C++ stream output.
static FRONT & current
intended to be hard-wired to SessManagerImpl singleton
Definition: run.hpp:49
Helpers for working with lib::meta::Types (i.e.
Steam-Layer implementation namespace root.
Namespace of Session and user visible high-level objects.
Definition: sequence.hpp:74
Access point to singletons and other kinds of dependencies designated by type.
Definition: depend.hpp:289
session::SessManager & PSess
acts as a "PImpl" smart ptr
Definition: session.hpp:82
Simple test class runner.
SessionServices< Types< SessionServiceFetch, SessionServiceMutate, SessionServiceExploreScope, SessionServiceMockIndex, SessionServiceDefaults >, SessManagerImpl, SessionImpl > SessionImplAPI
actual configuration of the session implementation compound: forming an inheritance chain of all inte...
Build a single inheritance chain of template instantiations.
Definition: generator.hpp:129
Singleton services and Dependency Injection.
uint magic()
example of an one-liner, as it might be used internally by implementation code within Steam-Layer ...
Verify the access mechanism both to the pubic session API and to implementation level APIs used by St...
Primary Interface to the current Session.