Python ModuleNamespace

Discussion about using Python with libRocket.

Python ModuleNamespace

Postby AFineTapestry on Wed Jun 18, 2014 11:25 pm

I'm going to inaugurate the reopening of these forums with a question of my own.

Is it possible to access a specific Document's Python Module Namespace? I'd like to be able to inject variables and call Python functions from C++.

Here is how I would expect it to work:
Code: Select all
Rocket::Core::RenderInterface * renderInterface = new OpenGLRenderInterface();
Rocket::Core::Context * context = Rocket::Core::CreateContext("main", Rocket::Core::Vector2i(1920, 1080), renderInterface);
Rocket::Core::ElementDocument * document = context->LoadDocument("main.rml");
PyObject * pyObject = document->GetModuleNamespace(); // Unavailable
boost::python::object module_namespace = boost::python:object(boost::python::handle<>(pyObject));
module_namespace["a"] = 3; // Inject variable

Cheers,
AFineTapestry
Last edited by AFineTapestry on Wed Jun 18, 2014 11:53 pm, edited 1 time in total.
Reason: Increased code sample clarity
AFineTapestry
Rocket Engineer
Rocket Engineer
 
Posts: 11
Joined: Fri Jun 13, 2014 8:55 am

Re: Python ModuleNamespace

Postby Supertim on Thu Jun 19, 2014 2:53 am

Hey AFineTapestry,

That should be pretty straightforward. Using your sample below:

Code: Select all
Rocket::Core::RenderInterface * renderInterface = new OpenGLRenderInterface();
Rocket::Core::Context * context = Rocket::Core::CreateContext("main", Rocket::Core::Vector2i(1920, 1080), renderInterface);
Rocket::Core::ElementDocument * document = context->LoadDocument("main.rml");
//PyObject * pyObject = document->GetModuleNamespace(); // Unavailable
// Instead lets try this:
Rocket::Core::Python::ElementDocumentWrapper *wrapper = (Rocket::Core::Python::ElementDocumentWrapper *) document;

// From here, we use PyObject* GetModuleNamespace() method from ElementDocumentWrapper.h file, line 56 :)
PyObject *pyObject = wrapper->GetModuleNamespace();

boost::python::object module_namespace = boost::python:object(boost::python::handle<>(pyObject));
module_namespace["a"] = 3; // Inject variable


That should do it, assuming Python bindings work somewhat the same way that my Lua bindings do, in the sense that instantiated objects are registered properly and work from C++ as well. The above should work.

Let me know if it doesn't, I'm sure we can get to the bottom of it.

Edit: I do my casting mostly just by traditional C casts, there may be a better way of casting the document object to correct type. Also added <code> tags
Supertim
Rocket Engineer
Rocket Engineer
 
Posts: 16
Joined: Sat Jun 14, 2014 5:31 am

Re: Python ModuleNamespace

Postby AFineTapestry on Thu Jun 19, 2014 12:53 pm

Thanks for your quick reply Supertim.

I've already tried your suggestion and I can't get it to work.

ElementDocumentWrapper.h is a private header but even if I copy it into my project folder and compile the linker cannot find GetModuleNamespace I think because it is in _rocketcore.so.
Last edited by AFineTapestry on Thu Jun 19, 2014 12:57 pm, edited 1 time in total.
Reason: Fixed rocket python object name.
AFineTapestry
Rocket Engineer
Rocket Engineer
 
Posts: 11
Joined: Fri Jun 13, 2014 8:55 am

Re: Python ModuleNamespace

Postby Supertim on Fri Jun 20, 2014 5:02 am

Sorry AFineTapestry, you are completely right - I was deceived by my own implementation of script bindings, and didn't even realize I was in the source folder.

Wow, I wrote a huge post about it and had to delete it completely. It was essentially on how to implement this class method, when I realized that default python bindings already have it!

Here is the method you need:

Code: Select all
PyObject *obj = document->GetScriptObject();


You will not believe the lengths I went haha :lol:

If this doesn't work - I can help you implement it, perhaps even submit a patch to the git repository (never done that before). Please let me know!
Supertim
Rocket Engineer
Rocket Engineer
 
Posts: 16
Joined: Sat Jun 14, 2014 5:31 am

Re: Python ModuleNamespace

Postby AFineTapestry on Fri Jun 20, 2014 8:02 am

Hi Supertim,

Sorry to hear that.

I'll try it later today but I think GetScriptObject() will get me the python interface to the document object not the python module.

I could try and implement it but I can't see anyway of doing it without it being very messy.
AFineTapestry
Rocket Engineer
Rocket Engineer
 
Posts: 11
Joined: Fri Jun 13, 2014 8:55 am

Re: Python ModuleNamespace

Postby Supertim on Fri Jun 20, 2014 8:58 pm

You are correct again, sorry - python stuff is very new to me.

I can try to implement it, shouldn't be rocket science ;)

I'll let you know how I go about it tonight, if that's ok.
Supertim
Rocket Engineer
Rocket Engineer
 
Posts: 16
Joined: Sat Jun 14, 2014 5:31 am

Re: Python ModuleNamespace

Postby AFineTapestry on Sun Jun 22, 2014 6:13 pm

Hi,

Sorry, I was away for the weekend.

You don't have to do it for me, but can you give me some idea of how you are thinking of implementing it? I can't see a clean way since I never directly instantiate an ElementDocumentWrapper, it is somehow injected by the presence of the Python plugin?

Cheers,
AFineTapestry
AFineTapestry
Rocket Engineer
Rocket Engineer
 
Posts: 11
Joined: Fri Jun 13, 2014 8:55 am

Re: Python ModuleNamespace

Postby AFineTapestry on Fri Jun 27, 2014 11:58 am

Hi Supertim,

Have you had another chance to look at this? Or can you point me in the right direction as to how to fix it?

Cheers,
AFT
AFineTapestry
Rocket Engineer
Rocket Engineer
 
Posts: 11
Joined: Fri Jun 13, 2014 8:55 am

Re: Python ModuleNamespace

Postby Supertim on Sat Jun 28, 2014 4:38 am

Hi AFineTapestry,

Sorry I didn't reply sooner - work kept me buried deep past few weeks :( To be completely honest - I did write a lengthy reply, but the forum timed out and when I tried to post it, it didn’t work, and the back button failed me. I was so upset I put my laptop away and didn’t even touch it afterwards. In retrospect - I think my reply was inaccurate after all, and I’m kind of glad it didn’t go through, but parts of it were right.

I took a look and tried compiling the pyinvaders and other python stuff but failed to setup boost and python altogether. Honestly I wasn’t very enthusiastic either, but I gave it a fair shot. I hope it’s ok if I simply explain my intentions :)

I think trying to extract the ElementDocumentWrapper interface is probably your best bet at getting the Document’s associated module namespace. I don’t know how far you’ve taken it, but I’d suggest trying this (inside libRocket directory, we will rebuild the library):

1. Place the ElementDocumentWrapper.h file in the includes folder of libRocket (the core/python subfolder obviously :))
2. In the ElementDocumentWrapper try changing the class declaration to this:

Code: Select all
class ROCKETCORE_API ElementDocumentWrapper : public ElementWrapper< ElementDocument >


Note the presence of “ROCKETCORE_API” macro in there, this is meant to say that this class will be exported from the library based on how you compile it. If you compile dynamically – this macro should be __declspec(dllexport), etc.

Now rebuild the library – and you should be able to cast your document to the (ElementDocumentWrapper *) type and call the GetModuleNamespace() method:

Code: Select all
ElementDocumentWrapper *wrapper = (ElementDocumentWrapper*)document;
PyObject *moduleNS = wrapper->GetModuleNamespace();


It’s been a very long few weeks, so I apologize for any mistakes. Please let me know if that works :) It should, technically, since the LoadScript method does inherit from ElementDocument, and is essential for loading scripts from document body (if I remember correctly). The only thing I’m not sure about, is whether simply casting the document to this wrapper is the right thing to do. The reason being that I have no idea what the python::class_ does with it’s template arguments. Mystical stuff for sure.

Good luck, and please let me know how it works out :)
Supertim
Rocket Engineer
Rocket Engineer
 
Posts: 16
Joined: Sat Jun 14, 2014 5:31 am

Re: Python ModuleNamespace

Postby Supertim on Sun Jul 06, 2014 5:50 am

Hey AFT,

Sorry for prying, have you had any success with your implementation? Just looking to see if I should try getting python to work after all, for further testing :)
Supertim
Rocket Engineer
Rocket Engineer
 
Posts: 16
Joined: Sat Jun 14, 2014 5:31 am

Next

Return to libRocket and Python


cron