/******************************************************************************** * Copyright (C) 2014-2018 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH * * * * This software is distributed under the terms of the * * GNU Lesser General Public Licence (LGPL) version 3, * * copied verbatim in the file "LICENSE" * ********************************************************************************/ #ifndef FAIR_MQ_PROGOPTIONS_H #define FAIR_MQ_PROGOPTIONS_H #include "FairMQChannel.h" #include "FairMQLogger.h" #include #include #include #include #include #include #include #include #include #include #include namespace fair { namespace mq { class ProgOptions { public: ProgOptions(); virtual ~ProgOptions() {} void ParseAll(const std::vector& cmdArgs, bool allowUnregistered); void ParseAll(const int argc, char const* const* argv, bool allowUnregistered = true); void Notify(); void AddToCmdLineOptions(const boost::program_options::options_description optDesc, bool visible = true); boost::program_options::options_description& GetCmdLineOptions(); int Count(const std::string& key) const; std::unordered_map GetChannelInfo() const; std::vector GetPropertyKeys() const; template T GetProperty(const std::string& key) const { std::lock_guard lock(fMtx); if (fVarMap.count(key)) { return fVarMap[key].as(); } else { LOG(warn) << "Config has no key: " << key << ". Returning default constructed object."; return T(); } } template T GetProperty(const std::string& key, const T& ifNotFound) const { std::lock_guard lock(fMtx); if (fVarMap.count(key)) { return fVarMap[key].as(); } return ifNotFound; } std::string GetPropertyAsString(const std::string& key) const; std::string GetPropertyAsString(const std::string& key, const std::string& ifNotFound) const; fair::mq::Properties GetProperties(const std::string& q) const; fair::mq::Properties GetPropertiesStartingWith(const std::string& q) const; std::map GetPropertiesAsString(const std::string& q) const; std::map GetPropertiesAsStringStartingWith(const std::string& q) const; template void SetProperty(const std::string& key, T val) { std::unique_lock lock(fMtx); SetVarMapValue::type>(key, val); lock.unlock(); fEvents.Emit::type>(key, val); fEvents.Emit(key, GetPropertyAsString(key)); } template bool UpdateProperty(const std::string& key, T val) { std::unique_lock lock(fMtx); if (fVarMap.count(key)) { SetVarMapValue::type>(key, val); lock.unlock(); fEvents.Emit::type>(key, val); fEvents.Emit(key, GetPropertyAsString(key)); return true; } else { LOG(debug) << "UpdateProperty failed, no property found with key '" << key << "'"; return false; } } void SetProperties(const fair::mq::Properties& input); bool UpdateProperties(const fair::mq::Properties& input); void DeleteProperty(const std::string& key); void AddChannel(const std::string& name, const FairMQChannel& channel); template void Subscribe(const std::string& subscriber, std::function func) const { std::lock_guard lock(fMtx); static_assert(!std::is_same::value || !std::is_same::value, "In template member ProgOptions::Subscribe(key,Lambda) the types const char* or char* for the calback signatures are not supported."); fEvents.Subscribe(subscriber, func); } template void Unsubscribe(const std::string& subscriber) const { std::lock_guard lock(fMtx); fEvents.Unsubscribe(subscriber); } void SubscribeAsString(const std::string& subscriber, std::function func) const { std::lock_guard lock(fMtx); fEvents.Subscribe(subscriber, func); } void UnsubscribeAsString(const std::string& subscriber) const { std::lock_guard lock(fMtx); fEvents.Unsubscribe(subscriber); } void PrintHelp(); void PrintOptions(); void PrintOptionsRaw(); const boost::program_options::variables_map& GetVarMap() const { return fVarMap; } template T GetValue(const std::string& key) const /* TODO: deprecate this */ { return GetProperty(key); } template int SetValue(const std::string& key, T val) /* TODO: deprecate this */ { SetProperty(key, val); return 0; } std::string GetStringValue(const std::string& key) const /* TODO: deprecate this */ { return GetPropertyAsString(key); } private: void ParseDefaults(); std::unordered_map GetChannelInfoImpl() const; template void SetVarMapValue(const std::string& key, const T& val) { std::map& vm = fVarMap; vm[key].value() = boost::any(val); } boost::program_options::variables_map fVarMap; ///< options container boost::program_options::options_description fAllOptions; ///< all options descriptions std::vector fUnregisteredOptions; ///< container with unregistered options mutable fair::mq::EventManager fEvents; mutable std::mutex fMtx; }; } // namespace mq } // namespace fair #endif /* FAIR_MQ_PROGOPTIONS_H */