summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrad Bishop <bradleyb@fuzziesquirrel.com>2017-02-04 10:51:06 -0500
committerBrad Bishop <bradleyb@fuzziesquirrel.com>2017-02-14 08:12:09 -0500
commit9bbfcb180ceba3c1af4ee03cc71e5c305c3a6b8b (patch)
tree93ae4cfed4b417117bc27f7c71c3cee505923dcc
parent0237971c1e8cd102e2035f92f8e794b8e6711b2d (diff)
downloadphosphor-inventory-manager-9bbfcb180ceba3c1af4ee03cc71e5c305c3a6b8b.tar.gz
phosphor-inventory-manager-9bbfcb180ceba3c1af4ee03cc71e5c305c3a6b8b.zip
Set properties when constructing interfaces.
Make use of new sdbusplus support for passing a map of properties and their values to the interface constructor. Change-Id: Ib0dd406fd80c89acb723e3a376af26ba57b53d27 Signed-off-by: Brad Bishop <bradleyb@fuzziesquirrel.com>
-rw-r--r--manager.cpp82
-rw-r--r--manager.hpp16
-rw-r--r--test/test.cpp2
-rw-r--r--utils.hpp62
4 files changed, 122 insertions, 40 deletions
diff --git a/manager.cpp b/manager.cpp
index 1d1f778..5dcd9e5 100644
--- a/manager.cpp
+++ b/manager.cpp
@@ -16,6 +16,7 @@
#include <iostream>
#include <exception>
#include <chrono>
+#include <log.hpp>
#include "manager.hpp"
using namespace std::literals::chrono_literals;
@@ -192,53 +193,60 @@ void Manager::createObjects(
for (auto& o : objs)
{
- auto& relPath = o.first;
- auto& ifaces = o.second;
-
- absPath.assign(_root);
- absPath.append(relPath);
-
- auto obj = _refs.find(absPath);
- if (obj != _refs.end())
+ try
{
- // This object already exists...skip.
- continue;
- }
+ auto& relPath = o.first;
+ auto& ifaces = o.second;
- // Create an interface holder for each interface
- // provided by the client and group them into
- // a container.
- InterfaceComposite ref;
+ absPath.assign(_root);
+ absPath.append(relPath);
- for (auto& iface : ifaces)
- {
- auto& props = iface.second;
- auto pMakers = _makers.find(iface.first.c_str());
-
- if (pMakers == _makers.end())
+ auto obj = _refs.find(absPath);
+ if (obj != _refs.end())
{
- // This interface is not known.
+ // This object already exists...skip.
continue;
}
- auto& maker = std::get<MakerType>(pMakers->second);
+ // Create an interface holder for each interface
+ // provided by the client and group them into
+ // a container.
+ InterfaceComposite ref;
- ref.emplace(
- iface.first,
- maker(
- _bus,
- absPath.c_str(),
- props));
- }
+ for (auto& iface : ifaces)
+ {
+ auto& props = iface.second;
+ auto pMakers = _makers.find(iface.first.c_str());
+
+ if (pMakers == _makers.end())
+ {
+ // This interface is not known.
+ continue;
+ }
+
+ auto& maker = std::get<MakerType>(pMakers->second);
+
+ ref.emplace(
+ iface.first,
+ maker(
+ _bus,
+ absPath.c_str(),
+ props));
+ }
- if (!ref.empty())
+ if (!ref.empty())
+ {
+ // Hang on to a reference to the object (interfaces)
+ // so it stays on the bus, and so we can make calls
+ // to it if needed.
+ _refs.emplace(
+ absPath, std::move(ref));
+ _bus.emit_object_added(absPath.c_str());
+ }
+ }
+ catch (const std::exception& e)
{
- // Hang on to a reference to the object (interfaces)
- // so it stays on the bus, and so we can make calls
- // to it if needed.
- _refs.emplace(
- absPath, std::move(ref));
- _bus.emit_object_added(absPath.c_str());
+ logging::log<logging::level::ERR>(e.what());
}
}
}
diff --git a/manager.hpp b/manager.hpp
index 5e0930b..806a9a4 100644
--- a/manager.hpp
+++ b/manager.hpp
@@ -39,8 +39,20 @@ struct MakeInterface
const char* path,
const Interface& props)
{
- // TODO: pass props to import constructor...
- return any_ns::any(std::make_shared<T>(bus, path));
+ using PropertiesVariant = typename T::PropertiesVariant;
+ using InterfaceVariant =
+ std::map<std::string, PropertiesVariant>;
+
+ InterfaceVariant v;
+
+ for (const auto& p : props)
+ {
+ v.emplace(
+ p.first,
+ convertVariant<PropertiesVariant>(p.second));
+ }
+
+ return any_ns::any(std::make_shared<T>(bus, path, v));
}
};
diff --git a/test/test.cpp b/test/test.cpp
index 0a941f7..d36aa24 100644
--- a/test/test.cpp
+++ b/test/test.cpp
@@ -207,7 +207,7 @@ void runTests()
},
{
"xyz.openbmc_project.Example.Iface2",
- {{"ExampleProperty2", "test2"s}}
+ {{"ExampleProperty2", "test2"s}, {"ExampleProperty3", 0ll}}
},
};
diff --git a/utils.hpp b/utils.hpp
index 33de439..60119be 100644
--- a/utils.hpp
+++ b/utils.hpp
@@ -6,7 +6,69 @@ namespace inventory
{
namespace manager
{
+/** @struct MakeVariantVisitor
+ * @brief Return a variant if the visited type is a possible variant type.
+ *
+ * @tparam V - The desired variant type.
+ */
+template <typename V>
+struct MakeVariantVisitor
+{
+ /** @struct Make
+ * @brief Return variant visitor.
+ *
+ * @tparam T - The variant type to return.
+ * @tparam Arg - The type being visited in the source variant.
+ * @tparam Enable - Overload resolution removal.
+ */
+ template <typename T, typename Arg, typename Enable = void>
+ struct Make
+ {
+ static auto make(Arg&& arg)
+ {
+ throw sdbusplus::message::variant_ns::bad_variant_access(
+ "in MakeVariantVisitor");
+ return T();
+ }
+ };
+
+ /** @struct Make
+ * @brief Return variant visitor.
+ *
+ * struct Make specialization if Arg is in T (int -> variant<int, char>).
+ */
+ template <typename T, typename Arg>
+ struct Make<T, Arg,
+ typename std::enable_if<std::is_convertible<Arg, T>::value>::type>
+ {
+ static auto make(Arg&& arg)
+ {
+ return T(std::forward<Arg>(arg));
+ }
+ };
+ /** @brief Make variant visitor. */
+ template <typename Arg>
+ auto operator()(Arg&& arg) const
+ {
+ return Make<V, Arg>::make(arg);
+ }
+};
+
+/** @brief Convert variants with different contained types.
+ *
+ * @tparam V - The desired variant type.
+ * @tparam Arg - The source variant type.
+ *
+ * @param[in] v - The source variant.
+ * @returns - The converted variant.
+ */
+template <typename V, typename Arg>
+auto convertVariant(Arg&& v)
+{
+ return sdbusplus::message::variant_ns::apply_visitor(
+ MakeVariantVisitor<V>(), v);
+}
} // namespace manager
} // namespace inventory
} // namespace phosphor
OpenPOWER on IntegriCloud