diff options
-rw-r--r-- | icetray/dryice/dryice.h | 11 | ||||
-rw-r--r-- | icetray/icetray/icecube.cpp | 5 | ||||
-rw-r--r-- | icetray/icetray/icecube.h | 62 | ||||
-rw-r--r-- | icetray/icetray/icetrayService.h | 2 | ||||
-rw-r--r-- | icetray/unittests/testIceTray.cpp | 17 | ||||
-rw-r--r-- | icetray/unittests/testIceTrayReplace.cpp | 1 | ||||
-rw-r--r-- | icetray/unittests/testIceTrayService.ice | 5 | ||||
-rw-r--r-- | icetray/unittests/testIceTrayServiceI.cpp | 13 | ||||
-rw-r--r-- | icetray/unittests/testIceTrayServiceI.h | 6 |
9 files changed, 120 insertions, 2 deletions
diff --git a/icetray/dryice/dryice.h b/icetray/dryice/dryice.h index a934efa..237c31f 100644 --- a/icetray/dryice/dryice.h +++ b/icetray/dryice/dryice.h @@ -5,9 +5,10 @@ #include <IceBox/IceBox.h> #include <visibility.h> #include "icetrayService.h" +#include "icecube.h" namespace IceTray { - class DLL_PUBLIC DryIce { + class DLL_PUBLIC DryIce : private Cube { public: DryIce(const Ice::StringSeq & = Ice::StringSeq()); DryIce(const DryIce &) = delete; @@ -22,6 +23,14 @@ namespace IceTray { void replace(const std::string &, const Ice::ObjectPtr &); + template<typename T, typename I, typename ... Args> + static auto replace(const Args & ... args) + { + pm()->remove<CubePlugIn>(typeid(T).name()); + return add<T, I>(args...); + } + + Ice::CommunicatorPtr ic; IceTray::ServicePtr s; }; diff --git a/icetray/icetray/icecube.cpp b/icetray/icetray/icecube.cpp new file mode 100644 index 0000000..2908c16 --- /dev/null +++ b/icetray/icetray/icecube.cpp @@ -0,0 +1,5 @@ +#include "icecube.h" +#include <plugins.impl.h> + +INSTANTIATEPLUGINOF(IceTray::CubePlugIn); + diff --git a/icetray/icetray/icecube.h b/icetray/icetray/icecube.h new file mode 100644 index 0000000..f2a3454 --- /dev/null +++ b/icetray/icetray/icecube.h @@ -0,0 +1,62 @@ +#ifndef ICETRAY_ICECUBE_H +#define ICETRAY_ICECUBE_H + +#include <plugins.h> +#include <Ice/ObjectAdapter.h> +#include <Ice/Initialize.h> +#include "icetrayService.h" + +namespace IceTray { + class CubePlugIn : public AdHoc::AbstractPluginImplementation { }; + + template<typename I> + class CubePlugInOf : public CubePlugIn, public I { + using I::I; + }; + + class CubeObject : public CubePlugIn { + public: + explicit inline CubeObject(Ice::ObjectPrxPtr o) : obj(std::move(o)) { } + Ice::ObjectPrxPtr obj; + }; + + class Cube { + protected: + static inline auto pm() { return &Service::getCurrent()->servicePlugins; } + + public: + template<typename T, typename I, typename ... Args> + static auto addObject(const Ice::ObjectAdapterPtr & adp, const std::string & name, const Args & ... args) + { + static_assert(std::is_convertible<I *, T *>::value); + static_assert(std::is_convertible<I *, Ice::Object *>::value); + auto prx = adp->add(std::make_shared<I>(args...), Ice::stringToIdentity(name)); + return pm()->add<CubePlugIn>(std::make_shared<CubeObject>(prx), + typeid(typename T::ProxyType).name(), __FILE__, __LINE__); + } + + template<typename T, typename I, typename ... Args> + static auto add(const Args & ... args) + { + static_assert(std::is_convertible<CubePlugInOf<I> *, T *>::value); + return pm()->add<CubePlugIn>(std::make_shared<CubePlugInOf<I>>(args...), typeid(T).name(), __FILE__, __LINE__); + } + + template<typename T> + static auto get() + { + if constexpr (std::is_convertible<T *, Ice::Object *>::value) { + using Prx = typename T::ProxyType; + auto c = pm()->getImplementation<CubePlugIn>(typeid(Prx).name()); + return Ice::uncheckedCast<Prx>(std::dynamic_pointer_cast<CubeObject>(c)->obj); + } + else { + auto c = pm()->getImplementation<CubePlugIn>(typeid(T).name()); + return std::dynamic_pointer_cast<T>(c); + } + } + }; +} + +#endif + diff --git a/icetray/icetray/icetrayService.h b/icetray/icetray/icetrayService.h index 6ea6a77..6c48a71 100644 --- a/icetray/icetray/icetrayService.h +++ b/icetray/icetray/icetrayService.h @@ -30,10 +30,12 @@ namespace IceTray { void shutdownLoggers(); friend class DryIce; + friend class Cube; Ice::ObjectAdapterPtr adp; static Service * current; std::set<Logging::LogWriterPrxPtr> logWriters; OptionsCollation optionsCollation; + AdHoc::PluginManager servicePlugins; }; typedef std::shared_ptr<Service> ServicePtr; diff --git a/icetray/unittests/testIceTray.cpp b/icetray/unittests/testIceTray.cpp index d5cda0b..307d0d7 100644 --- a/icetray/unittests/testIceTray.cpp +++ b/icetray/unittests/testIceTray.cpp @@ -43,6 +43,23 @@ BOOST_AUTO_TEST_CASE( services ) p->method2(1, "test"); } +BOOST_AUTO_TEST_CASE( cube_services_proxy ) +{ + auto prx = IceTray::Cube::get<TestIceTray::TestIceTrayService>(); + BOOST_REQUIRE(prx); + prx->ice_ping(); + prx->method1(); + prx->method2(1, "test"); +} + +BOOST_AUTO_TEST_CASE( cube_services_local ) +{ + auto ptr = IceTray::Cube::get<TestIceTray::TestCube>(); + BOOST_REQUIRE(ptr); + ptr->method1(); + ptr->method2(1, "test"); +} + BOOST_AUTO_TEST_CASE( getIceComponents ) { BOOST_REQUIRE(getService()); diff --git a/icetray/unittests/testIceTrayReplace.cpp b/icetray/unittests/testIceTrayReplace.cpp index 1558326..ac176b4 100644 --- a/icetray/unittests/testIceTrayReplace.cpp +++ b/icetray/unittests/testIceTrayReplace.cpp @@ -21,6 +21,7 @@ class Service : public IceTray::DryIce { Service() { replace("test", std::make_shared<TestIceTray::DummyTestIceTrayServiceI>()); + replace<TestIceTray::TestCube, TestIceTray::TestCubeI>(); } }; diff --git a/icetray/unittests/testIceTrayService.ice b/icetray/unittests/testIceTrayService.ice index e0a3dad..fc0caf4 100644 --- a/icetray/unittests/testIceTrayService.ice +++ b/icetray/unittests/testIceTrayService.ice @@ -3,5 +3,10 @@ module TestIceTray { void method1(); void method2(int id, string name); }; + + local interface TestCube { + void method1(); + void method2(int id, string name); + }; }; diff --git a/icetray/unittests/testIceTrayServiceI.cpp b/icetray/unittests/testIceTrayServiceI.cpp index 09c2ac6..33cdde4 100644 --- a/icetray/unittests/testIceTrayServiceI.cpp +++ b/icetray/unittests/testIceTrayServiceI.cpp @@ -8,6 +8,7 @@ #include <subdir/some.sql.h> #include <subdir/a/more.sql.h> #include <boost/test/test_tools.hpp> +#include "icecube.h" class Foo { }; @@ -66,9 +67,19 @@ namespace TestIceTray { BOOST_VERIFY((fetchCache<int>(sql::testIceTrayServiceTestSql, 10, id, name)) == (fetchCache<int>(sql::testIceTrayServiceTestSql, 10, id, name))); } + void TestCubeI::method1() + { + } + + void TestCubeI::method2(Ice::Int, const std::string &) + { + } + void TestService::addObjects(const std::string &, const Ice::CommunicatorPtr & ic, const Ice::StringSeq &, const Ice::ObjectAdapterPtr & adp) { - adp->add(std::make_shared<TestIceTray::TestIceTrayServiceI>(getConnectionPool(ic, "postgresql", "icetraydb")), Ice::stringToIdentity("test")); + IceTray::Cube::addObject<TestIceTray::TestIceTrayService, TestIceTray::TestIceTrayServiceI>( + adp, "test", getConnectionPool(ic, "postgresql", "icetraydb")); + IceTray::Cube::add<TestIceTray::TestCube, TestIceTray::TestCubeI>(); } NAMEDFACTORY("default", TestService, IceTray::ServiceFactory); diff --git a/icetray/unittests/testIceTrayServiceI.h b/icetray/unittests/testIceTrayServiceI.h index d300668..ef2f3a6 100644 --- a/icetray/unittests/testIceTrayServiceI.h +++ b/icetray/unittests/testIceTrayServiceI.h @@ -21,6 +21,12 @@ namespace TestIceTray { public: void addObjects(const std::string &, const Ice::CommunicatorPtr &, const Ice::StringSeq &, const Ice::ObjectAdapterPtr &) override; }; + + class TestCubeI : public TestCube { + public: + void method1() override; + void method2(Ice::Int id, const std::string & name) override; + }; } #endif |