envire / envire-envire_core

Core part for the Environment Representation library
BSD 2-Clause "Simplified" License
7 stars 13 forks source link

Add macro to register multiple items in one file #25

Open AlexanderFabisch opened 6 years ago

AlexanderFabisch commented 6 years ago

I open this issue to keep track of the current state of the discussion.

Registering multiple item types in one file is currently not possible, e.g.

#include <envire_core/plugin/Plugin.hpp>

#include <base/samples/RigidBodyState.hpp>
ENVIRE_REGISTER_ITEM(base::samples::RigidBodyState)
#include <base/samples/Pointcloud.hpp>
ENVIRE_REGISTER_ITEM(base::samples::Pointcloud)

The reason is that ENVIRE_REGISTER_METADATA expands to

#define ENVIRE_REGISTER_METADATA( _classname, _datatype ) \
static envire::core::MetadataInitializer _metadataInit(typeid(_classname), #_datatype, #_classname);

which means that _metadataInit is declared more than once. We cannot simply rename it to _metadataInit##_datatype because _datatype might contain namespaces (::). One option would be to define an additional macro ENVIRE_REGISTER_ITEM(_datatype, _variableName).

Unfortunately I cannot really use this in my use case because at the moment I need ENVIRE_REGISTER_ITEM without the serialization feature because there is no boost serialization for the basetypes that I want to register.

My temporary solution for both problems is

#include <envire_core/plugin/Plugin.hpp>
#include <envire_core/items/Item.hpp>

#define ENVIRE_REGISTER_MULTI_METADATA( _classname, _datatype, _variable ) \
static envire::core::MetadataInitializer _metadataInit##_variable(typeid(_classname), #_datatype, #_classname);
#define ENVIRE_REGISTER_MULTI_ITEM_WITHOUT_SERIALIZATION( _datatype, _variable ) \
CLASS_LOADER_REGISTER_CLASS(envire::core::Item<_datatype>, envire::core::ItemBase) \
ENVIRE_REGISTER_MULTI_METADATA(envire::core::Item<_datatype>, _datatype, _variable)

#include <base/samples/RigidBodyState.hpp>
using base::samples::RigidBodyState;
ENVIRE_REGISTER_MULTI_ITEM_WITHOUT_SERIALIZATION(base::samples::RigidBodyState, 1)
#include <base/samples/Pointcloud.hpp>
ENVIRE_REGISTER_MULTI_ITEM_WITHOUT_SERIALIZATION(base::samples::Pointcloud, 2)

As soon as there is boost serialization functionality for basetypes, I would implement ENVIRE_REGISTER_ITEM(_datatype, _variableName).

But maybe there is a completely different solution to run code once after starting the program that does not rely on some static variable that is defined in the file.

AlexanderFabisch commented 6 years ago

@arneboe to inform you.

saarnold commented 6 years ago

To fix the first problem you can change ENVIRE_REGISTER_METADATA to:

#define ENVIRE_REGISTER_METADATA( _classname, _datatype, _unique_id ) \
static envire::core::MetadataInitializer _metadataInit##_unique_id(typeid(_classname), #_datatype, #_classname);

And then call it with ENVIRE_REGISTER_METADATA( _classname, _datatype, __COUNTER__ ) to get a unique variable name.

For the second we would need to implement the support to load typekit plugins in envire.