Registry.cpp 3.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. // Copyright (c) 2013-2017 Josh Blum
  2. // SPDX-License-Identifier: BSL-1.0
  3. #include <Pothos/Managed/Class.hpp>
  4. #include <Pothos/Managed/Exception.hpp>
  5. #include <Pothos/Util/SpinLockRW.hpp>
  6. #include <Pothos/Util/TypeInfo.hpp>
  7. #include <Pothos/Callable.hpp>
  8. #include <Pothos/Plugin.hpp>
  9. #include <Poco/Logger.h>
  10. #include <mutex>
  11. #include <map>
  12. /***********************************************************************
  13. * Global map structure for registry
  14. **********************************************************************/
  15. static Pothos::Util::SpinLockRW &getMapMutex(void)
  16. {
  17. static Pothos::Util::SpinLockRW lock;
  18. return lock;
  19. }
  20. //singleton global map for all supported classes
  21. typedef std::map<size_t, Pothos::Plugin> ClassMapType;
  22. static ClassMapType &getClassMap(void)
  23. {
  24. static ClassMapType map;
  25. return map;
  26. }
  27. /***********************************************************************
  28. * Conversion registration handling
  29. **********************************************************************/
  30. static void handlePluginEvent(const Pothos::Plugin &plugin, const std::string &event)
  31. {
  32. poco_debug_f2(Poco::Logger::get("Pothos.ManagedClass.handlePluginEvent"), "plugin %s, event %s", plugin.toString(), event);
  33. POTHOS_EXCEPTION_TRY
  34. {
  35. //validate the plugin -- if we want to handle it -- check the signature:
  36. if (plugin.getObject().type() != typeid(Pothos::ManagedClass)) return;
  37. const auto &reg = plugin.getObject().extract<Pothos::ManagedClass>();
  38. std::lock_guard<Pothos::Util::SpinLockRW> lock(getMapMutex());
  39. if (event == "add")
  40. {
  41. getClassMap()[reg.type().hash_code()] = plugin;
  42. getClassMap()[reg.pointerType().hash_code()] = plugin;
  43. getClassMap()[reg.sharedType().hash_code()] = plugin;
  44. }
  45. if (event == "remove")
  46. {
  47. getClassMap()[reg.type().hash_code()] = Pothos::Plugin();
  48. getClassMap()[reg.pointerType().hash_code()] = Pothos::Plugin();
  49. getClassMap()[reg.sharedType().hash_code()] = Pothos::Plugin();
  50. }
  51. }
  52. POTHOS_EXCEPTION_CATCH(const Pothos::Exception &ex)
  53. {
  54. poco_error_f3(Poco::Logger::get("Pothos.ManagedClass.handlePluginEvent"),
  55. "exception %s, plugin %s, event %s", ex.displayText(), plugin.toString(), event);
  56. }
  57. }
  58. /***********************************************************************
  59. * Register event handler
  60. **********************************************************************/
  61. pothos_static_block(pothosManagedClassRegister)
  62. {
  63. Pothos::PluginRegistry::addCall("/managed", &handlePluginEvent);
  64. }
  65. /***********************************************************************
  66. * The lookup implementation
  67. **********************************************************************/
  68. Pothos::ManagedClass Pothos::ManagedClass::lookup(const std::type_info &type)
  69. {
  70. //find the plugin in the map, it will be null if not found
  71. Pothos::Util::SpinLockRW::SharedLock lock(getMapMutex());
  72. auto it = getClassMap().find(type.hash_code());
  73. //thow an error when the entry is not found
  74. if (it == getClassMap().end()) throw ManagedClassLookupError(
  75. "Pothos::ManagedClass::lookup("+Util::typeInfoToString(type)+")",
  76. "no registration found");
  77. //extract the managed class
  78. return it->second.getObject().extract<Pothos::ManagedClass>();
  79. }