Skip to content
Snippets Groups Projects
ConnectionMaker.h 3.17 KiB
Newer Older
// SPDX-FileCopyrightText: Deutsches Elektronen-Synchrotron DESY, MSK, ChimeraTK Project <chimeratk-support@desy.de>
// SPDX-License-Identifier: LGPL-3.0-or-later
#pragma once

#include "FanOut.h"
#include "Model.h"
#include "VariableNetworkNode.h"

#include <list>

namespace ChimeraTK {
  class Application;
Jens Georg's avatar
Jens Georg committed
  class TriggerFanOut;
Jens Georg's avatar
Jens Georg committed
  class NetworkVisitor {
Jens Georg's avatar
Jens Georg committed
    void setDebugConnections(bool enable) { _debugConnections = enable; }


    /**
     * @brief Helper predicate to put ProcessVariableProxies into std::set
     */
    struct ProcessVariableComperator {
      bool operator()(const Model::ProcessVariableProxy& a, const Model::ProcessVariableProxy& b) const {
        return a.getFullyQualifiedPath() < b.getFullyQualifiedPath();
      }
    };

   protected:
    struct NetworkInformation {
      explicit NetworkInformation(const Model::ProcessVariableProxy* p) : proxy(p) {}

      const Model::ProcessVariableProxy* proxy{nullptr};
      // Variables related to the current network
      VariableNetworkNode feeder{};
Jens Georg's avatar
Jens Georg committed
      std::map<std::string, boost::shared_ptr<TriggerFanOut>> triggerImpl;
      std::list<VariableNetworkNode> consumers;
      const std::type_info* valueType{&typeid(AnyType)};
      size_t valueLength{0};
      std::string description{};
      std::string unit{};
      size_t numberOfBidirectionalNodes{0};
      size_t numberOfPollingConsumers{0};
      bool useExternalTrigger{false};
    };
Jens Georg's avatar
Jens Georg committed
    std::map<std::string, NetworkInformation> _triggerNetworks{};
    bool _debugConnections{false};

    NetworkInformation checkNetwork(Model::ProcessVariableProxy& proxy);
    void finaliseNetwork(NetworkInformation& net);

    template<typename... Args>
    void debug(Args&&...);
  };

  class ConnectionMaker : public NetworkVisitor {
   public:

    explicit ConnectionMaker(Application& app) : _app(app) {}

    void connect();

   private:
    Application& _app;

    NetworkInformation connectNetwork(Model::ProcessVariableProxy& proxy);

Jens Georg's avatar
Jens Georg committed
    void makeDirectConnectionForFeederWithImplementation(NetworkInformation& net);
    void makeFanOutConnectionForFeederWithImplementation(NetworkInformation& net,
        const Model::DeviceModuleProxy& device, const Model::ProcessVariableProxy& trigger);
Jens Georg's avatar
Jens Georg committed
    void makeConnectionForFeederWithoutImplementation(NetworkInformation& net);
    void makeConnectionForConstantFeeder(NetworkInformation& net);

    template<typename UserType>
    boost::shared_ptr<ChimeraTK::NDRegisterAccessor<UserType>> createProcessVariable(const VariableNetworkNode& node,
        size_t length, const std::string& unit, const std::string& description, AccessModeFlags flags);

    template<typename UserType>
    boost::shared_ptr<ChimeraTK::NDRegisterAccessor<UserType>> createDeviceVariable(VariableNetworkNode const& node);

    template<typename UserType>
Jens Georg's avatar
Jens Georg committed
    ConsumerImplementationPairs<UserType> setConsumerImplementations(NetworkInformation& net);

    template<typename UserType>
    std::pair<boost::shared_ptr<ChimeraTK::NDRegisterAccessor<UserType>>,
        boost::shared_ptr<ChimeraTK::NDRegisterAccessor<UserType>>>
        createApplicationVariable(VariableNetworkNode const& node, VariableNetworkNode const& consumer = {});
  };
} // namespace ChimeraTK