FairMQ  1.2.3
C++ Message Passing Framework
FairMQProgOptions.h
1 /********************************************************************************
2  * Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
3  * *
4  * This software is distributed under the terms of the *
5  * GNU Lesser General Public Licence (LGPL) version 3, *
6  * copied verbatim in the file "LICENSE" *
7  ********************************************************************************/
8 
9 /*
10  * File: FairMQProgOptions.h
11  * Author: winckler
12  *
13  * Created on March 11, 2015, 10:20 PM
14  */
15 
16 #ifndef FAIRMQPROGOPTIONS_H
17 #define FAIRMQPROGOPTIONS_H
18 
19 #include <fairmq/EventManager.h>
20 
21 #include "FairProgOptions.h"
22 #include "FairMQChannel.h"
23 
24 #include <unordered_map>
25 #include <functional>
26 #include <map>
27 #include <mutex>
28 #include <string>
29 
30 namespace fair
31 {
32 namespace mq
33 {
34 
35 struct PropertyChange : Event<std::string> {};
36 struct PropertyChangeAsString : Event<std::string> {};
37 
38 } /* namespace mq */
39 } /* namespace fair */
40 
42 {
43  protected:
44  using FairMQMap = std::unordered_map<std::string, std::vector<FairMQChannel>>;
45 
46  public:
48  virtual ~FairMQProgOptions();
49 
50  int ParseAll(const std::vector<std::string>& cmdLineArgs, bool allowUnregistered);
51  // parse command line.
52  // default parser for the mq-configuration file (JSON/XML) is called if command line key mq-config is called
53  int ParseAll(const int argc, char const* const* argv, bool allowUnregistered = false) override;
54 
55  FairMQMap GetFairMQMap() const
56  {
57  return fFairMQMap;
58  }
59 
60  std::unordered_map<std::string, int> GetChannelInfo() const
61  {
62  return fChannelInfo;
63  }
64 
65  template<typename T>
66  int UpdateValue(const std::string& key, T val)
67  {
68  std::unique_lock<std::mutex> lock(fConfigMutex);
69 
70  if (fVarMap.count(key))
71  {
72  // update variable map
73  UpdateVarMap<typename std::decay<T>::type>(key, val);
74 
75  // update FairMQChannel map, check first if data are int or string
76  if (std::is_same<T, int>::value || std::is_same<T, std::string>::value)
77  {
78  if (fMQKeyMap.count(key))
79  {
80  UpdateChannelMap(fMQKeyMap.at(key).channel, fMQKeyMap.at(key).index, fMQKeyMap.at(key).member, val);
81  }
82  }
83 
84  lock.unlock();
85  //if (std::is_same<T, int>::value || std::is_same<T, std::string>::value)//if one wants to restrict type
86  fEvents.Emit<fair::mq::PropertyChange, typename std::decay<T>::type>(key, val);
87  fEvents.Emit<fair::mq::PropertyChangeAsString, std::string>(key, GetStringValue(key));
88 
89  return 0;
90  }
91  else
92  {
93  LOG(error) << "UpdateValue failed: key '" << key << "' not found in the variable map";
94  return 1;
95  }
96  return 0;
97  }
98 
99  template<typename T>
100  int SetValue(const std::string& key, T val)
101  {
102  std::unique_lock<std::mutex> lock(fConfigMutex);
103 
104  // update variable map
105  UpdateVarMap<typename std::decay<T>::type>(key, val);
106 
107  // update FairMQChannel map, check first if data are int or string
108  if (std::is_same<T, int>::value || std::is_same<T, std::string>::value)
109  {
110  if (fMQKeyMap.count(key))
111  {
112  UpdateChannelMap(fMQKeyMap.at(key).channel, fMQKeyMap.at(key).index, fMQKeyMap.at(key).member, val);
113  }
114  }
115 
116  lock.unlock();
117 
118  //if (std::is_same<T, int>::value || std::is_same<T, std::string>::value)//if one wants to restrict type
119  fEvents.Emit<fair::mq::PropertyChange, typename std::decay<T>::type>(key, val);
120  fEvents.Emit<fair::mq::PropertyChangeAsString, std::string>(key, GetStringValue(key));
121 
122  return 0;
123  }
124 
125  template <typename T>
126  void Subscribe(const std::string& subscriber, std::function<void(typename fair::mq::PropertyChange::KeyType, T)> func)
127  {
128  std::unique_lock<std::mutex> lock(fConfigMutex);
129 
130  static_assert(!std::is_same<T,const char*>::value || !std::is_same<T, char*>::value,
131  "In template member FairMQProgOptions::Subscribe<T>(key,Lambda) the types const char* or char* for the calback signatures are not supported.");
132 
133  fEvents.Subscribe<fair::mq::PropertyChange, T>(subscriber, func);
134  }
135 
136  template <typename T>
137  void Unsubscribe(const std::string& subscriber)
138  {
139  std::unique_lock<std::mutex> lock(fConfigMutex);
140 
141  fEvents.Unsubscribe<fair::mq::PropertyChange, T>(subscriber);
142  }
143 
144  void SubscribeAsString(const std::string& subscriber, std::function<void(typename fair::mq::PropertyChange::KeyType, std::string)> func)
145  {
146  std::unique_lock<std::mutex> lock(fConfigMutex);
147 
148  fEvents.Subscribe<fair::mq::PropertyChangeAsString, std::string>(subscriber, func);
149  }
150 
151  void UnsubscribeAsString(const std::string& subscriber)
152  {
153  std::unique_lock<std::mutex> lock(fConfigMutex);
154 
155  fEvents.Unsubscribe<fair::mq::PropertyChangeAsString, std::string>(subscriber);
156  }
157 
158  // replace FairMQChannelMap, and update variable map accordingly
159  int UpdateChannelMap(const FairMQMap& map);
160 
161  protected:
162  struct MQKey
163  {
164  std::string channel;
165  int index;
166  std::string member;
167  };
168 
169  po::options_description fMQCmdOptions;
170  po::options_description fMQParserOptions;
171  FairMQMap fFairMQMap;
172 
173  // map of read channel info - channel name - number of subchannels
174  std::unordered_map<std::string, int> fChannelInfo;
175 
176  std::map<std::string, MQKey> fMQKeyMap;// key=full path - val=key info
177 
178  int ImmediateOptions() override; // for custom help & version printing
179  void InitOptionDescription();
180 
181  // read FairMQChannelMap and insert/update corresponding values in variable map
182  // create key for variable map as follow : channelName.index.memberName
183  void UpdateMQValues();
184  int Store(const FairMQMap& channels);
185 
186  private:
187  template<typename T>
188  void EmitUpdate(const std::string& key, T val)
189  {
190  //compile time check whether T is const char* or char*, and in that case a compile time error is thrown.
191  static_assert(!std::is_same<T,const char*>::value || !std::is_same<T, char*>::value,
192  "In template member FairMQProgOptions::EmitUpdate<T>(key,val) the types const char* or char* for the calback signatures are not supported.");
193  fEvents.Emit<fair::mq::PropertyChange, T>(key, val);
194  fEvents.Emit<fair::mq::PropertyChangeAsString, std::string>(key, GetStringValue(key));
195  }
196 
197  int UpdateChannelMap(const std::string& channelName, int index, const std::string& member, const std::string& val);
198  int UpdateChannelMap(const std::string& channelName, int index, const std::string& member, int val);
199  // for cases other than int and string
200  template<typename T>
201  int UpdateChannelMap(const std::string& /*channelName*/, int /*index*/, const std::string& /*member*/, T /*val*/)
202  {
203  return 0;
204  }
205 
206  void UpdateChannelInfo();
207 
208  fair::mq::EventManager fEvents;
209 };
210 
211 #endif /* FAIRMQPROGOPTIONS_H */
Definition: FairMQProgOptions.h:162
Definition: EventManager.h:33
Definition: FairProgOptions.h:35
Manages event callbacks from different subscribers.
Definition: EventManager.h:53
Definition: FairMQProgOptions.h:41
Definition: FairMQProgOptions.h:36
Definition: DeviceRunner.h:23
Definition: FairMQProgOptions.h:35