addon_manager.cpp
Go to the documentation of this file.
00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 #include <opc/common/addons_core/addon.h>
00012 #include <opc/common/addons_core/addon_manager.h>
00013 #include <opc/common/addons_core/errors.h>
00014 #include <opc/common/exception.h>
00015 
00016 #include <iostream>
00017 #include <map>
00018 
00019 namespace
00020 {
00021   struct AddonData
00022   {
00023     Common::AddonId Id;
00024     Common::AddonFactory::SharedPtr Factory;
00025     std::vector<Common::AddonId> Dependencies;
00026     Common::AddonParameters Parameters;
00027     Common::Addon::SharedPtr Addon;
00028 
00029     AddonData(const Common::AddonInformation& configuration)
00030       : Id(configuration.Id)
00031       , Factory(configuration.Factory)
00032       , Dependencies(configuration.Dependencies)
00033       , Parameters(configuration.Parameters)
00034     {
00035     }
00036   };
00037 
00038   bool IsAddonNotStarted(const std::pair<Common::AddonId, AddonData>& addonData)
00039   {
00040     return addonData.second.Addon == Common::Addon::SharedPtr();
00041   }
00042 
00043   class AddonsManagerImpl : public Common::AddonsManager
00044   {
00045     typedef std::map<Common::AddonId, AddonData> AddonList;
00046 
00047   public:
00048     AddonsManagerImpl()
00049       : ManagerStarted(false)
00050     {
00051     }
00052 
00053     virtual ~AddonsManagerImpl()
00054     {
00055       try
00056       {
00057         if (ManagerStarted)
00058         {
00059           Stop();
00060         }
00061       }
00062       catch(const Common::Error& err)
00063       {
00064         std::cerr << err.GetFullMessage() << std::endl;
00065       }
00066       catch (...)
00067       {
00068         std::cerr << "unknown exception" << std::endl;
00069         throw;
00070       }
00071     }
00072 
00073     virtual void Register(const Common::AddonInformation& addonConfiguration)
00074     {
00075       // TODO lock manager
00076       if (ManagerStarted && !addonConfiguration.Dependencies.empty())
00077       {
00078         THROW_ERROR1(UnableToRegisterAddonWhenStarted, addonConfiguration.Id);
00079       }
00080 
00081       EnsureAddonNotRegistered(addonConfiguration.Id);
00082       Addons.insert(std::make_pair(addonConfiguration.Id, AddonData(addonConfiguration)));
00083       if (ManagerStarted)
00084       {
00085         DoStart();
00086       }
00087     }
00088 
00089     virtual void Unregister(const Common::AddonId& id)
00090     {
00091       // TODO lock manager
00092       EnsureAddonRegistered(id);
00093       AddonData& addonData = Addons.find(id)->second;
00094       if (addonData.Addon)
00095       {
00096         addonData.Addon->Stop();
00097       }
00098       Addons.erase(id);
00099     }
00100 
00101     virtual Common::Addon::SharedPtr GetAddon(const Common::AddonId& id) const
00102     {
00103       // TODO lock manager
00104       EnsureAddonRegistered(id);
00105       EnsureAddonInitialized(id);
00106       return Addons.find(id)->second.Addon;
00107     }
00108 
00109     virtual void Start()
00110     {
00111       if (ManagerStarted)
00112       {
00113         THROW_ERROR(AddonsManagerAlreadyStarted);
00114       }
00115       // TODO lock manager
00116       if (!DoStart())
00117       {
00118         StopAddons();
00119         THROW_ERROR(FailedToStartAddons);
00120       }
00121       ManagerStarted = true;
00122     }
00123 
00124     virtual void Stop()
00125     {
00126       if (!ManagerStarted)
00127       {
00128         THROW_ERROR(AddonsManagerAlreadyStopped);
00129       }
00130 
00131       StopAddons();
00132       ManagerStarted = false;
00133     }
00134   private:
00135     void StopAddons()
00136     {
00137       if (Addons.empty())
00138           return;
00139 
00140       while (AddonData* addonData = GetNextAddonDataForStop())
00141       {
00142         try
00143         {
00144           //std::cout << "Stopping addon '" << addonData->Id << "'" <<  std::endl;
00145           addonData->Addon->Stop();
00146           addonData->Addon.reset();
00147           //std::cout << "Addon '" << addonData->Id << "' successfully stopped." <<  std::endl;
00148         }
00149         catch (const std::exception& exc)
00150         {
00151           std::cerr << "Failed to initialize addon '" << addonData->Id << "': "<< exc.what() <<  std::endl;
00152         }
00153       }
00154       Addons.clear();
00155     }
00156 
00157     bool DoStart()
00158     {
00159       while (AddonData* addonData = GetNextAddonDataForStart())
00160       {
00161         //std::cout << "Creating addon '" << addonData->Id << "'" <<  std::endl;
00162         Common::Addon::SharedPtr addon = addonData->Factory->CreateAddon();
00163         //std::cout << "Initializing addon '" << addonData->Id << "'" <<  std::endl;
00164         try
00165         {
00166           addon->Initialize(*this, addonData->Parameters);
00167           //std::cout << "Addon '" << addonData->Id << "' successfully initialized." <<  std::endl;
00168         }
00169         catch (const std::exception& exc)
00170         {
00171           std::cerr << "Failed to initialize addon '" << addonData->Id << "': "<< exc.what() <<  std::endl;
00172           return false;
00173         }
00174         addonData->Addon = addon;
00175       }
00176       EnsureAllAddonsStarted();
00177       return true;
00178    }
00179 
00180    AddonData* GetNextAddonDataForStart()
00181    {
00182      for (AddonList::iterator it = Addons.begin(); it != Addons.end(); ++it)
00183      {
00184        if (!IsAddonStarted(it->second) && IsAllAddonsStarted(it->second.Dependencies))
00185        {
00186          return &it->second;
00187        }
00188      }
00189      return 0;
00190    }
00191 
00192 
00193    AddonData* GetNextAddonDataForStop()
00194    {
00195      for (AddonList::iterator it = Addons.begin(); it != Addons.end(); ++it)
00196      {
00197        if (IsAddonStarted(it->second) && IsAllDependentAddonsStopped(it->first))
00198        {
00199          return &it->second;
00200        }
00201      }
00202      return 0;
00203    }
00204 
00205    bool IsAddonStarted(const AddonData& addonData) const
00206    {
00207      return static_cast<bool>(addonData.Addon);
00208    }
00209 
00210    bool IsAllAddonsStarted(const std::vector<Common::AddonId>& ids) const
00211    {
00212      for (std::vector<Common::AddonId>::const_iterator it = ids.begin(); it != ids.end(); ++it)
00213      {
00214        const AddonList::const_iterator addonIt = Addons.find(*it);
00215        if (addonIt == Addons.end())
00216        {
00217          THROW_ERROR1(AddonNotFound, *it);
00218        }
00219 
00220        if (!IsAddonStarted(addonIt->second))
00221        {
00222          return false;
00223        }
00224      }
00225      return true;
00226    }
00227 
00228    bool IsAllDependentAddonsStopped(const Common::AddonId& id) const
00229    {
00230      for (const AddonList::value_type& addonIt : Addons)
00231      {
00232        // Skip alreay sopped addons.
00233        if (!IsAddonStarted(addonIt.second))
00234        {
00235          continue;
00236        }
00237        // If current addon depends on passed.
00238        const std::vector<Common::AddonId>& deps = addonIt.second.Dependencies;
00239        if (std::find(deps.begin(), deps.end(), id) != deps.end())
00240        {
00241          return false;
00242        }
00243      }
00244      return true;
00245    }
00246 
00247    void EnsureAddonInitialized(Common::AddonId id) const
00248    {
00249      if (!Addons.find(id)->second.Addon)
00250      {
00251        THROW_ERROR1(AddonNotInitializedYet, id);
00252      }
00253    }
00254 
00255    void EnsureAddonRegistered(Common::AddonId id) const
00256    {
00257      if (!IsAddonRegistered(id))
00258      {
00259        THROW_ERROR1(AddonNotRegistered, id);
00260      }
00261    }
00262 
00263    void EnsureAddonNotRegistered(Common::AddonId id) const
00264    {
00265      if (IsAddonRegistered(id))
00266      {
00267        THROW_ERROR1(AddonRegisteredButShouldnt, id);
00268      }
00269    }
00270 
00271    bool IsAddonRegistered(Common::AddonId id) const
00272    {
00273      return Addons.find(id) != Addons.end();
00274    }
00275 
00276    void EnsureAllAddonsStarted() const
00277    {
00278      AddonList::const_iterator addonIt = std::find_if(Addons.begin(), Addons.end(), IsAddonNotStarted);
00279      if (!Addons.empty() && addonIt != Addons.end())
00280      {
00281        THROW_ERROR1(AddonIsNotStarted, addonIt->first);
00282      }
00283    }
00284 
00285   private:
00286     AddonList Addons;
00287     bool ManagerStarted;
00288   };
00289 }
00290 
00291 Common::AddonsManager::UniquePtr Common::CreateAddonsManager()
00292 {
00293   return AddonsManager::UniquePtr(new AddonsManagerImpl());
00294 }
00295 


ros_opcua_impl_freeopcua
Author(s): Denis Štogl
autogenerated on Sat Jun 8 2019 18:24:39