/** * @RDE_HEADER@ * ProxyBuilding to handle access to HandlerBuildingModelInterface * $Id$ * $HeadURL$ * $Author$ * Created by Norbert Thoden, ESVG, 2024-09-09 */ #pragma once #include #include #include #include #include //----------------------------------------------------------------------------- // forwards and interface //----------------------------------------------------------------------------- namespace CesBuildings { //----------------------------------------------------------------------------- // some forward declarations: class HandlerBuildingModel; //----------------------------------------------------------------------------- // interface for HandlerBuildingModel //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ // Norbert Thoden, 29.08.2024 // Branch svn://slssvn/TDS/branches/product/features/3dws_devel // // Im Zuge der Verdeckungsberechnung waren Umstellungen erforderlich. // https://devhub.defence-elec.de/jira/browse/GUEZE-2765 und // https://devhub.defence-elec.de/jira/browse/GUEZE-2779 // // //Es wurde eine Kommunikation _zwischen_ CES-Plugins notwendig. //Es erfolgten dann die ein oder andere Umstrukturierung: r 63587 //Wie ZWISCHEN CES-Plugins kommunizieren? //Bei den Plugins der Operator-App wurde ein 'Foreign...Interface'-Ansatz //eingefügt. //M.E. hat diese eine aehnliche Aufgabe. Als Unterschiede identifiziere ich //- Es muss beruecksichtigt werden, dass das gesamte Plugin im Build-Prozess // nicht zur Verfügung steht. // Ein Interface muss also _ausserhalb_ des (implementierenden) Plugins // sein. //- 'Foreign...Interface'-Ansatz beruecksichtigt nur die Existenz eines Plugins, // nicht dessen Funktionsfaehigkeit. //- Es wirkt auf das ganze Plugin, nicht auf Teile (Ein CES-Plugin beherbergt // möglicherweise zwei unabhängige Funktionsblöcke, die hoch- oder // runtergefahren werden könnten. //.. // //Daher habe ich mich für eine Moeglichkeit entschieden, die rel. unabhaengig von //CentralEffectSimulation::Plugin::Plugin & Co ist. // //- Statische Sicht: //- Interface 'HandlerBuildingModelInterface' in proxy_building.{h,cpp} //- Es bietet derzeit zwei Los-Methoden an, mit _synchronen_ Aufruf an. //- Es nutzt möglichst nur POD oder Elemente aus DDS::Core. // Da das Plugin spaeter moeglicherweise nicht erstellt wird, fehlen auch dessen // Strukturen //- Die Implementierung des Interfaces ist HandlerBuildingModel // Dort wird einerseites das HandlerBuildingModelInterface implementiert. // (getLineBuildingIntersection...) // Andererseits gibt es zwei FunctionCalls, die zudem implementiert werden. // - GetLineBuildingIntersectionRequestHandler // - GetLineBuildingIntersectsRequestHandler // // Alle vier stützen sich auf _EINE_ inter ab: // getLineBuildingIntersectionInternal(); // //- Dynamische Sicht: // - Mit Start des MainHandlers wird 'ProxyBuilding' erstellt. // - Wenn nur das Plugin 'Building' // - geladen, initialisiert und // - funktionsbereit ist (Alle Buildings geladen) // DANN // kann es sich im ProxyBuilding eintragen (set_handlerBuildingModel) // // - Anderen Plugins koennen via MainHandlers ebenfalls Zugriff auf // denselben ProxyBuilding erlangen. Und abfragen, ob die angeboten // Funktionalitaeten verfügbar sind: isSet_handlerBuildingModel() // // - Wenn man also sorgsam die FunctionCall und die HandlerBuildingModelInterface // abstimmt, liefern sie konsistente Ergebnisse! // // - Im MainHandler sollten für das Plugin 'Building' relevaten Topics // moeglichst fruehzeitig angefordert werden. // Damit sollte dann gewaehrleistet sein, dass mit Abschluss von // HandlerBuildingModel::init() auch alle relevaten MainStruktureElements, // also Buidlings, geladen sind. // In CesBuildingsInterfaceImpl::init wird NACH dem Erstellen und // Initialisierern von HandlerBuildingModel das Eintrag der Funktionen // im ProxyBuilding vorgenommen (proxyBuilding->set_handlerBuildingModel) // // - Es waere theoretisch denkbar, die Funktionen wieder auszutragen, // wenn der Exercise keine Buildings mehr zugeordnet sind. //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ // be aware, used data types _must_ be available, even if the executing/implementing plugin is not not build (eg. no Building-Plugin) // !!! take care if generated structures are involved !!! // !!! -> use more of less pods ; Core::GeoPosition ... !!! class HandlerBuildingModelInterface { public: /*! \name Plugin 'Buildings' - HandlerBuildingModel - LineOfSight etc*/ //@{ //---------------------------------------------------------------------------- struct LineBuildingIntersectionResult { std::string requestId; std::string errorString; std::vector errorParams; Core::GeoPosition intersection; // maybe int segmentIdxOfIntersection{-1} }; virtual LineBuildingIntersectionResult getLineBuildingIntersection(const std::vector& line, const std::string& requestIdOpt = {}) = 0; //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- struct LineBuildingIntersectsResult { std::string requestId; std::string errorString; std::vector errorParams; bool intersects{false}; }; virtual LineBuildingIntersectsResult getLineBuildingIntersects(const std::vector& line, const std::string& requestIdOpt = {}) = 0; //---------------------------------------------------------------------------- //@} }; } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // real start: //----------------------------------------------------------------------------- namespace CentralEffectSimulation { /*! * \brief The ProxyBuilding class passes the calls. * Calls from any CesPlugin (via mainHandler?) to the CesPlugin 'Buildings' - if available and set. */ class SVCCESDDSCOMMON_EXPORT ProxyBuilding : public QObject { Q_OBJECT public: using BaseClass = QObject; explicit ProxyBuilding(QObject *parent = nullptr); ~ProxyBuilding(); /*! \name Plugin 'Buildings' - HandlerBuildingModel - admin operations */ //@{ // triple: set_XY ; clear_XY ; isSet_XY void set_handlerBuildingModel(std::shared_ptr handlerBuildingModel); void clear_handlerBuildingModel(); bool isSet_handlerBuildingModel() const; std::shared_ptr handlerBuildingModelInterface(); //@} private: // use Pimpl idiom to reduce includes class Private; /** * The private d->pointer to not break BC when changing internals of this class */ Private *d = nullptr; CentralEffectSimulation::LOGGER_T &m_logger; ///< Interface to the Logging-Facility Q_DISABLE_COPY(ProxyBuilding) }; } // namespace CentralEffectSimulation