#include <functional>
#include <boost/config.hpp>
-#include <boost/any.hpp>
#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <boost/preprocessor.hpp>
#include <client.hxx>
#include <command_client.hxx>
-#ifndef T2NWRAPPER_MAX_ARGS
-#define T2NWRAPPER_MAX_ARGS 9
+#ifndef T2N_SINGLETON_WRAPPER_MAX_ARGS
+#define T2N_SINGLETON_WRAPPER_MAX_ARGS 9
#endif
namespace libt2n
{
-class ConnectionInitData
+class ConnectionWrapper
{
- public:
+ private:
+ long long command_timeout_usec;
+ long long hello_timeout_usec;
- virtual std::auto_ptr<client_connection> createConnection()=0;
+ protected:
+ log_level_values log_level;
+ std::ostream *logstream;
+ void set_logging_on_connection(client_connection& c);
- virtual ~ConnectionInitData()
+ public:
+ ConnectionWrapper()
+ : log_level(none), logstream(NULL),
+ command_timeout_usec(command_client::command_timeout_usec_default),
+ hello_timeout_usec(command_client::hello_timeout_usec_default)
{ }
-};
-class TrivialHandler
-{
- public:
- static void handle( boost::function< void() > f)
+ virtual ~ConnectionWrapper()
+ { }
+
+ virtual client_connection* get_connection()=0;
+
+ virtual void handle(command_client* stubBase, boost::function< void() > f)
{
f();
}
+
+ long long get_command_timeout_usec(void)
+ { return command_timeout_usec; }
+
+ void set_command_timeout_usec(long long _command_timeout_usec)
+ { command_timeout_usec=_command_timeout_usec; }
+
+ long long get_hello_timeout_usec(void)
+ { return hello_timeout_usec; }
+
+ void set_hello_timeout_usec(long long _hello_timeout_usec)
+ { hello_timeout_usec=_hello_timeout_usec; }
+
+ void set_logging(std::ostream *_logstream, log_level_values _log_level);
+
+ std::ostream* get_logstream(log_level_values level);
};
// contains the internal stuff needed for T2nWrapper
};
} // eo namespace detail
-template<
- class Client,
- class Handler = TrivialHandler
->
-class T2nWrapper
+class T2nSingletonWrapperMessages
{
- private:
+ protected:
+ static const char* NotInitializedMessage;
+};
- std::auto_ptr<client_connection> conndConn;
- std::auto_ptr<Client> client;
+template< class Client >
+class T2nSingletonWrapper : public T2nSingletonWrapperMessages
+{
+ private:
+ std::auto_ptr<Client> Stub;
- static std::auto_ptr<T2nWrapper> singletonObject;
- static std::auto_ptr<ConnectionInitData> initData;
+ static std::auto_ptr<T2nSingletonWrapper> SingletonObject;
+ static std::auto_ptr<ConnectionWrapper> WrappedConnection;
// create a prep-method for each possible number of parameters
#define _GEN_ARG(z,n,d) Arg ## n arg ##n
); \
} // eo prep
- BOOST_PP_REPEAT( BOOST_PP_ADD(T2NWRAPPER_MAX_ARGS,1) , _GEN_PREP, ~ )
+ BOOST_PP_REPEAT( BOOST_PP_ADD(T2N_SINGLETON_WRAPPER_MAX_ARGS,1) , _GEN_PREP, ~ )
#undef _GEN_PREP
#undef _GEN_ARG
- static void ensureSingletonThere(void)
+ T2nSingletonWrapper(std::auto_ptr<Client> stub)
{
- if (singletonObject.get() == NULL)
- {
- // we need to initialize
+ Stub=stub;
+ }
- if (initData.get() == NULL)
- throw std::logic_error("T2nWrapper singleton used before setting initData");
+ static void init()
+ {
+ if (WrappedConnection.get() == NULL)
+ throw std::logic_error(NotInitializedMessage);
- std::auto_ptr<client_connection> myConndConn=initData->createConnection();
+ std::auto_ptr<Client> stub(new Client(*(WrappedConnection->get_connection()),
+ WrappedConnection->get_command_timeout_usec(),
+ WrappedConnection->get_hello_timeout_usec()));
- }
+ SingletonObject=std::auto_ptr<T2nSingletonWrapper>(new T2nSingletonWrapper(stub));
}
template< typename R >
static
typename detail::TypeWrap<R>::type real_exec( boost::function< R(Client*) > f)
{
- ensureSingletonThere();
+ ensure_singleton_there();
typename detail::TypeWrap<R>::type result;
- detail::Call<R> call( boost::bind( f, &(*(singletonObject->client))), result );
- Handler::handle( call );
+ detail::Call<R> call( boost::bind( f, SingletonObject->Stub.get()), result );
+ WrappedConnection->handle(SingletonObject->Stub.get(),call);
return result;
}
public:
- static void setInitData(std::auto_ptr<ConnectionInitData> newInitData)
- { initData=newInitData; }
- static ConnectionInitData* getInitData(void)
- { return initData.get(); }
+ static void set_connection(std::auto_ptr<ConnectionWrapper> wrappedConnection)
+ {
+ WrappedConnection=wrappedConnection;
- T2nWrapper()
+ // reset the singleton to NULL because the singleton must be constructed with current WrappedConnection
+ if (SingletonObject.get() != NULL)
+ SingletonObject.reset();
+ }
+ static ConnectionWrapper* get_connection_wrapper(void)
+ { return WrappedConnection.get(); }
+
+ static void ensure_singleton_there(void)
{
- client=std::auto_ptr<Client>(new Client(*conndConn));
+ if (SingletonObject.get() == NULL)
+ init();
}
// create an exec-method for each possible number of parameters
{ \
boost::function<R(Client*)>(*p)(R(Client::*)( BOOST_PP_ENUM_PARAMS(n,Arg) ) \
BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n,Arg)) \
- = &T2nWrapper::template prep<R BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n,Arg) >; \
+ = &T2nSingletonWrapper::template prep<R BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n,Arg) >; \
return boost::bind \
( \
- T2nWrapper::template real_exec<R>, \
+ T2nSingletonWrapper::template real_exec<R>, \
boost::bind( p, f BOOST_PP_COMMA_IF(n) \
BOOST_PP_ENUM(n, _GEN_PLACEHOLDER, ~ ) ) \
); \
} // eo exec
- BOOST_PP_REPEAT( BOOST_PP_ADD(T2NWRAPPER_MAX_ARGS,1), _GEN_EXEC, ~ )
+ BOOST_PP_REPEAT( BOOST_PP_ADD(T2N_SINGLETON_WRAPPER_MAX_ARGS,1), _GEN_EXEC, ~ )
#undef _GEN_EXEC
#undef _GEN_PLACEHOLDER
};
+// create an t2n_exec-method for each possible number of parameters
+#define _GEN_EXEC(z,n,d) \
+ template< class Client, typename R BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n,typename Arg) > \
+ static boost::function< R( BOOST_PP_ENUM_PARAMS(n,Arg) ) > t2n_exec \
+ ( \
+ R(Client::*f)( BOOST_PP_ENUM_PARAMS(n,Arg) ) \
+ ) \
+ { \
+ return T2nSingletonWrapper<Client>::exec(f); \
+ } // eo exec
+
+ BOOST_PP_REPEAT( BOOST_PP_ADD(T2N_SINGLETON_WRAPPER_MAX_ARGS,1), _GEN_EXEC, ~ )
+
+#undef _GEN_EXEC
+#undef _GEN_PLACEHOLDER
+
}
#endif