I need a way to fake reflection in C++ code that makes as few
assumptions about the data types involved as possible. I suspect
there is no good answer for what I need to do, but I'll present the
case anyway.
We have a class that normally registers with another service, which
then executes callbacks in our class. Since that other service isn't
going to be available for testing for a while, we're simulating it
with a simple script-based driver. The callbacks look something like:
class MyListener : public baseListener
{
public:
onSubscribe (const MyQueryType& query);
onUnsubscribe (const MyQueryType& query);
onChanged(const MyQueryType& oldQuery, const myQueryType&
newQuery);
// etc., etc., etc.
};
There are potentially going to be many different types of listeners,
each taking a different query object type.
The format of the script is:
subscribe <MyQueryType>{parm1 = value1; parm2 = value2; parmN =
valueN;}
unsubscribe <MyQueryType>{parm1 = value1; parm2 = value2; parmN =
valueN;}
subscribe <MyQueryType>{parm1 = value1;}
As you can see, some parameters for the query type may be left
unspecified.
Now, here's my problem: I need to take a text description of an object
and translate that into a real object, setting its parameters. IOW,
at runtime I need to go from a string of text that says:
subscribe <MyQueryType>{parm1 = value1; parm2 = value2; parmN =
valueN;}
to executing the equivalent of the following code:
MyQueryType newQuery;
newQuery.parm1 = value1;
newQuery.parm2 = value2;
newQuery.parmN = valueN;
m_listener.Subscribe(newQuery);
but doing so in a way that isn't hard-coded, or that relies on an
implementation for every possible query type.
I need some way to fake reflection, where I could maybe do something
like
genericQueryObject = CreateObject(typeName);
genericQueryObject.Set(paramName, paramValue);
... // repeat for each parameter
m_listener.Subscribe(genericQueryObject.GetQuery() );
without having to write a specific implementation for every possible
query type class. IOW, I don't want to have to do this:
void MyQueryTypeHandler::Set(string paramName, string value)
{
if (paramName == "lat")
lat = convertToFloat(value);
else if (paramName == "lon")
lon = convertToFloat(value);
...
}
for each query type, especially since I don't know what query types
are going to be generated in the future.
Just being able to refer to members by name would be a *huge* help,
but I suspect there's no good answer for what I need to do, and that I
am going to have to some variation of the Set function above, but if
anyone has any pointers, I'd be glad to hear them.