Skip to content

Commit

Permalink
Add plugin name accessor (#29)
Browse files Browse the repository at this point in the history
Closes #5

* Update plugin tests
* Fix indentation in PrettyStr

Signed-off-by: Nick Lamprianidis <[email protected]>
  • Loading branch information
nlamprian authored Oct 29, 2020
1 parent e77d5ae commit 4a87904
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 22 deletions.
14 changes: 10 additions & 4 deletions core/include/ignition/plugin/Plugin.hh
Original file line number Diff line number Diff line change
Expand Up @@ -120,13 +120,13 @@ namespace ignition
std::shared_ptr<const Interface> QueryInterfaceSharedPtr(
const std::string &/*_interfaceName*/) const;

/// \brief Returns true if this Plugin has the specified type of
/// interface.
/// \brief Checks if this Plugin has the specified type of interface.
/// \return Returns true if this Plugin has the specified type of
/// interface, and false otherwise.
public: template <class Interface>
bool HasInterface() const;

/// \brief Returns true if this Plugin has the specified type of
/// interface, otherwise returns false.
/// \brief Checks if this Plugin has the specified type of interface.
///
/// By default, we expect you to pass in a demangled version of the
/// interface name. If you want to use a mangled version of the name,
Expand All @@ -137,9 +137,15 @@ namespace ignition
/// \param[in] _demangled If _interfaceName is demangled, set this to
/// true. If you are instead using the raw mangled name that gets provided
/// by typeid(T).name(), then set _demangled to false.
/// \return Returns true if this Plugin has the specified type of
/// interface, and false otherwise.
public: bool HasInterface(const std::string &_interfaceName,
const bool _demangled = true) const;

/// \brief Gets the name of this Plugin.
/// \return A pointer to the name of this Plugin, or nullptr if this
/// Plugin is not instantiated.
public: const std::string *Name() const;

// -------------------- Private API -----------------------

Expand Down
9 changes: 9 additions & 0 deletions core/src/Plugin.cc
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,15 @@ namespace ignition
return (this->dataPtr->interfaces.count(_interfaceName) != 0);
}

//////////////////////////////////////////////////
const std::string *Plugin::Name() const
{
if (!this->dataPtr->info)
return nullptr;

return &this->dataPtr->info->name;
}

//////////////////////////////////////////////////
Plugin::Plugin()
: dataPtr(new Implementation)
Expand Down
2 changes: 1 addition & 1 deletion loader/src/Loader.cc
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ namespace ignition
}
else
{
pretty << "has no aliases\n";
pretty << "\t\t\thas no aliases\n";
}

const std::size_t iSize = plugin->interfaces.size();
Expand Down
62 changes: 45 additions & 17 deletions test/integration/plugin.cc
Original file line number Diff line number Diff line change
Expand Up @@ -58,32 +58,50 @@ TEST(Loader, LoadExistingLibrary)
// Make sure the expected plugins were loaded.
std::unordered_set<std::string> pluginNames =
pl.LoadLib(IGNDummyPlugins_LIB);
ASSERT_EQ(3u, pluginNames.size());
ASSERT_EQ(1u, pluginNames.count("test::util::DummySinglePlugin"));
ASSERT_EQ(1u, pluginNames.count("test::util::DummyMultiPlugin"));
ASSERT_EQ(1u, pluginNames.count("test::util::DummyNoAliasPlugin"));

std::cout << pl.PrettyStr();

// Make sure the expected interfaces were loaded.
EXPECT_EQ(7u, pl.InterfacesImplemented().size());
EXPECT_EQ(1u, pl.InterfacesImplemented().count(
"test::util::DummyDoubleBase"));
EXPECT_EQ(1u, pl.InterfacesImplemented().count(
"test::util::DummyGetObjectBase"));
EXPECT_EQ(1u, pl.InterfacesImplemented().count("test::util::DummyIntBase"));
EXPECT_EQ(1u, pl.InterfacesImplemented().count(
"test::util::DummySetterBase"));
EXPECT_EQ(1u, pl.InterfacesImplemented().count(
"ignition::plugin::EnablePluginFromThis"));
EXPECT_EQ(1u, pl.InterfacesImplemented().count(
"test::util::DummyGetPluginInstancePtr"));
EXPECT_EQ(1u, pl.InterfacesImplemented().count("test::util::DummyNameBase"));

// Make sure the expected number of plugins implements each interface.

EXPECT_EQ(3u, pl.PluginsImplementing<::test::util::DummyNameBase>().size());
EXPECT_EQ(3u, pl.PluginsImplementing("test::util::DummyNameBase").size());
EXPECT_EQ(3u, pl.PluginsImplementing(
typeid(test::util::DummyNameBase).name(), false).size());
typeid(test::util::DummyNameBase).name(), false).size());

EXPECT_EQ(1u, pl.PluginsImplementing<::test::util::DummyDoubleBase>().size());
EXPECT_EQ(1u, pl.PluginsImplementing("test::util::DummyDoubleBase").size());
EXPECT_EQ(1u, pl.PluginsImplementing(
typeid(test::util::DummyDoubleBase).name(), false).size());
typeid(test::util::DummyDoubleBase).name(), false).size());

EXPECT_EQ(3u, pl.AllPlugins().size());

// Check DummySinglePlugin.
ignition::plugin::PluginPtr firstPlugin =
pl.Instantiate("test::util::DummySinglePlugin");
EXPECT_FALSE(firstPlugin.IsEmpty());
EXPECT_TRUE(static_cast<bool>(firstPlugin));

EXPECT_EQ(std::string("test::util::DummySinglePlugin"), *firstPlugin->Name());

EXPECT_TRUE(firstPlugin->HasInterface<test::util::DummyNameBase>());
EXPECT_TRUE(firstPlugin->HasInterface("test::util::DummyNameBase"));

Expand All @@ -96,10 +114,13 @@ TEST(Loader, LoadExistingLibrary)
EXPECT_FALSE(firstPlugin->HasInterface<test::util::DummySetterBase>());
EXPECT_FALSE(firstPlugin->HasInterface("test::util::DummySetterBase"));

// Check DummyMultiPlugin.
ignition::plugin::PluginPtr secondPlugin =
pl.Instantiate("test::util::DummyMultiPlugin");
EXPECT_FALSE(secondPlugin.IsEmpty());

EXPECT_EQ(std::string("test::util::DummyMultiPlugin"), *secondPlugin->Name());

EXPECT_TRUE(secondPlugin->HasInterface<test::util::DummyNameBase>());
EXPECT_TRUE(secondPlugin->HasInterface("test::util::DummyNameBase"));

Expand All @@ -112,38 +133,42 @@ TEST(Loader, LoadExistingLibrary)
EXPECT_TRUE(secondPlugin->HasInterface<test::util::DummySetterBase>());
EXPECT_TRUE(secondPlugin->HasInterface("test::util::DummySetterBase"));

// Check that the DummyNameBase interface exists and that it returns the
// correct value.
// Check that the right interfaces for each plugin exist (or don't exist) and
// that they return the correct values.

// DummyNameBase interface by DummySinglePlugin.
test::util::DummyNameBase* nameBase =
firstPlugin->QueryInterface<test::util::DummyNameBase>();
ASSERT_NE(nullptr, nameBase);
EXPECT_EQ(std::string("DummySinglePlugin"), nameBase->MyNameIs());

// Check that DummyDoubleBase does not exist for this plugin
// No DummyDoubleBase interface by DummySinglePlugin.
test::util::DummyDoubleBase* doubleBase =
firstPlugin->QueryInterface<test::util::DummyDoubleBase>();
EXPECT_EQ(nullptr, doubleBase);

// Check that DummyDoubleBase does exist for this function and that it returns
// the correct value.
// DummyNameBase interface by DummyMultiPlugin.
nameBase = secondPlugin->QueryInterface<test::util::DummyNameBase>();
ASSERT_NE(nullptr, nameBase);
EXPECT_EQ(std::string("DummyMultiPlugin"), nameBase->MyNameIs());

// DummyDoubleBase interface by DummyMultiPlugin.
doubleBase = secondPlugin->QueryInterface<test::util::DummyDoubleBase>();
ASSERT_NE(nullptr, doubleBase);
EXPECT_NEAR(3.14159, doubleBase->MyDoubleValueIs(), 1e-8);

// Check that the DummyNameBase interface exists for this plugin and that it
// returns the correct value.
nameBase = secondPlugin->QueryInterface<test::util::DummyNameBase>();
ASSERT_NE(nullptr, nameBase);
EXPECT_EQ(std::string("DummyMultiPlugin"), nameBase->MyNameIs());
// DummyIntBase interface by DummyMultiPlugin.
test::util::DummyIntBase* intBase =
secondPlugin->QueryInterface<test::util::DummyIntBase>();
EXPECT_EQ(5, intBase->MyIntegerValueIs());

// DummyGetObjectBase interface by DummyMultiPlugin.
test::util::DummyGetObjectBase *objectBase =
secondPlugin->QueryInterface<test::util::DummyGetObjectBase>();
secondPlugin->QueryInterface<test::util::DummyGetObjectBase>();
ASSERT_NE(nullptr, objectBase);

test::util::DummyObject object = objectBase->GetDummyObject();
EXPECT_EQ(secondPlugin->QueryInterface<test::util::DummyIntBase>()
->MyIntegerValueIs(), object.dummyInt);
EXPECT_NEAR(doubleBase->MyDoubleValueIs(), object.dummyDouble, 1e-8);
EXPECT_EQ(intBase->MyIntegerValueIs(), object.dummyInt);
}


Expand All @@ -163,9 +188,11 @@ TEST(SpecializedPluginPtr, Construction)
pl.LoadLib(IGNDummyPlugins_LIB);

SomeSpecializedPluginPtr plugin(
pl.Instantiate("test::util::DummyMultiPlugin"));
pl.Instantiate("test::util::DummyMultiPlugin"));
EXPECT_FALSE(plugin.IsEmpty());

EXPECT_EQ(std::string("test::util::DummyMultiPlugin"), *plugin->Name());

// Make sure the specialized interface is available, that it is accessed using
// the specialized access, and that it returns the expected value.
usedSpecializedInterfaceAccess = false;
Expand Down Expand Up @@ -215,6 +242,7 @@ TEST(PluginPtr, Empty)
{
ignition::plugin::PluginPtr empty;
EXPECT_TRUE(empty.IsEmpty());
EXPECT_EQ(nullptr, empty->Name());
EXPECT_FALSE(empty->HasInterface<SomeInterface>());
EXPECT_FALSE(static_cast<bool>(empty));
EXPECT_EQ(nullptr, empty->QueryInterfaceSharedPtr<SomeInterface>());
Expand Down
2 changes: 2 additions & 0 deletions test/integration/templated_plugins.cc
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ void TestSetAndGet(const ignition::plugin::Loader &_pl,
const SetAndGetPluginPtr<T> plugin = _pl.Instantiate(pluginName);
ASSERT_TRUE(static_cast<bool>(plugin));

EXPECT_EQ(pluginName, *plugin->Name());

usedSpecializedInterfaceAccess = false;
ASSERT_TRUE(plugin->template HasInterface<SetInterface>());
EXPECT_TRUE(usedSpecializedInterfaceAccess);
Expand Down

0 comments on commit 4a87904

Please sign in to comment.