In a couple of months I'll be part of a large(ish) project, and there's good chances my team will be a lot bigger, with at least 2 programmers (probably 3) and some 3-5, or more, consumers of the API we'll build (we're building a game, and they'll script high level logic using a scripting language we've yet to choose).
Now, last project I was in I used the below mentioned technique with "great" success when generating structures for use in mapping configuration files. Problem is, this will be a first timer for me in building an API with several developers and multiple consumers, and I have no idea how well it will scale.
tl;dr:
- Is this system intuitive enough and scale-able enough for someone (you!), without pre-existent knowledge of the system, to pick it up and extend it without much issue?
- If not, how should I go about building something that achieves the same but lets me skip all the repetitive cruft?
- Can you spot any gotchas I've overlooked?
These examples uses python 2.7 and pybind11 (for binding structures to python). When properly linked against python they're buildable and runnable.
#include <pybind11/pybind11.h>
namespace py = pybind11;
#define PLUGIN PYBIND11_PLUGIN
#define PLUGIN_BEGIN(TYPE, NAME, DESCR) \
PLUGIN(TYPE) \
{ \
typedef TYPE Type; \
py::module Module (NAME, DESCR); \
py::class_<Type> Binding(Module, #NAME);\
#define PLUGIN_END \
return Module.ptr(); \
} \
#define PLUGIN_MAP_FIELD(NAME) \
Binding.def_readwrite(#NAME, &Type::NAME);\
#define PLUGIN_MAP_PROPERTY(NAME) \
Binding.def_property(#NAME, &Type::get##NAME, &Type::set##NAME);\
And then you use it as so:
#include <string>
struct SPerson
{
unsigned int Age;
std::string getName( void ) { return m_Name; }
void setName( const std::string name ) { m_Name = name; }
private:
std::string m_Name;
};
PLUGIN_BEGIN(SPerson, "Person", "A person descriptor")
PLUGIN_MAP_FIELD(Age)
PLUGIN_MAP_PROPERTY(Name)
PLUGIN_END