/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // GENERATED CODE - do not edit (Generated by ddkit/genModelApi) // /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // RecordingCtrl.hpp (rmodel-api) #ifndef RecordingCtrl_API #define RecordingCtrl_API #include #include #include #include #include #include #include #include #include #include #include #include #include namespace ddkit { namespace actors { class IActor; typedef std::shared_ptr ActorPtr; typedef std::weak_ptr ActorWeakPtr; } // namespace actors } // namespace ddkit namespace M_RecordingCtrl { class TMSIF_EXPORT IServiceFactory { public: typedef M_RecordingCtrl::IService InterfaceType; /// @brief Creates a sender for writing to an IService TMSIF_DEPRECATED static IService* create(std::string const& serviceName, int domain); /// @brief Deletes the sender received from create() /// - the sender must not be used any more afterwards (undefined behaviour) TMSIF_DEPRECATED static void remove(M_RecordingCtrl::IService* sender); /// @brief deletes all senders received from create() /// - if create() was called only once, this is equivalent to remove() TMSIF_DEPRECATED static void shutdown(); TMSIF_DEPRECATED static IService* create(std::string const& serviceName); /// @brief calling create with clientName [IServiceFactory only] /// - clientName is the former clientId, which had problems: /// - Ids of user-space are conceptually mixed with internal ids to distinguish actors. /// - you may use this signature and give clientName. /// - it will not be used internally for "ID"entifiying your client, hence the name 'clientName' /// - you will get the clientName instead of its actorId, when calling getSource() during callbacks on service. /// - if used here (IServiceFactory::create) and in IClientObsFactory::add, you must give the same clientName! /// - it is theoretically possible, that the service will read "unknown" instead of your clientName on samples /// sent very early after creation of actor. TMSIF_DEPRECATED static IService* create(std::string const& serviceName, int domain, std::string const& clientName); }; class TMSIF_EXPORT IServiceObsFactory { public: typedef std::vector StringSet; typedef M_RecordingCtrl::IService InterfaceType; /// @brief Register an observer for getting IService-callbacks on it template TMSIF_DEPRECATED static void add(std::string const& serviceName, IServiceDerived* obs, int domain); TMSIF_DEPRECATED static void addFiltered(std::string const& serviceName, M_RecordingCtrl::IService* obs, std::string const& ignoredOps); /// @brief Register manually an observer for getting IService-callbacks on it /// - semicolon-separated std::string-list of not-to-override-methods /// - unclear logic about derived ifaces, error-prone-syntax, better do not use /// - logically deprecated, better use add() or new oo-API instead TMSIF_DEPRECATED static void addFiltered(std::string const& serviceName, M_RecordingCtrl::IService* obs, std::string const& ignoredOps, int domain); /// @brief Unregister observer previously registered with add...() TMSIF_DEPRECATED static void removeObs(M_RecordingCtrl::IService* observer); /// @brief - deprecated: on call a warning is issued, but function still works: serviceName is ignored. /// - you must use add/remove 'normally' (one registration per observer), so better call removeObs(1 param) above! TMSIF_DEPRECATED static void remove(std::string const& serviceName, M_RecordingCtrl::IService* observer); /// @brief unregisters all observers previously registered with add...() /// - if add() called only once, this is equivalent to removeObs() TMSIF_DEPRECATED static void shutdown(); /// @brief Use the new Api `ddkit::actors::CallbackInfo::current()` instead. /// Call this method only from inside a callback. TMSIF_DEPRECATED static std::string getSource(); IServiceObsFactory() {} private: static void addCustom(M_RecordingCtrl::IService* obs, StringSet custom, std::string serviceName, int domain); static void addCustom(M_RecordingCtrl::IService* obs, StringSet custom, std::string serviceName, int domain, std::string clientName); // only used on client! }; class IClient; typedef std::shared_ptr IClientPtr; /// @brief new oo-api class TMSIF_EXPORT Service { public: typedef M_RecordingCtrl::IService InterfaceTypeReceiver; typedef M_RecordingCtrl::IClient InterfaceTypeSender; #ifndef SWIG /// @brief Create dds-readers + writers. remove on Service leaving scope (overridden methods are auto-detected), template static typename std::enable_if< std::is_same::value && std::is_same >::value, Service>::type create(T domain, std::string serviceName, IServiceDerived& callbacks); /// @brief Create dds-readers + writers. remove on Service leaving scope (overridden methods are auto-detected) template static typename std::enable_if< std::is_same::value && !std::is_same >::value, Service>::type create(T domain, std::string serviceName, IServiceDerived& callbacks); /// @brief Create dds-readers + writers. remove on Service leaving scope (overridden methods are auto-detected) template static typename std::enable_if< std::is_same>::value && std::is_same >::value, Service>::type create(T session, std::string serviceName, IServiceDerived& callbacks); /// @brief Create dds-readers + writers. remove on Service leaving scope (overridden methods are auto-detected) template static typename std::enable_if< std::is_same>::value && !std::is_same >::value, Service>::type create(T session, std::string serviceName, IServiceDerived& callbacks); static Service createWriteOnly(int domain, std::string serviceName); static Service createWriteOnly(std::shared_ptr session, std::string serviceName); #endif /// @brief call operations on matching Clients IClientPtr operator->(); Service& operator=(Service&& other); void invalidate(); #ifndef SWIG /// @brief (only for monitors: Listener, Inspector / resulting services are read-only!) template static typename std::enable_if< std::is_same::value && std::is_same >::value, Service>::type createMonitor(T domain, std::string serviceName, IServiceDerived& callbacks); /// @brief (only for monitors: Listener, Inspector / resulting services are read-only!) template static typename std::enable_if< std::is_same::value && !std::is_same >::value, Service>::type createMonitor(T domain, std::string serviceName, IServiceDerived& callbacks); /// @brief (only for monitors: Listener, Inspector / resulting services are read-only!) template static typename std::enable_if< std::is_same>::value && std::is_same >::value, Service>::type createMonitor(T monitorSession, std::string serviceName, IServiceDerived& callbacks); /// @brief (only for monitors: Listener, Inspector / resulting services are read-only!) template static typename std::enable_if< std::is_same>::value && !std::is_same >::value, Service>::type createMonitor(T monitorSession, std::string serviceName, IServiceDerived& callbacks); // MULTIPLEX /// @brief Reading all serviceNames. template static typename std::enable_if< std::is_same::value && std::is_same >::value, Service>::type createMonitor(T domain, IServiceDerived& callbacks); /// @brief Reading all serviceNames. template static typename std::enable_if< std::is_same::value && !std::is_same >::value, Service>::type createMonitor(T domain, IServiceDerived& callbacks); /// @brief Reading all serviceNames. template static typename std::enable_if >::value && std::is_same >::value, Service>::type createMonitor(T monitorSession, IServiceDerived& callbacks); /// @brief Reading all serviceNames. template static typename std::enable_if< std::is_same>::value && !std::is_same >::value, Service>::type createMonitor(T monitorSession, IServiceDerived& callbacks); #endif /// @brief true, if dds-able (false, if default-constructed or Session destructed) bool isValid() const; /// @brief Construct an invalid service-obj /// (sometimes needed for beeing data-member, prefer create() instead) Service(); Service(Service&& other); Service(const Service& other) = default; ~Service(); std::shared_ptr getSession(); std::shared_ptr getMonitorSession(); // SWIG Wrapper only static Service* _internalSwigCreateWriteOnly(int domain, std::string serviceName); static Service* _internalSwigCreateWriteOnly(std::shared_ptr session, std::string serviceName); static Service* _internalSwigCreate(int domain, std::string serviceName, IService& callbacks); static Service* _internalSwigCreateMonitor(int domain, std::string serviceName, IService& callbacks); static Service* _internalSwigCreateMonitor(int domain, IService& callbacks); // reading all serviceNames! static Service* _internalSwigCreate(std::shared_ptr session, std::string serviceName, IService& callbacks); static Service* _internalSwigCreateMonitor(std::shared_ptr session, std::string serviceName, IService& callbacks); static Service* _internalSwigCreateMonitor(std::shared_ptr session, IService& callbacks); // reading all serviceNames! private: #ifdef _WIN32 #pragma warning(disable:4251) // MSVC would warn about shared/export/dll-inline-stuff here #endif ddkit::actors::ActorWeakPtr m_actor; bool m_discardSenderOnDestruction; bool m_discardObserverOnDestruction; std::shared_ptr m_session; std::shared_ptr m_monitorSession; #ifdef _WIN32 #pragma warning(default:4251) #endif ddkit::actors::IActor& actor(); Service(ddkit::actors::ActorPtr actor, bool discardSenderOnDestruction, bool discardObserverOnDestruction, std::shared_ptr session, std::shared_ptr monitorSession); static bool isCheckMostDerivedClassType(ddkit::actors::Session& session); static bool isCheckMostDerivedClassType(ddkit::actors::MonitorSession& monitorSession); static Service createCustom(std::shared_ptr session, std::string serviceName, IService& callbacks, std::vector methods); static Service createCustomReadOnly(std::shared_ptr monitorSession, std::string serviceName, IService& callbacks, std::vector methods); static Service createCustomReadOnlyMultiplex(std::shared_ptr monitorSession, IService& callbacks, std::vector methods); static Service createCustom(std::shared_ptr session, std::string serviceName, std::map> callbacks, std::vector methods); static Service createCustomReadOnly(std::shared_ptr monitorSession, std::string serviceName, std::map> callbacks, std::vector methods); static Service createCustomReadOnlyMultiplex(std::shared_ptr monitorSession, std::map> callbacks, std::vector methods); }; class TMSIF_EXPORT IClientFactory { public: typedef M_RecordingCtrl::IClient InterfaceType; /// @brief Creates a sender for writing to an IClient TMSIF_DEPRECATED static IClient* create(std::string const& serviceName, int domain); /// @brief Deletes the sender received from create() /// - the sender must not be used any more afterwards (undefined behaviour) TMSIF_DEPRECATED static void remove(M_RecordingCtrl::IClient* sender); /// @brief deletes all senders received from create() /// - if create() was called only once, this is equivalent to remove() TMSIF_DEPRECATED static void shutdown(); TMSIF_DEPRECATED static IClient* create(std::string const& serviceName); }; class TMSIF_EXPORT IClientObsFactory { public: typedef std::vector StringSet; typedef M_RecordingCtrl::IClient InterfaceType; /// @brief Register an observer for getting IClient-callbacks on it template TMSIF_DEPRECATED static void add(std::string const& serviceName, IClientDerived* obs, int domain); TMSIF_DEPRECATED static void addFiltered(std::string const& serviceName, M_RecordingCtrl::IClient* obs, std::string const& ignoredOps); /// @brief Register manually an observer for getting IClient-callbacks on it /// - semicolon-separated std::string-list of not-to-override-methods /// - unclear logic about derived ifaces, error-prone-syntax, better do not use /// - logically deprecated, better use add() or new oo-API instead TMSIF_DEPRECATED static void addFiltered(std::string const& serviceName, M_RecordingCtrl::IClient* obs, std::string const& ignoredOps, int domain); /// @brief Unregister observer previously registered with add...() TMSIF_DEPRECATED static void removeObs(M_RecordingCtrl::IClient* observer); /// @brief - deprecated: on call a warning is issued, but function still works: serviceName is ignored. /// - you must use add/remove 'normally' (one registration per observer), so better call removeObs(1 param) above! TMSIF_DEPRECATED static void remove(std::string const& serviceName, M_RecordingCtrl::IClient* observer); /// @brief unregisters all observers previously registered with add...() /// - if add() called only once, this is equivalent to removeObs() TMSIF_DEPRECATED static void shutdown(); /// @brief Use the new Api `ddkit::actors::CallbackInfo::current()` instead. /// Call this method only from inside a callback. TMSIF_DEPRECATED static std::string getSource(); IClientObsFactory() {} /// @brief Calling add with clientName [IClientObsFactory only] template TMSIF_DEPRECATED static void add(std::string const& serviceName, IClientDerived* obs, int domain, std::string const& clientName); /// @brief calling addFiltered with clientName [IClientObsFactory only] /// - clientName is the former clientId - see also IServiceFactory::create(...clientName) TMSIF_DEPRECATED static void addFiltered(std::string const& serviceName, M_RecordingCtrl::IClient* obs, std::string const& ignoredOps, int domain, std::string const& clientName); private: static void addCustom(M_RecordingCtrl::IClient* obs, StringSet custom, std::string serviceName, int domain); static void addCustom(M_RecordingCtrl::IClient* obs, StringSet custom, std::string serviceName, int domain, std::string clientName); // only used on client! }; class IService; typedef std::shared_ptr IServicePtr; /// @brief new oo-api class TMSIF_EXPORT Client { public: typedef M_RecordingCtrl::IClient InterfaceTypeReceiver; typedef M_RecordingCtrl::IService InterfaceTypeSender; #ifndef SWIG /// @brief Create dds-readers + writers. remove on Client leaving scope (overridden methods are auto-detected), template static typename std::enable_if< std::is_same::value && std::is_same >::value, Client>::type create(T domain, std::string serviceName, IClientDerived& callbacks); /// @brief Create dds-readers + writers. remove on Client leaving scope (overridden methods are auto-detected) template static typename std::enable_if< std::is_same::value && !std::is_same >::value, Client>::type create(T domain, std::string serviceName, IClientDerived& callbacks); /// @brief Create dds-readers + writers. remove on Client leaving scope (overridden methods are auto-detected) template static typename std::enable_if< std::is_same>::value && std::is_same >::value, Client>::type create(T session, std::string serviceName, IClientDerived& callbacks); /// @brief Create dds-readers + writers. remove on Client leaving scope (overridden methods are auto-detected) template static typename std::enable_if< std::is_same>::value && !std::is_same >::value, Client>::type create(T session, std::string serviceName, IClientDerived& callbacks); static Client createWriteOnly(int domain, std::string serviceName); static Client createWriteOnly(std::shared_ptr session, std::string serviceName); #endif /// @brief set client-display-name (former 'clientId') void setName(std::string clientName); /// @brief call operations on matching Services IServicePtr operator->(); Client& operator=(Client&& other); void invalidate(); /// @brief block, until the corresponding service appears. void waitUntilConnected(); #ifndef SWIG /// @brief (only for monitors: Listener, Inspector / resulting clients are read-only!) template static typename std::enable_if< std::is_same::value && std::is_same >::value, Client>::type createMonitor(T domain, std::string serviceName, IClientDerived& callbacks); /// @brief (only for monitors: Listener, Inspector / resulting clients are read-only!) template static typename std::enable_if< std::is_same::value && !std::is_same >::value, Client>::type createMonitor(T domain, std::string serviceName, IClientDerived& callbacks); /// @brief (only for monitors: Listener, Inspector / resulting clients are read-only!) template static typename std::enable_if< std::is_same>::value && std::is_same >::value, Client>::type createMonitor(T monitorSession, std::string serviceName, IClientDerived& callbacks); /// @brief (only for monitors: Listener, Inspector / resulting clients are read-only!) template static typename std::enable_if< std::is_same>::value && !std::is_same >::value, Client>::type createMonitor(T monitorSession, std::string serviceName, IClientDerived& callbacks); // MULTIPLEX /// @brief Reading all serviceNames. template static typename std::enable_if< std::is_same::value && std::is_same >::value, Client>::type createMonitor(T domain, IClientDerived& callbacks); /// @brief Reading all serviceNames. template static typename std::enable_if< std::is_same::value && !std::is_same >::value, Client>::type createMonitor(T domain, IClientDerived& callbacks); /// @brief Reading all serviceNames. template static typename std::enable_if >::value && std::is_same >::value, Client>::type createMonitor(T monitorSession, IClientDerived& callbacks); /// @brief Reading all serviceNames. template static typename std::enable_if< std::is_same>::value && !std::is_same >::value, Client>::type createMonitor(T monitorSession, IClientDerived& callbacks); #endif /// @brief true, if dds-able (false, if default-constructed or Session destructed) bool isValid() const; /// @brief Construct an invalid client-obj /// (sometimes needed for beeing data-member, prefer create() instead) Client(); Client(Client&& other); Client(const Client& other) = default; ~Client(); std::shared_ptr getSession(); std::shared_ptr getMonitorSession(); // SWIG Wrapper only static Client* _internalSwigCreateWriteOnly(int domain, std::string serviceName); static Client* _internalSwigCreateWriteOnly(std::shared_ptr session, std::string serviceName); static Client* _internalSwigCreate(int domain, std::string serviceName, IClient& callbacks); static Client* _internalSwigCreateMonitor(int domain, std::string serviceName, IClient& callbacks); static Client* _internalSwigCreateMonitor(int domain, IClient& callbacks); // reading all serviceNames! static Client* _internalSwigCreate(std::shared_ptr session, std::string serviceName, IClient& callbacks); static Client* _internalSwigCreateMonitor(std::shared_ptr session, std::string serviceName, IClient& callbacks); static Client* _internalSwigCreateMonitor(std::shared_ptr session, IClient& callbacks); // reading all serviceNames! private: #ifdef _WIN32 #pragma warning(disable:4251) // MSVC would warn about shared/export/dll-inline-stuff here #endif ddkit::actors::ActorWeakPtr m_actor; bool m_discardSenderOnDestruction; bool m_discardObserverOnDestruction; std::shared_ptr m_session; std::shared_ptr m_monitorSession; #ifdef _WIN32 #pragma warning(default:4251) #endif ddkit::actors::IActor& actor(); Client(ddkit::actors::ActorPtr actor, bool discardSenderOnDestruction, bool discardObserverOnDestruction, std::shared_ptr session, std::shared_ptr monitorSession); static bool isCheckMostDerivedClassType(ddkit::actors::Session& session); static bool isCheckMostDerivedClassType(ddkit::actors::MonitorSession& monitorSession); static Client createCustom(std::shared_ptr session, std::string serviceName, IClient& callbacks, std::vector methods); static Client createCustomReadOnly(std::shared_ptr monitorSession, std::string serviceName, IClient& callbacks, std::vector methods); static Client createCustomReadOnlyMultiplex(std::shared_ptr monitorSession, IClient& callbacks, std::vector methods); static Client createCustom(std::shared_ptr session, std::string serviceName, std::map> callbacks, std::vector methods); static Client createCustomReadOnly(std::shared_ptr monitorSession, std::string serviceName, std::map> callbacks, std::vector methods); static Client createCustomReadOnlyMultiplex(std::shared_ptr monitorSession, std::map> callbacks, std::vector methods); }; #ifndef SWIG template typename std::enable_if>::value, std::map>>::type detectCallbacksIService(IServiceDerived& callbacks) { std::map> methods; for(auto& obj : callbacks) { (void) obj; // classes without callbacks // methods of M_RecordingCtrl::IService { auto cb = dynamic_cast*>(obj); if(cb && cb->isFunction(&M_RecordingCtrl::IService::CmdStartRecording)) { if(!methods.count("CmdStartRecording")) { std::vector c; methods.insert(std::make_pair("CmdStartRecording", c)); } methods["CmdStartRecording"].push_back(obj); continue; } } { auto cb = dynamic_cast*>(obj); if(cb && cb->isFunction(&M_RecordingCtrl::IService::CmdCaptureVideoCutout)) { if(!methods.count("CmdCaptureVideoCutout")) { std::vector c; methods.insert(std::make_pair("CmdCaptureVideoCutout", c)); } methods["CmdCaptureVideoCutout"].push_back(obj); continue; } } { auto cb = dynamic_cast*>(obj); if(cb && cb->isFunction(&M_RecordingCtrl::IService::CmdStopRecording)) { if(!methods.count("CmdStopRecording")) { std::vector c; methods.insert(std::make_pair("CmdStopRecording", c)); } methods["CmdStopRecording"].push_back(obj); continue; } } { auto cb = dynamic_cast*>(obj); if(cb && cb->isFunction(&M_RecordingCtrl::IService::CmdRemoveVideoCutout)) { if(!methods.count("CmdRemoveVideoCutout")) { std::vector c; methods.insert(std::make_pair("CmdRemoveVideoCutout", c)); } methods["CmdRemoveVideoCutout"].push_back(obj); continue; } } { auto cb = dynamic_cast*>(obj); if(cb && cb->isFunction(&M_RecordingCtrl::IService::CmdRemoveAllVideoCutouts)) { if(!methods.count("CmdRemoveAllVideoCutouts")) { std::vector c; methods.insert(std::make_pair("CmdRemoveAllVideoCutouts", c)); } methods["CmdRemoveAllVideoCutouts"].push_back(obj); continue; } } { auto cb = dynamic_cast*>(obj); if(cb && cb->isFunction(&M_RecordingCtrl::IService::CmdCaptureImage)) { if(!methods.count("CmdCaptureImage")) { std::vector c; methods.insert(std::make_pair("CmdCaptureImage", c)); } methods["CmdCaptureImage"].push_back(obj); continue; } } } return methods; } template typename std::enable_if>::value, std::vector>::type detectMethodsIService(IServiceDerived& callbacks, bool isCheckMostDerivedClassType) { std::set methods; for(auto& obj : callbacks) { (void) obj; // classes without callbacks // methods of M_RecordingCtrl::IService { auto cb = dynamic_cast*>(obj); if(cb && cb->isFunction(&M_RecordingCtrl::IService::CmdStartRecording)) { methods.insert("CmdStartRecording"); continue; } } { auto cb = dynamic_cast*>(obj); if(cb && cb->isFunction(&M_RecordingCtrl::IService::CmdCaptureVideoCutout)) { methods.insert("CmdCaptureVideoCutout"); continue; } } { auto cb = dynamic_cast*>(obj); if(cb && cb->isFunction(&M_RecordingCtrl::IService::CmdStopRecording)) { methods.insert("CmdStopRecording"); continue; } } { auto cb = dynamic_cast*>(obj); if(cb && cb->isFunction(&M_RecordingCtrl::IService::CmdRemoveVideoCutout)) { methods.insert("CmdRemoveVideoCutout"); continue; } } { auto cb = dynamic_cast*>(obj); if(cb && cb->isFunction(&M_RecordingCtrl::IService::CmdRemoveAllVideoCutouts)) { methods.insert("CmdRemoveAllVideoCutouts"); continue; } } { auto cb = dynamic_cast*>(obj); if(cb && cb->isFunction(&M_RecordingCtrl::IService::CmdCaptureImage)) { methods.insert("CmdCaptureImage"); continue; } } } std::vector result(methods.begin(), methods.end()); return result; } template typename std::enable_if>::value, std::vector>::type detectMethodsIService(IServiceDerived& callbacks, bool isCheckMostDerivedClassType) { // if user has casted its derived IService* to IService* (implicitly by going through some wrapper-proxy, which // does not make use of a template-parameter, all functions will appear to be not overridden, so the compiler // should cry: static_assert(!std::is_same::value, "\033[00;37m\033[40m" "\n" "\nCannot take your callbacks* while auto-detecting your overridden methods! It" "\nappears to be of type IService* - but must be of derived class of IService* (that" "\nis to say: it must be >your< class)." "\nMost certainly this problem is triggered by you having a wrapper-method around" "\nour add/create-methods and thus unintentionally casting up the callbacks* to" "\nan IService* - a simple solution is to use a template-function as wrapper-method," "\nthereby keeping the type of your callbacks* original, while transferring to us." "\n" "\n(in case of new Service/Client-api all this refers not to * but to & instead) " "\n" "\nVisit .../confluence/display/RMS/%5BTMS-IF%5D+Troubleshooting (see" "\n'detection of overridden methods') or contact ddkit-Team for more help." "\n" "\033[0m"); // compile-error due to static-assert should have avoided this already. bool isInFactDerivedType = !std::is_same::value; if(!isInFactDerivedType) { throw std::logic_error("isInFactDerivedType is false"); } if (isCheckMostDerivedClassType) { // one may fool both tests by writing a wrapper with a different (generic) class, which overrides nothing, // but only is base-class for other derived-classes, in which the methods are overridden. // Or one could add multi-levels of inheritance and add some functions each level. // In these cases the equalness of the template-parameter with the interface-class is not enough any more, // to detect, if the correct (most bottom) class was given as pointer into the auto-detection. // But another method works, as typeid cannot only be used to compare function-addresses for equality like // in the auto-detect-functionality of adapterlib 7.0.0, but also classes of objects (the original purpose), // and so we can check, if the template-type, that here is presenting itself, is the same type, as the object // itself, that is given. If not, some slicing did occur, and some overridden methods would not be detected // correctly, so we have to error here. // - and now the magic happens: if (typeid(callbacks) != typeid(IServiceDerived)) { throw std::runtime_error("detectMethods called with 'sliced' type of your object. Your given" " callbacks-pointer/reference maybe was (implicitly) casted to a base-class."); } } // determine set of overridden methods (walk methods of inherited classes as well) std::vector methods; // methods of M_RecordingCtrl::IService if (!std::is_same::value) methods.push_back("CmdStartRecording"); if (!std::is_same::value) methods.push_back("CmdCaptureVideoCutout"); if (!std::is_same::value) methods.push_back("CmdStopRecording"); if (!std::is_same::value) methods.push_back("CmdRemoveVideoCutout"); if (!std::is_same::value) methods.push_back("CmdRemoveAllVideoCutouts"); if (!std::is_same::value) methods.push_back("CmdCaptureImage"); return methods; } // static template void IServiceObsFactory::add(std::string const& serviceName, IServiceDerived* obs, int domain) { ddkit::actors::SessionManager::instance(); // Must be first on the stack (init logging etc.)! bool checkMostDerivedClassType = ddkit::actors::BackwardManager::instance().createOrGetSession_(domain)->isCheckMostDerivedClassType(); std::vector methods = M_RecordingCtrl::detectMethodsIService(*obs, checkMostDerivedClassType); addCustom(obs, methods, serviceName, domain); } // static int domain, lambda template typename std::enable_if::value && std::is_same>::value, Service>::type Service::create(T domain, std::string serviceName, IServiceDerived& callbacks) { auto session = ddkit::actors::SessionFactory::instance().getSession(domain); std::vector methods = M_RecordingCtrl::detectMethodsIService(callbacks, false); std::map> lambdaMap = M_RecordingCtrl::detectCallbacksIService(callbacks); return createCustom(session, serviceName, lambdaMap, methods); } // static int domain, IServiceDerived template typename std::enable_if::value && !std::is_same>::value, Service>::type Service::create(T domain, std::string serviceName, IServiceDerived& callbacks) { auto session = ddkit::actors::SessionFactory::instance().getSession(domain); std::vector methods = M_RecordingCtrl::detectMethodsIService(callbacks, isCheckMostDerivedClassType(*session.get())); return createCustom(session, serviceName, callbacks, methods); } // static shared_ptr session, lambda template typename std::enable_if>::value && std::is_same>::value, Service>::type Service::create(T session, std::string serviceName, IServiceDerived& callbacks) { std::vector methods = M_RecordingCtrl::detectMethodsIService(callbacks, false); std::map> lambdaMap = M_RecordingCtrl::detectCallbacksIService(callbacks); return createCustom(session, serviceName, lambdaMap, methods); } // static shared_ptr session, IServiceDerived template typename std::enable_if>::value && !std::is_same>::value, Service>::type Service::create(T session, std::string serviceName, IServiceDerived& callbacks) { std::vector methods = M_RecordingCtrl::detectMethodsIService(callbacks, isCheckMostDerivedClassType(*session.get())); return createCustom(session, serviceName, callbacks, methods); } // static int domain, lambda template typename std::enable_if::value && std::is_same>::value, Service>::type Service::createMonitor(T domain, std::string serviceName, IServiceDerived& callbacks) { auto monitorSession = ddkit::actors::SessionFactory::instance().getMonitorSession(domain); std::vector methods = M_RecordingCtrl::detectMethodsIService(callbacks, false); std::map> lambdaMap = M_RecordingCtrl::detectCallbacksIService(callbacks); return createCustomReadOnly(monitorSession, serviceName, lambdaMap, methods); } // static int domain, IServiceDerived template typename std::enable_if::value && !std::is_same>::value, Service>::type Service::createMonitor(T domain, std::string serviceName, IServiceDerived& callbacks) { auto monitorSession = ddkit::actors::SessionFactory::instance().getMonitorSession(domain); std::vector methods = M_RecordingCtrl::detectMethodsIService(callbacks, isCheckMostDerivedClassType(*monitorSession.get())); return createCustomReadOnly(monitorSession, serviceName, callbacks, methods); } // static std::shared_ptr monitorSession, lambda template typename std::enable_if>::value && std::is_same>::value, Service>::type Service::createMonitor(T monitorSession, std::string serviceName, IServiceDerived& callbacks) { std::vector methods = M_RecordingCtrl::detectMethodsIService(callbacks, false); std::map> lambdaMap = M_RecordingCtrl::detectCallbacksIService(callbacks); return createCustomReadOnly(monitorSession, serviceName, lambdaMap, methods); } // static std::shared_ptr monitorSession, IServiceDerived template typename std::enable_if>::value && !std::is_same>::value, Service>::type Service::createMonitor(T monitorSession, std::string serviceName, IServiceDerived& callbacks) { std::vector methods = M_RecordingCtrl::detectMethodsIService(callbacks, isCheckMostDerivedClassType(*monitorSession.get())); return createCustomReadOnly(monitorSession, serviceName, callbacks, methods); } // static int domain, lambda template typename std::enable_if::value && std::is_same>::value, Service>::type Service::createMonitor(T domain, IServiceDerived& callbacks) { auto monitorSession = ddkit::actors::SessionFactory::instance().getMonitorSession(domain); std::vector methods = M_RecordingCtrl::detectMethodsIService(callbacks, false); std::map> lambdaMap = M_RecordingCtrl::detectCallbacksIService(callbacks); return createCustomReadOnlyMultiplex(monitorSession, lambdaMap, methods); } // static int domain, IServiceDerived template typename std::enable_if::value && !std::is_same>::value, Service>::type Service::createMonitor(T domain, IServiceDerived& callbacks) { auto monitorSession = ddkit::actors::SessionFactory::instance().getMonitorSession(domain); std::vector methods = M_RecordingCtrl::detectMethodsIService(callbacks, isCheckMostDerivedClassType(*monitorSession.get())); return createCustomReadOnlyMultiplex(monitorSession, callbacks, methods); } // static std::shared_ptr monitorSession, lambda template typename std::enable_if>::value && std::is_same>::value, Service>::type Service::createMonitor(T monitorSession, IServiceDerived& callbacks) { std::vector methods = M_RecordingCtrl::detectMethodsIService(callbacks, false); std::map> lambdaMap = M_RecordingCtrl::detectCallbacksIService(callbacks); return createCustomReadOnlyMultiplex(monitorSession, lambdaMap, methods); } // static std::shared_ptr monitorSession, IServiceDerived template typename std::enable_if>::value && !std::is_same>::value, Service>::type Service::createMonitor(T monitorSession, IServiceDerived& callbacks) { std::vector methods = M_RecordingCtrl::detectMethodsIService(callbacks, isCheckMostDerivedClassType(*monitorSession.get())); return createCustomReadOnlyMultiplex(monitorSession, callbacks, methods); } #endif #ifndef SWIG template typename std::enable_if>::value, std::map>>::type detectCallbacksIClient(IClientDerived& callbacks) { std::map> methods; for(auto& obj : callbacks) { (void) obj; // classes without callbacks // methods of M_RecordingCtrl::IClient { auto cb = dynamic_cast*>(obj); if(cb && cb->isFunction(&M_RecordingCtrl::IClient::ReportRecordingSettings)) { if(!methods.count("ReportRecordingSettings")) { std::vector c; methods.insert(std::make_pair("ReportRecordingSettings", c)); } methods["ReportRecordingSettings"].push_back(obj); continue; } } { auto cb = dynamic_cast*>(obj); if(cb && cb->isFunction(&M_RecordingCtrl::IClient::ReportRecordingStatus)) { if(!methods.count("ReportRecordingStatus")) { std::vector c; methods.insert(std::make_pair("ReportRecordingStatus", c)); } methods["ReportRecordingStatus"].push_back(obj); continue; } } } return methods; } template typename std::enable_if>::value, std::vector>::type detectMethodsIClient(IClientDerived& callbacks, bool isCheckMostDerivedClassType) { std::set methods; for(auto& obj : callbacks) { (void) obj; // classes without callbacks // methods of M_RecordingCtrl::IClient { auto cb = dynamic_cast*>(obj); if(cb && cb->isFunction(&M_RecordingCtrl::IClient::ReportRecordingSettings)) { methods.insert("ReportRecordingSettings"); continue; } } { auto cb = dynamic_cast*>(obj); if(cb && cb->isFunction(&M_RecordingCtrl::IClient::ReportRecordingStatus)) { methods.insert("ReportRecordingStatus"); continue; } } } std::vector result(methods.begin(), methods.end()); return result; } template typename std::enable_if>::value, std::vector>::type detectMethodsIClient(IClientDerived& callbacks, bool isCheckMostDerivedClassType) { // if user has casted its derived IClient* to IClient* (implicitly by going through some wrapper-proxy, which // does not make use of a template-parameter, all functions will appear to be not overridden, so the compiler // should cry: static_assert(!std::is_same::value, "\033[00;37m\033[40m" "\n" "\nCannot take your callbacks* while auto-detecting your overridden methods! It" "\nappears to be of type IClient* - but must be of derived class of IClient* (that" "\nis to say: it must be >your< class)." "\nMost certainly this problem is triggered by you having a wrapper-method around" "\nour add/create-methods and thus unintentionally casting up the callbacks* to" "\nan IClient* - a simple solution is to use a template-function as wrapper-method," "\nthereby keeping the type of your callbacks* original, while transferring to us." "\n" "\n(in case of new Service/Client-api all this refers not to * but to & instead) " "\n" "\nVisit .../confluence/display/RMS/%5BTMS-IF%5D+Troubleshooting (see" "\n'detection of overridden methods') or contact ddkit-Team for more help." "\n" "\033[0m"); // compile-error due to static-assert should have avoided this already. bool isInFactDerivedType = !std::is_same::value; if(!isInFactDerivedType) { throw std::logic_error("isInFactDerivedType is false"); } if (isCheckMostDerivedClassType) { // one may fool both tests by writing a wrapper with a different (generic) class, which overrides nothing, // but only is base-class for other derived-classes, in which the methods are overridden. // Or one could add multi-levels of inheritance and add some functions each level. // In these cases the equalness of the template-parameter with the interface-class is not enough any more, // to detect, if the correct (most bottom) class was given as pointer into the auto-detection. // But another method works, as typeid cannot only be used to compare function-addresses for equality like // in the auto-detect-functionality of adapterlib 7.0.0, but also classes of objects (the original purpose), // and so we can check, if the template-type, that here is presenting itself, is the same type, as the object // itself, that is given. If not, some slicing did occur, and some overridden methods would not be detected // correctly, so we have to error here. // - and now the magic happens: if (typeid(callbacks) != typeid(IClientDerived)) { throw std::runtime_error("detectMethods called with 'sliced' type of your object. Your given" " callbacks-pointer/reference maybe was (implicitly) casted to a base-class."); } } // determine set of overridden methods (walk methods of inherited classes as well) std::vector methods; // methods of M_RecordingCtrl::IClient if (!std::is_same::value) methods.push_back("ReportRecordingSettings"); if (!std::is_same::value) methods.push_back("ReportRecordingStatus"); return methods; } // static template void IClientObsFactory::add(std::string const& serviceName, IClientDerived* obs, int domain) { ddkit::actors::SessionManager::instance(); // Must be first on the stack (init logging etc.)! bool checkMostDerivedClassType = ddkit::actors::BackwardManager::instance().createOrGetSession_(domain)->isCheckMostDerivedClassType(); std::vector methods = M_RecordingCtrl::detectMethodsIClient(*obs, checkMostDerivedClassType); addCustom(obs, methods, serviceName, domain); } // static template void IClientObsFactory::add(std::string const& serviceName, IClientDerived* obs, int domain, std::string const& clientName) { ddkit::actors::SessionManager::instance(); // Must be first on the stack (init logging etc.)! bool checkMostDerivedClassType = ddkit::actors::BackwardManager::instance().createOrGetSession_(domain)->isCheckMostDerivedClassType(); std::vector methods = M_RecordingCtrl::detectMethodsIClient(*obs, checkMostDerivedClassType); addCustom(obs, methods, serviceName, domain, clientName); } // static int domain, lambda template typename std::enable_if::value && std::is_same>::value, Client>::type Client::create(T domain, std::string serviceName, IClientDerived& callbacks) { auto session = ddkit::actors::SessionFactory::instance().getSession(domain); std::vector methods = M_RecordingCtrl::detectMethodsIClient(callbacks, false); std::map> lambdaMap = M_RecordingCtrl::detectCallbacksIClient(callbacks); return createCustom(session, serviceName, lambdaMap, methods); } // static int domain, IClientDerived template typename std::enable_if::value && !std::is_same>::value, Client>::type Client::create(T domain, std::string serviceName, IClientDerived& callbacks) { auto session = ddkit::actors::SessionFactory::instance().getSession(domain); std::vector methods = M_RecordingCtrl::detectMethodsIClient(callbacks, isCheckMostDerivedClassType(*session.get())); return createCustom(session, serviceName, callbacks, methods); } // static shared_ptr session, lambda template typename std::enable_if>::value && std::is_same>::value, Client>::type Client::create(T session, std::string serviceName, IClientDerived& callbacks) { std::vector methods = M_RecordingCtrl::detectMethodsIClient(callbacks, false); std::map> lambdaMap = M_RecordingCtrl::detectCallbacksIClient(callbacks); return createCustom(session, serviceName, lambdaMap, methods); } // static shared_ptr session, IClientDerived template typename std::enable_if>::value && !std::is_same>::value, Client>::type Client::create(T session, std::string serviceName, IClientDerived& callbacks) { std::vector methods = M_RecordingCtrl::detectMethodsIClient(callbacks, isCheckMostDerivedClassType(*session.get())); return createCustom(session, serviceName, callbacks, methods); } // static int domain, lambda template typename std::enable_if::value && std::is_same>::value, Client>::type Client::createMonitor(T domain, std::string serviceName, IClientDerived& callbacks) { auto monitorSession = ddkit::actors::SessionFactory::instance().getMonitorSession(domain); std::vector methods = M_RecordingCtrl::detectMethodsIClient(callbacks, false); std::map> lambdaMap = M_RecordingCtrl::detectCallbacksIClient(callbacks); return createCustomReadOnly(monitorSession, serviceName, lambdaMap, methods); } // static int domain, IClientDerived template typename std::enable_if::value && !std::is_same>::value, Client>::type Client::createMonitor(T domain, std::string serviceName, IClientDerived& callbacks) { auto monitorSession = ddkit::actors::SessionFactory::instance().getMonitorSession(domain); std::vector methods = M_RecordingCtrl::detectMethodsIClient(callbacks, isCheckMostDerivedClassType(*monitorSession.get())); return createCustomReadOnly(monitorSession, serviceName, callbacks, methods); } // static std::shared_ptr monitorSession, lambda template typename std::enable_if>::value && std::is_same>::value, Client>::type Client::createMonitor(T monitorSession, std::string serviceName, IClientDerived& callbacks) { std::vector methods = M_RecordingCtrl::detectMethodsIClient(callbacks, false); std::map> lambdaMap = M_RecordingCtrl::detectCallbacksIClient(callbacks); return createCustomReadOnly(monitorSession, serviceName, lambdaMap, methods); } // static std::shared_ptr monitorSession, IClientDerived template typename std::enable_if>::value && !std::is_same>::value, Client>::type Client::createMonitor(T monitorSession, std::string serviceName, IClientDerived& callbacks) { std::vector methods = M_RecordingCtrl::detectMethodsIClient(callbacks, isCheckMostDerivedClassType(*monitorSession.get())); return createCustomReadOnly(monitorSession, serviceName, callbacks, methods); } // static int domain, lambda template typename std::enable_if::value && std::is_same>::value, Client>::type Client::createMonitor(T domain, IClientDerived& callbacks) { auto monitorSession = ddkit::actors::SessionFactory::instance().getMonitorSession(domain); std::vector methods = M_RecordingCtrl::detectMethodsIClient(callbacks, false); std::map> lambdaMap = M_RecordingCtrl::detectCallbacksIClient(callbacks); return createCustomReadOnlyMultiplex(monitorSession, lambdaMap, methods); } // static int domain, IClientDerived template typename std::enable_if::value && !std::is_same>::value, Client>::type Client::createMonitor(T domain, IClientDerived& callbacks) { auto monitorSession = ddkit::actors::SessionFactory::instance().getMonitorSession(domain); std::vector methods = M_RecordingCtrl::detectMethodsIClient(callbacks, isCheckMostDerivedClassType(*monitorSession.get())); return createCustomReadOnlyMultiplex(monitorSession, callbacks, methods); } // static std::shared_ptr monitorSession, lambda template typename std::enable_if>::value && std::is_same>::value, Client>::type Client::createMonitor(T monitorSession, IClientDerived& callbacks) { std::vector methods = M_RecordingCtrl::detectMethodsIClient(callbacks, false); std::map> lambdaMap = M_RecordingCtrl::detectCallbacksIClient(callbacks); return createCustomReadOnlyMultiplex(monitorSession, lambdaMap, methods); } // static std::shared_ptr monitorSession, IClientDerived template typename std::enable_if>::value && !std::is_same>::value, Client>::type Client::createMonitor(T monitorSession, IClientDerived& callbacks) { std::vector methods = M_RecordingCtrl::detectMethodsIClient(callbacks, isCheckMostDerivedClassType(*monitorSession.get())); return createCustomReadOnlyMultiplex(monitorSession, callbacks, methods); } #endif } // namespace M_RecordingCtrl #endif