PothosUtilProxyEnvironmentInfo.cpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. // Copyright (c) 2020 Nicholas Corgan
  2. // SPDX-License-Identifier: BSL-1.0
  3. #include "PothosUtil.hpp"
  4. #include <Pothos/Callable.hpp>
  5. #include <Pothos/Plugin.hpp>
  6. #include <Pothos/Proxy.hpp>
  7. #include <Pothos/System/Paths.hpp>
  8. #include <Pothos/Util/TypeInfo.hpp>
  9. #include <Poco/Format.h>
  10. #include <Poco/Path.h>
  11. #include <iostream>
  12. #include <vector>
  13. // Expected signature: Pothos::Proxy(Pothos::ProxyEnvironment::Sptr, const CppType&)
  14. static bool isCallableConverterToEnv(const Pothos::Callable& callable)
  15. {
  16. if (callable.getNumArgs() != 2) return false;
  17. if (callable.type(-1) != typeid(Pothos::Proxy)) return false;
  18. if (callable.type(0) != typeid(Pothos::ProxyEnvironment::Sptr)) return false;
  19. return true;
  20. }
  21. // Expected signature: CppType(const Pothos::Proxy&)
  22. static bool isCallableConverterFromEnv(const Pothos::Callable& callable)
  23. {
  24. if (callable.getNumArgs() != 1) return false;
  25. if (callable.type(0) != typeid(const Pothos::Proxy&)) return false;
  26. return true;
  27. }
  28. static std::string getEnvironmentModuleFilepath(const std::string& proxyEnvName)
  29. {
  30. if ((proxyEnvName == "managed") || (proxyEnvName == "remote")) return Pothos::System::getPothosRuntimeLibraryPath();
  31. // Since we can't necessarily assume there are are specific converters or tests,
  32. // look in all potential locations for a plugin registered in paths designated
  33. // for proxy-specific plugins.
  34. const auto convertersPluginPath = "/proxy/converters/" + proxyEnvName;
  35. const auto testsPluginPath = Poco::format("/proxy/%s/tests", proxyEnvName);
  36. for (const auto& pluginLeaf : Pothos::PluginRegistry::list(convertersPluginPath))
  37. {
  38. const auto pluginPath = Poco::format("%s/%s", convertersPluginPath, pluginLeaf);
  39. const auto plugin = Pothos::PluginRegistry::get(pluginPath);
  40. return plugin.getModule().getFilePath();
  41. }
  42. for (const auto& pluginLeaf : Pothos::PluginRegistry::list(testsPluginPath))
  43. {
  44. const auto pluginPath = Poco::format("%s/%s", testsPluginPath, pluginLeaf);
  45. const auto plugin = Pothos::PluginRegistry::get(pluginPath);
  46. return plugin.getModule().getFilePath();
  47. }
  48. return "";
  49. }
  50. static void printConverters(const std::string& proxyEnvName)
  51. {
  52. const auto convertersPluginPath = "/proxy/converters/" + proxyEnvName;
  53. if (Pothos::PluginRegistry::exists(convertersPluginPath))
  54. {
  55. std::vector<Pothos::Callable> convertersToEnvironment;
  56. std::vector<Pothos::ProxyConvertPair> convertersFromEnvironment;
  57. for (const auto& pluginLeaf : Pothos::PluginRegistry::list(convertersPluginPath))
  58. {
  59. const auto pluginPath = Poco::format("%s/%s", convertersPluginPath, pluginLeaf);
  60. const auto plugin = Pothos::PluginRegistry::get(pluginPath);
  61. if (plugin.getObject().type() == typeid(Pothos::Callable))
  62. {
  63. auto pluginCallable = plugin.getObject().extract<Pothos::Callable>();
  64. if (isCallableConverterToEnv(pluginCallable)) convertersToEnvironment.emplace_back(std::move(pluginCallable));
  65. }
  66. else if (plugin.getObject().type() == typeid(Pothos::ProxyConvertPair))
  67. {
  68. auto pluginPair = plugin.getObject().extract<Pothos::ProxyConvertPair>();
  69. if (isCallableConverterFromEnv(pluginPair.second)) convertersFromEnvironment.emplace_back(std::move(pluginPair));
  70. }
  71. }
  72. if (!convertersToEnvironment.empty())
  73. {
  74. std::cout << std::endl << "Types directly convertible to environment:" << std::endl;
  75. for (const auto& converterCallable : convertersToEnvironment)
  76. {
  77. std::cout << " * " << Pothos::Util::typeInfoToString(converterCallable.type(1)) << std::endl;
  78. }
  79. }
  80. if (!convertersFromEnvironment.empty())
  81. {
  82. std::cout << std::endl << "Type conversions from environment:" << std::endl;
  83. for (const auto& converterPair : convertersFromEnvironment)
  84. {
  85. std::cout << " * " << converterPair.first << " -> " << Pothos::Util::typeInfoToString(converterPair.second.type(-1)) << std::endl;
  86. }
  87. }
  88. }
  89. }
  90. static void printTests(const std::string& proxyEnvName)
  91. {
  92. const auto testsPluginPath = Poco::format("/proxy/%s/tests", proxyEnvName);
  93. if (Pothos::PluginRegistry::exists(testsPluginPath))
  94. {
  95. std::cout << std::endl << "Self-tests:" << std::endl;
  96. for (const auto& pluginLeaf : Pothos::PluginRegistry::list(testsPluginPath))
  97. {
  98. std::cout << " * " << pluginLeaf << std::endl;
  99. }
  100. }
  101. }
  102. void PothosUtilBase::printProxyEnvironmentInfo(const std::string&, const std::string&)
  103. {
  104. Pothos::ScopedInit init;
  105. const auto proxyEnvName = this->config().getString("proxyEnvName");
  106. if (proxyEnvName.empty())
  107. {
  108. std::cout << ">>> Specify --proxy-environment-info=proxyEnvName for more information..." << std::endl;
  109. std::cout << ">>> Available proxy environments are:" << std::endl;
  110. for (const auto& name : Pothos::PluginRegistry::list("/proxy"))
  111. {
  112. if (name != "converters") std::cout << " * " << name << std::endl;
  113. }
  114. std::cout << std::endl;
  115. return;
  116. }
  117. std::cout << "Proxy environment " << proxyEnvName << " (" << getEnvironmentModuleFilepath(proxyEnvName) << ")" << std::endl;
  118. printConverters(proxyEnvName);
  119. printTests(proxyEnvName);
  120. }