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)
5  2008, Hermann Vosseler <Ichthyostega@web.de>
6 
7   **Lumiera** is free software; you can redistribute it and/or modify it
8   under the terms of the GNU General Public License as published by the
9   Free Software Foundation; either version 2 of the License, or (at your
10   option) any later version. See the file COPYING for further details.
11 
12 * *****************************************************************/
13 
19 #include "lib/test/run.hpp"
21 #include "lib/meta/generator.hpp"
22 #include "lib/format-cout.hpp"
23 #include "lib/depend.hpp"
24 
25 #include <boost/lexical_cast.hpp>
26 #include <memory>
27 #include <string>
28 
29 
30 namespace steam {
31 namespace mobject {
32 namespace session {
33 namespace test {
34 
35  using lib::Depend;
36  using boost::lexical_cast;
37  using std::unique_ptr;
38  using std::string;
39 
40 
41  namespace { // what follows is a simulated (simplified) version
42  // of the complete Session + SessionManager setup.....
43 
44  using lib::meta::Types;
46 
47 
48 
49  /* === Interface level === */ //----------------corresponding-to-session.hpp
50 
51  struct TSessManager;
52  typedef TSessManager& PSess;
53 
54  struct TSession
55  {
56  virtual ~TSession () { }
57  static TSessManager& current;
58 
59  virtual void externalOperation () =0;
60  };
61 
62  struct TSessManager
63  {
65  virtual TSession* operator-> () =0;
66 
67  virtual void reset () =0;
68  virtual ~TSessManager() { };
69  };
70 
71 
72 
73 
74  /* === Service level API === */ //----------------internal-API-definition-headers
75 
77  {
78  virtual ~InternalAPI_1() {}
79  virtual uint getMagic() =0;
80 
81  static InternalAPI_1& access();
82  };
83 
85  {
86  static void invokeImplementationService();
87  };
88 
89 
90 
91  /* === Implementation level === */ //----------------corresponding-to-session-impl.hpp
92 
94  {
95  static uint magic_;
96 
97  /* ==== Session API ==== */
98  void externalOperation() ;
99 
100  /* ==== Implementation level API ==== */
101  void implementationService() ;
102 
103  /* ==== internals ==== */
104 
105  TSessionImpl();
106  operator string() const;
107  };
108 
109 
110 
111  template<class API, class IMPL>
113 
114  template<class IMPL>
116  : IMPL
117  , InternalAPI_1
118  {
119  uint
120  getMagic ()
121  {
122  return IMPL::magic_;
123  }
124  };
125 
126  template<class IMPL>
128  : IMPL
129  {
130  void
131  forwardServiceInvocation()
132  {
133  IMPL::implementationService();
134  }
135  };
136 
137  template< typename IMPS
138  , class FRONT
139  , class SESS
140  >
142  : public InstantiateChained<typename IMPS::List, TServiceAccessPoint, SESS>
143  {
144  public:
145 
146  static FRONT& current;
147 
148  template<class API>
149  API&
150  get()
151  {
152  return *this;
153  }
154  };
155 
156 
157 
158 
159 
160  /* === storage and basic session manager configuration === */
161 
162  struct TSessManagerImpl;
163 
166  , TSessionImpl
167  > SessionImplAPI;
168 
169 
170 
171  struct TSessManagerImpl : TSessManager
172  {
173  unique_ptr<SessionImplAPI> pImpl_;
174 
175  TSessManagerImpl()
176  : pImpl_{}
177  { }
178 
179  SessionImplAPI*
180  operator-> ()
181  {
182  if (!pImpl_)
183  this->reset();
184  return pImpl_.get();
185  }
186 
187 
188  /* ==== Manager API ==== */
189  void
190  reset ()
191  {
192  unique_ptr<SessionImplAPI> tmpS {new SessionImplAPI};
193  pImpl_.swap (tmpS);
194  }
195  };
196 
197 
198  uint TSessionImpl::magic_;
199 
200  TSessManager& TSession::current = Depend<TSessManagerImpl>()();
201  //note: already during static initialisation
202 
203  template<>
204  TSessManagerImpl& SessionImplAPI::current = static_cast<TSessManagerImpl&> (TSession::current);
205 
206 
207 
208 
209 
210 
211 
212 
213  /* === Implementation of service access === */ //----------------corresponding-to-session-services.cpp
214 
216  InternalAPI_1::access()
217  {
218  return SessionImplAPI::current->get<InternalAPI_1>();
219  }
220 
221  void
222  InternalAPI_2::invokeImplementationService()
223  {
224  SessionImplAPI::current->forwardServiceInvocation();
225  }
226 
227 
228 
229 
230 
231  /* === Implementation of Session internals === */ //----------------corresponding-to-session-impl.cpp
232 
233  TSessionImpl::operator string() const
234  {
235  return string("Session-Impl(")
236  + lexical_cast<string>(magic_)
237  + ")";
238  }
239 
240  TSessionImpl::TSessionImpl()
241  {
242  ++magic_;
243  cout << "creating new Session " << magic_ << endl;
244  }
245 
246  void
247  TSessionImpl::externalOperation()
248  {
249  cout << this << "::externalOperation()" << endl;
250  }
251 
252  /* ==== Implementation level API ==== */
253  inline void
254  TSessionImpl::implementationService()
255  {
256  cout << this << "::implementationService()" << endl;
257  }
258 
259 
260  } // (END) simulated session management
261 
262 
263 
264 
265 
266 
267 
268 
269 
270 
271  /***************************************************************************/
281  class SessionServiceAccess_test : public Test
282  {
283  virtual void
284  run (Arg)
285  {
286  access_defaultSession();
287  make_newSession();
288  invoke_implServices();
289  }
290 
291 
296  void
298  {
299  cout << "Session not yet used...." << endl;
300  TSession::current->externalOperation();
301  }
302 
303 
308  void
310  {
311  TSession::current.reset();
312  TSession::current->externalOperation();
313  }
314 
315 
318  uint magic() { return InternalAPI_1::access().getMagic(); }
319 
321  void
323  {
324  cout << "current Session-Impl-ID = " << magic() << endl;
325  InternalAPI_2::invokeImplementationService();
326 
327  cout << "now resetting this session." << endl;
328  TSession::current.reset();
329 
330  InternalAPI_2::invokeImplementationService(); // invocation creates new session as side effect
331  cout << "current Session-Impl-ID = " << magic() << endl;
332  }
333  };
334 
335 
337  LAUNCHER (SessionServiceAccess_test, "function session");
338 
339 
340 
341 }}}} // 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:40
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:65
Access point to singletons and other kinds of dependencies designated by type.
Definition: depend.hpp:280
session::SessManager & PSess
acts as a "PImpl" smart ptr
Definition: session.hpp:73
Simplistic 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:120
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.