Instantiating shared_ptr's in boost::python - c++

I had a question about boost python. I've been working on exporting some functionality of a project into boost python, and I haven't found a way to solve the following problem:
I have a set of StatusEffect objects that i store and use throughout the game. At the game startup, I want to be able to call a python script that will populate/add to the set of status effect objects. I'm having no problems exposing the StatusEffect class and it's derived class to python and calling the script.
The problem is that I'm storing that StatusEffect objects in an std::vector<boost::shared_ptr<StatusEffect> > Effects;
I have no idea how to create new instances of boost::shared_ptr<StatusEffect> aside from the method of adding a static create method as described here http://wiki.python.org/moin/boost.python/PointersAndSmartPointers Given the large number of constructors and the wide variety of derived classes I have, this seems an unoptimal solution at best. I'd like to be able to create instances of boost::shared_ptr directly using the constructors of the StatusEffect objects, and be able to add those to the vector. Is this possible?
An answer or some helpful suggestions would be helpful. I asked a simialr question yesterday but unfortunately it wasn't of much help.
Thanks in advance

I hope I am understanding your question. If you declare your python class with the shared_ptr as shown at http://wiki.python.org/moin/boost.python/PointersAndSmartPointers, then boost::python will automatically convert StatusEffect objects you create in python to shared_ptr<StatusEffect> if necessary (you can try this e.g. by .def-ing a function which takes const shared_ptr<StatusEffect>& or shared_ptr<StatusEffect> as argument, and call it with StatusEffect instance created in python.
If you want to assign an attribute of type vector<shared_ptr<StatusEffect> >, you must create converters for it (from python sequences, and back), that's described in documentation. For an example, see c++ to python converter template (line 120), python to c++ template (line 127), and then using it for various types (including shared_ptr's) contained in the sequences (line 212).
Then you can write something like yourObject.listOfStatusEffects=[StatusEffect(),StatusEffect(),StatusEffect()]

Related

Creating a new c++ object from within a lua script?

---Context---
I want to have a class called "fileProcessor". This class is completely static and merely serves as a convinient namespace (within my normal library namespace) for some global function. This is a basic blueprint of the class with only the relevant stuff
class fileProcessor{
private:
lua_State* LUA_state;
public:
static std::variant<type1,type2> processFile(const char* filePath,const char* processorScript);
}
Please note again that I ommitted most of the stuff from the class so if anything seems odd ignore it.
What process file is supposed to do is:
Read the filePath file, storing all directives including it (this is my own filetype or style of syntax. This is already handeled correctly). The directives are stored with strings, one for the command and one for everything after it.
Read the script file and check if it has a commented out fileProcessor line at the top. This is to make sure that the lua script loaded is relevant and not some random behaviour script
Load and compile the lua script.
Make all read directives available (they are saved in a struct of 2 strings as mentioned before)
Run the file and recieve a object back. The object should only be of types that I listed in the return type (variant)
I am having problems with step 4 and one vital part of the scripting.
---Question---
How can I make the creation of a full new object of type1 or type2 possible within lua, write to it from within lua and then get it back from the lua stack into c++ and still know if its type1 or type2?
---No example provided since this question is more general and the only reason I provided my class is for context.---
It seems like you are trying to do it the other way around. I quote a part of this answer:
...you are expecting Lua to be the primary language, and C++ to be the client. The problem is, that the Lua C interface is not designed to work like that, Lua is meant to be the client, and all the hard work is meant to be written in C so that Lua can call it effortlessly.
If you are convinced there is no other way that doing it other way around you can follow the workaround that answer has given. Otherwise I think you can achieve what you need by using LUA as it meant to be.
LUA has 8 basic types (nil, boolean, number, string, userdata, function, thread, and table). But you can add new types as you require by creating a class as the new type in native C++ and registering it with LUA.
You can register by either:
Using some LUA helper for C++ like luna.h (as shown in this tutorial).
Pushing a new lua table with the C++ class (check this answer).
Class object instance is created in your native C++ code and passed to LUA. LUA then makes use of the methods given by the class interface.

Documenting fake classes

I have a function which exposes all of my required C++ functions to Lua, there are various tables representing different aspects of my "Scripting API", what I wish to do is use doxygen to make a scripting reference using the C++ code that exposes these script functions.
I have tried to make 'fake' classes in the body of the function, which successfully makes a new entry with the name I have given it, for instance if I make a table named 'Math' which has several functions exposed on it, how would I also make 'fake' member functions in this 'fake' class, I have tried to simply pass in \fn defining the function, however it does not show up as they are not actually real members to add a description to. How would I create this sort of effect in doxygen without hand righting a verbatim definition of every class, but instead treat the comment block as if it were a real class with real members?
It sounds like you're trying to document Lua code as if they were C++. Maybe it's possible, but it's probably more trouble than it's worth.
If you're trying to document Lua code with doxygen, maybe you could try doxygen-lua.
If your Lua API is small, you could just write a page by hand, with \ref's to the relavent C++ code. (Kind of hacky, but I've done this before.)
You could also consider using some other doc generator for your Lua API, such as LuaDoc, or anything else listed on the lua-users wiki DocumentingLuaCode.
I ended up writing a fake .doxy file which had typenames similar to lua values, apparently doxygen will document any type to throw at it.

Suggestion on C++ object serialization techniques

I'm creating a C++ object serialization library. This is more towards self-learning and enhancements & I don't want to use off-the-shelf library like boost or google protocol buf.
Please share your experience or comments on good ways to go about it (like creating some encoding with tag-value etc).
I would like to start by supporting PODs followed by support to non-linear DSs.
Thanks
PS: HNY2012
If you need serialization for inter process communication, then I suggest to use some interface language (IDL or ASN.1) for defining interfaces.
So it will be easier to make support for other languages (than C++) too. And also, it will be easier to implement code/stub generator.
I have been working on something similar for the last few months. I couldn't use Boost because the task was to serialize a bunch of existing classes (huge existing codebase) and it was inappropriate to have the classes inherit from the interface which had the serialize() virtual function (we did not want multiple inheritance).
The approach taken had the following salient features:
Create a helper class for each existing class, designated with the task of serializing that particular class, and make the helper class a friend of the class being serialized. This avoids introduction of inheritance in the class being serialized, and also allows the helper class access to private variables.
Have each of the helper classes (let's call them 'serializers') register themselves into a global map. Each serializer class implements a clone() virtual function ('prototype' pattern), which allows one to retrieve a pointer to a serializer, given the name of the class, from this map. The name is obtained by using compiler-specific RTTI information. The registration into the global map is taken care of by instantiating static pointers and 'new'ing them, since static variables get created before the program starts.
A special stream object was created (derived from std::fstream), that contained template functions to serialize non-pointer, pointer, and STL data types. The stream object could only be opened in read-only or write-only modes (by design), so the same serialize() function could be used to either read from the file or write into the file, depending on the mode in which the stream was opened. Thus, there is no chance of any mismatch in the order of reading versus writing of the class members.
For every object being saved or restored, a unique tag (integer) was created based on the address of the variable and stored in a map. If the same address occurred again, only the tag was saved, not the deep-copied object itself. Thus, each object was deep copied only once into the file.
A page on the web captures some of these ideas shared above: http://www.cs.sjsu.edu/~pearce/modules/lectures/cpp/Serialization.htm. Hope that helps.
I wrote an article some years ago. Code and tools can be obsolete, but concepts can remain the same.
May be this can help you.

exposing boost::tuple part of class to boost python

I've been trying to figure out how to expose a property in my class that is a boost::tuple. The tuple is defined as follows:
typedef boost::shared_ptr<Action> action_ptr;
typedef boost::tuple<BattleCharacter*, action_ptr > ActionTargetTuple;
It's contained with a class defined as follows:
class Action : public Cloneable<Action>
{
public:
//Irrelevant Code Omitted
std::vector<ActionTargetTuple> Targets;
}
I've seen numerous articles while I was searching about how to convert a boost::tuple into a python tuple, but that's not what I'm looking to do. I want to be able to access the tuple as it exists on the Action class. (I know how to do the vector part).
class_<Action, std::auto_ptr<ActionWrapper> >("Action")
.def("Targets", &Action::Targets)
;
I expose it simply as above. I figured I might be able to expose it by some variation on the below:
class_<ActionTargetTuple>("ActionTargetTuple")
.def("get", &ActionTargetTuple::get<int>, return_value_policy<reference_existing_object>())
;
then use get from python, but if it is doable in this way, I'm not sure what the set up needs to be. Does anyone know how to do this/could suggest an alternative?
Thanks
You can use:
...
.add_property("Targets", & ActionTargetTuple::get, &ActionTargetTuple::set)
to make a read-write property using getter/setter methods in c++
If you want to control ownership:
namespace bp = boost::python;
...
.add_property("Targets",
bp::make_function(&ActionTargetTuple::get, bp::return_value_policy<...>()),
bp::make_function(&ActionTargetTuple::set, bp::return_value_policy<...>())
)
Besides using add_property as explained in the previous answer, and writing accessor functions, you can consider writing converters for your tuple (between boost::tuple and boost::python::tuple) and exposing those attributes directly with def_readonly or def_readwrite. It is worth it if you have many such attributes to expose.
This has a template you adapt can for c++→python conversion (use boost::tuple instead of std::pair), though unless you go c++0x, you have to write out templates for different number of arguments.
If your property is read-write, additionaly define from-python converter, you find examples on the web. Here is my code I use to define generic sequence-std::vector converter. In your case, you have to check that the python object is a sequence, that it has the right number of items, that you can extract required types from each of them; and then return new boost::tuple object.
HTH, edx.
P.S. I found ackward has the converters ready, perhaps you could just reuse it. Doc here

Flexible application configuration in C++

I am developing a C++ application used to simulate a real world scenario. Based on this simulation our team is going to develop, test and evaluate different algorithms working within such a real world scenrio.
We need the possibility to define several scenarios (they might differ in a few parameters, but a future scenario might also require creating objects of new classes) and the possibility to maintain a set of algorithms (which is, again, a set of parameters but also the definition which classes are to be created). Parameters are passed to the classes in the constructor.
I am wondering which is the best way to manage all the scenario and algorithm configurations. It should be easily possible to have one developer work on one scenario with "his" algorithm and another developer working on another scenario with "his" different algorithm. Still, the parameter sets might be huge and should be "sharable" (if I defined a set of parameters for a certain algorithm in Scenario A, it should be possible to use the algorithm in Scenario B without copy&paste).
It seems like there are two main ways to accomplish my task:
Define a configuration file format that can handle my requirements. This format might be XML based or custom. As there is no C#-like reflection in C++, it seems like I have to update the config-file parser each time a new algorithm class is added to project (in order to convert a string like "MyClass" into a new instance of MyClass). I could create a name for every setup and pass this name as command line argument.
The pros are: no compilation required to change a parameter and re-run, I can easily store the whole config file with the simulation results
contra: seems like a lot of effort, especially hard because I am using a lot of template classes that have to be instantiated with given template arguments. No IDE support for writing the file (at least without creating a whole XSD which I would have to update everytime a parameter/class is added)
Wire everything up in C++ code. I am not completely sure how I would do this to separate all the different creation logic but still be able to reuse parameters across scenarios. I think I'd also try to give every setup a (string) name and use this name to select the setup via command line arg.
pro: type safety, IDE support, no parser needed
con: how can I easily store the setup with the results (maybe some serialization?)?, needs compilation after every parameter change
Now here are my questions:
- What is your opinion? Did I miss
important pros/cons?
- did I miss a third option?
- Is there a simple way to implement the config file approach that gives
me enough flexibility?
- How would you organize all the factory code in the seconde approach? Are there any good C++ examples for something like this out there?
Thanks a lot!
There is a way to do this without templates or reflection.
First, you make sure that all the classes you want to create from the configuration file have a common base class. Let's call this MyBaseClass and assume that MyClass1, MyClass2 and MyClass3 all inherit from it.
Second, you implement a factory function for each of MyClass1, MyClass2 and MyClass3. The signatures of all these factory functions must be identical. An example factory function is as follows.
MyBaseClass * create_MyClass1(Configuration & cfg)
{
// Retrieve config variables and pass as parameters
// to the constructor
int age = cfg->lookupInt("age");
std::string address = cfg->lookupString("address");
return new MyClass1(age, address);
}
Third, you register all the factory functions in a map.
typedef MyBaseClass* (*FactoryFunc)(Configuration *);
std::map<std::string, FactoryFunc> nameToFactoryFunc;
nameToFactoryFunc["MyClass1"] = &create_MyClass1;
nameToFactoryFunc["MyClass2"] = &create_MyClass2;
nameToFactoryFunc["MyClass3"] = &create_MyClass3;
Finally, you parse the configuration file and iterate over it to find all the entries that specify the name of a class. When you find such an entry, you look up its factory function in the nameToFactoryFunc table and invoke the function to create the corresponding object.
If you don't use XML, it's possible that boost::spirit could short-circuit at least some of the problems you are facing. Here's a simple example of how config data could be parsed directly into a class instance.
I found this website with a nice template supporting factory which I think will be used in my code.