Extract variables from Lua into C++ - c++

I'm working on a numerical C++ code. This C++ code has a config file with physical parameters of my system. I would like to be able to do mathematical computations and some programming in a config file. Lua seems perfect.
suppose my lua file computes variable vol and mass:
method = cube
len = 3
rho = 1.5
vol = len*len*len
mass = vol*rho
I'd like to pass vol and mass to C++ code. I also would like to pass method, which is a std::string.
I can do something like this. However, in this example, they go through elements of a table one-by-one without relying on the variables' names. I'd like C++ to extract values of variables based on their names. also the structure of the lua config code may be more complicated; I might be writing few functions to get those values.

I think you can make function such as GetGlobal(name), which will basically return the value of given variable. Then call this function from C++ with appriopriate parameter pushed onto the stack, and take the result from the stack.
Additionally, it might be worth protecting your code from variables with wrong type, using lua_is* functions.
I can post you the more complete solution of the code, but I didn't want you to spoil you the fun of writing it yourself ;), so let me know shall you need any additional information.

Related

How to automatically initialize component parameters?

While doing a game engine that uses .lua files in order to read parameter values, I got stuck when I had to read these values and assign them to the parameters of each component in C++. I tried to investigate the way Unity does it, but I didn't find it (and I'm starting to doubt that Unity has to do it at all).
I want the parameters to be initialized automatically, without the user having to do the process of
myComponentParameter = readFromLuaFile("myParameterName")
for each one of the parameters.
My initial idea is to use the std::variant type, and storing an array of variants in order to read them automatically. My problems with this are:
First of all, I don't know how to know the type that std::variant is storing at the moment (tried with std::variant::type, but it didn't work for the template), in order to cast from the untyped .lua value to the C++ value. For reference, my component initialization looks like this:
bool init(luabridge::LuaRef parameterTable)
{
myIntParameter = readVariable<int>(parameterTable, "myIntParameter");
myStringParameter = readVariable<std::string>(parameterTable, "myStringParameter");
return true;
}
(readVariable function is already written in this question, in case you're curious)
The second problem is that the user would have to write std::get(myIntParameter); whenever they want to access to the value stored by the variant, and that sounds like something worse than making the user read the parameter value.
The third problem is that I can't create an array of std::variant<any type>, which is what I would like to do in order to automatically initialize the parameters.
Is there any good solution for this kind of situation where I want the init function to not be necessary, and the user doesn't need to manually set up the parameter values?
Thanks in advance.
Let's expand my comment. In a nutshell, you need to get from
"I have some things entered by the user in some file"
to:
"the client code can read the value without std::get"
…which roughly translates to:
"input validation was done, and values are ready for direct use."
…which implies you do not store your variables in variants.
In the end it is a design question. One module somewhere must have the knowledge of which variable names exist, and the type of each, and the valid values.
The input of that module will be unverified values.
The output of the module will probably be some regular c++ struct.
And the body of that module will likely have a bunch of those:
config.foo = readVariable<int>("foo");
config.bar = readVariable<std::string>("bar");
// you also want to validate values there - all ints may not be valid values for foo,
// maybe bar must follow some specific rules, etc
assuming somewhere else it was defined as:
struct Configuration {
int fooVariable;
std::string bar;
};
Where that module lives depends on your application. If all expected types are known, there is no reason to ever use a variant, just parse right away.
You would read to variants if some things do not make sense until later. For instance if you want to read configuration values that will be used by plugins, so you cannot make sense of them yet.
(actually even then simply re-parsing the file later, or just saving values as text for later parsing would work)

Where should the user-defined parameters of a framework be ?

I am kind of a newbie and I am creating a framework to evolve objects in C++ with an evolutionary algorithm.
An evolutionary algorithm evolves objects and tests them to get the best solution (for example, evolve the weights neural network and test it on sample data, so that in the end you get a network which has a good accuracy, without having trained it).
My problem is that there are lots of parameters for the algorithm (type of selection/crossover/mutation, probabilities for each of them...) and since it is a framework, the user should be able to easily access and modify them.
CURRENT SOLUTION
For now, I created a header file parameters.h of this form:
// DON'T CHANGE THESE PARAMETERS
//mutation type
#define FLIP 1
#define ADD_CONNECTION 2
#define RM_CONNECTION 3
// USER DEFINED
static const int TYPE_OF_MUTATION = FLIP;
The user modifies the static variables TYPE_OF_MUTATION and then my mutation function tests what the value of TYPE_OF_MUTATION is and calls the right mutation function.
This works well, but it has a few drawbacks:
when I change a parameter in this header and then call "make", no change is taken into account, I have to call "make clean" then "make". From what I saw, it is not a problem in the makefile but it is how building works. Even if it did re-build when I change a parameter, it would mean re-compile the whole project as these parameters are used everywhere; it is definitely not efficient.
if you want to run the genetic algorithm several times with different parameters, you have to run it a first time then save the results, change the parameters then run it a second time etc.
OTHER POSSIBILITIES
I thought about taking these parameters as arguments of the top-level function. The problem is that the function would then take 20 arguments or so, it doesn't seem really readable...
What I mean about the top-level function is that for now, the evolutionary algorithm is run simply by doing this:
PopulationManager myPop;
myPop.evolveIt();
If I defined the parameters as arguments, we would have something like:
PopulationManager myPop;
myPop.evolveIt(20,10,5,FLIP,9,8,2,3,TOURNAMENT,0,23,4);
You can see how hellish it may be to always define parameters in the right order !
CONCLUSION
The frameworks I know make you build your algorithm yourself from pre-defined functions, but the user shouldn't have to go through all the code to change parameters one by one.
It may be useful to indicate that this framework will be used internally, for a definite set of projects.
Any input about the best way to define these parameters is welcome !
If the options do not change I usually use a struct for this:
enum class MutationType {
Flip,
AddConnection,
RemoveConnection
};
struct Options {
// Documentation for mutation_type.
MutationType mutation_type = MutationType::Flip;
// Documentation for integer option.
int integer_option = 10;
};
And then provide a constructor that takes these options.
Options options;
options.mutation_type = MutationType::AddConnection;
PopulationManager population(options);
C++11 makes this really easy, because it allows specifying defaults for the options, so a user only needs to set the options that need to be different from the default.
Also note that I used an enum for the options, this ensures that the user can only use correct values.
This is a classic example of polymorphism. In your proposed implementation you're doing a switch on constant to decide which polymorphic mutation algorithm you will choose to decide how to mutate the parameter. In C++, the corresponding mechanisms are templates (static polymorphism) or virtual functions (dynamic polymorphism) to select the appropriate mutating algorithm to apply to the parameter.
The templates way has the advantage that everything is resolvable at compile time and the resulting mutating algorithm could be inlined entirely, depending on the implementation. What you give up is the ability to dynamically select parameter mutation algorithms at runtime.
The virtual function way has the advantage that you can defer the choice of mutation algorithm until runtime, allowing this to vary based on input from the user or whatnot. The disadvantage is that the mutation algorithm can no longer be inlined and you pay the cost of a virtual function call (an extra level of indirection) when you mutate the parameter.
If you want to see a real example of how "algorithmic mutation" can work, look at evolve.cpp in my Iterated Dynamics repository on github. This is C code converted to C++ so it is neither using templates nor using virtual functions. Instead it uses function pointers and a switch-on-constant to select the appropriate code. However, the idea is the same.
My recommendation would be to see if you can use static polymorphism (templates) first. From your initial description you were fixing the mutation at compile-time anyway, so you're not giving anything up.
If that was just a prototyping phase and you intended to support switching of mutation algorithms at runtime, then look at virtual functions. As the other answer recommended, please shun C-style coding like #define constants and instead use proper enums.
To solve the "long parameter list smell", the idea of packing all the parameters into a structure is a good one. You can achieve more readability on top of that by using the builder pattern to build up the structure of parameters in a more readable way than just assigning a bunch of values into a struct. In this blog post, I applied the builder pattern to the resource description structures in Direct3D. That allowed me to more directly express these "bags of data" with reasonable defaults and directly reveal my intent to override or replace default values with special values when necessary.

Convert std::string to existing function with parameters in C++

I've got an implemented function MyFunc(int, double, string) in my project. How can I call this function with necessary parameters having its string representation, for example
std::string str = "MyFunc(2, 3.12, \"Lemon Juice\")";
And what about the standard functions, for example, how can I call time() having std::string "time()"?
Ok, here's more detailed task.
I've got a map <string, Data>
Data is a class-wrapper with many childs. When I call Data.GetValue() method, it returns a std::string, depending of child class inner data. One of Data childs must return the string representation of int, another - the string representation of double, and the last one - the string representation of current date and time. Here's the problem - I don't know how to call the standard function ctime() for getting information from one of Data childs.
You cannot in general execute code in C++ whose source is contained in a string. Probably the most compelling motivation for this is so that a C++ implementation is not required to have a C++ compiler on the machine that the code runs on, although there is more to it than just that.
You may be able to do it for specific cases. That could be:
Platform-specific, for example:
Wrap the source up in some boilerplate, then either call the compiler externally, link against it, or embed it in your program. This gives you a program or library.
Run that new program externally, or dynamically link against that library.
Input-specific, for example:
You could parse a function call to a particular known function, with literals as arguments, relatively easily without needing a complete C++ compiler. Get the argument values out into variables and call the function. But if you're going to do that, you could specify a more easily parsable format for the string, than one that looks like a C++ function call.
It sounds as though in your task you have a string that is one of:
a representation of an int
a representation of a double
a representation of a date and time.
You don't say what you want to do with this string, but whatever that is you probably need to (a) examine the string to find out which of the three it is, and then (b) do something appropriate to that format. Better, you could give the derived class the responsibility of returning the same representation no matter which of the three GetValue() returns. For example, if what you really want is seconds since 1970, add a GetSecondsSinceEpoc function, and implement it differently in each class.
As mentioned by others, C++ in itself is not able to do that. However external frameworks can help you.
ROOT (used at CERN) provides reflection for C++ along with an interpreter. You will be able to execute/interpret a method call or a macro written in C++ from within your code.
You can not do that using C++.

C++ howto use the same function twice with different name and different names for variables

I have a function that commands a device. This device is available twice so I need the same functionality for two devices. Out of maintenance reasons I don't want to have to code the function twice (one for each device) because then I always need to apply changes twice.
The functions are the same in principle but are supposed to work on different variables. Is it possible to instantiate this function with kind of a "varying" name, similar to template but not with classes but names?
I try to provide an example. It should look something like this.
void function_x (int Var, double Vary, ...) {
int var3_x = getFunctionFromDatabase(var3_x);
double var2_x = getFunctionFromDatabase(var2_x);
// some operations
}
The functions are applied by two instances of a Device Handler class.
The variables var1_x, var2_x and var3_x are stored in a data pool as var1_1, var1_2, var2_1, ... the "same" variable but one for each device. One Controller commands the two devices via these variables and the data pool.
Is this possible somehow?
I hope that the problem got clear ;). This is my first question here :P.
Thanks in advance for any help.
Why not use an array? E.g.
var1[0], var1[1], etc.
Use an array element for each device that you manage.
You could do some trickery with macros, but I think the code will be more clear if you use arrays.
Even if the variables are in a library that you can't change, you could set up arrays of pointers to the original variables in an initialization function. E.g.:
var1[0] = &var1_0;
var1[1] = &var1_1;
Then, function_x becomes function and would accept a parameter for the device index.
You say they have different variables, in which case it would be a simple case of overloading the function. Your example implies that you want to get the function from a database in which case you would need to use function pointers. Another option is that you have 1 function and you pass a handle (or some such) to it (as well as your arguments) to identify which device it is.

C++ Factory using lua

I had a script with:
Custom language used only for data
Was loaded using a Script class from C++
I had tags like Type, etc
An interface to get a value for a tag - Script::GetValue(Tag, T& value)
The script was used like this:
Script* script("someFile");
script->GetValue("Type", type);
Object* obj = CreateObject(type);
obj->Load(script);
Where Load functions from object was used to load the rest of obj parameters.
Now I changed the script language to lua. My questions is:
Should I keep this way of creating objects(use lua only for data) or should I expose the factory in lua and use it from lua, something like this(in lua):
CreateObject("someType")
SetProperty(someObj, someProperty, someValue)
First of all I want to know which is faster, first or second approach. Do you have other suggestions? Because I'm refactoring this part I'm open to other suggestions. I want to keep lua because is fast, easy to integrate, and small.
You may allow your script environment to create C++ objects or not, depending on your needs.
tolua++ uses all the metatable features to allow a very straightforward manipulation of your c++ types in lua.
For example, this declaration :
// tolua_begin
class SomeCppClass
{
public:
SomeCppClass();
~SomeCppClass();
int some_field;
void some_method();
};
// tolua_end
Will automatically generate the lua bindings to allow this lua scipt :
#!lua
-- obj1 must be deleted manually
local obj1 = SomeCppClass:new()
-- obj1 will be automatically garbage collected
local obj2 = SomeCppClass:new_local()
obj1.some_field = 3 -- direct access to "some_field"
obj2:some_method() -- direct call to "some_method"
obj1:delete()
The advantage of this technique is that your lua code will ve very consistent with the relying C++ code. See http://www.codenix.com/~tolua/tolua++.html
In situations like that, I prefer to setup a bound C function that takes a table of parameters as an argument. So, the Lua script would look like the following.
CreateObject{
Type = "someType"'
someProperty = someValue,
-- ...
}
This table would be on top of the stack in the callback function, and all parameters can be accessed by name using lua_getfield.
You may also want to investigate sandboxing your Lua environment.
The first approach would most likely be faster, but the second approach would probably result in less object initialization code (assuming you're initializing a lot of objects). If you choose the first approach, you can do it manually. If you choose the second approach you might want to use a binding library like Luabind to avoid errors and speed up implementation time, assuming you're doing this for multiple object types and data types.
The simplest approach will probably be to just use Lua for data; if you want to expose the factory and use it via Lua, make sure it's worth the effort first.

Categories