Is it possible to use *Manager.parseScript() in PyOgre?

esteban

11-10-2005 08:54:34

... I mean, in current SVN.

The problem I have is getting the DataStreamPtr that parseScript() expects. I tried creating a FileHandleDataStream in Python, but it doesn't work. Maybe SWIG doesn't know to map Python file objects to FILE*s?

>>> s = ogre.FileHandleDataStream(file("d:\\lala.txt"))
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "c:\python24\lib\site-packages\pyogre\ogre.py", line 4890, in __init__
newobj = _ogre.new_FileHandleDataStream(*args)
NotImplementedError: No matching function for overloaded 'new_FileHandleDataStre
am'
>>> f = file("d:\\lala.txt")
>>> f.fileno()
4
>>> s = ogre.FileHandleDataStream(f.fileno())
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "c:\python24\lib\site-packages\pyogre\ogre.py", line 4890, in __init__
newobj = _ogre.new_FileHandleDataStream(*args)
NotImplementedError: No matching function for overloaded 'new_FileHandleDataStre
am'


Later I discovered FileSystemArchive and FileSystemArchiveFactory, but neither is wrapped in PyOgre and I'm not sure whether I'm supposed to use these anyway. At least the Archive class says you shouldn't instantiate it directly, but through an ArchiveFactory.

So, in short, do you know of any way to use *Manager.parseScript() in current PyOgre? Do I create an FileSystemArchiveFactory, then ask it to give me a FileSystemArchive, then call load() on that? I'd have to wrap these in SWIG first. That's no problem, but could someone confirm this is what is needed? If not, any pointers?

Maybe the über-pythonic way to use parseScript would be to just let it take a python file object, or a python string. But to do this I'd still need to know what is the canonical way to use parseScript() in C++ Ogre, i.e. where are you expected to get the DataStreamPtr from.

TIA,

Esteban.

esteban

13-10-2005 15:56:15

Hi again. After some interesting interchange with :wumpus: in the C++ Ogre forum, and especially with Clay by email, I think I got something that could be useful. If you add the following to the end of ogre_typemaps.i :

/* DataStreamPtr in typemap: accept a Python string as it was a DataStreamPtr */

%typemap(in) Ogre::DataStreamPtr & (SwigValueWrapper<Ogre::DataStreamPtr> dsp) {
if (!PyString_Check($input)) {
PyErr_SetString(PyExc_TypeError, "String expected.");
return NULL;
}
int len;
char *buff;
PyString_AsStringAndSize($input, &buff, &len);
char *buffcopy = new char[len];
strncpy(buffcopy, buff, len);
dsp = Ogre::DataStreamPtr(new Ogre::MemoryDataStream(buffcopy, len, true));
$1 = &dsp;
}


And rebuild PyOgre, then you can pass a Python string wherever Ogre expects a DataStreamPtr. That means you can use *.parseScript() like this:

s = file("some.material").read()
ogre.MaterialManager.getSingleton().parseScript(s, "SomeResourceGroup")


Any chance the maintainers would consider adding something on the lines of this to the official PyOgre trunk? That is, with any corrections that may be needed- I'm a C++ and SWIG newbie. A couple days messing with these monstrosities was enough to remind me of why I love Python so much. :wink:

Anyway, if anyone ever needs to use parseScript and are brave enough to build PyOgre, I hope you find this useful.

PyOgre rules! Thanks for your great work!!

esteban

13-10-2005 23:46:01

Clay added a corrected version of this to the main repository.