Ogre::Any problem

DenisKoronchik

18-10-2009 18:02:45

Problems to use Ogre::Any object
For exmple i need to to set UserAny object to SceneNode, but wraper for Ogre::Any, doesn't have methods to get data from it.
I've set pointer to it, but i can't get it back

andy

19-10-2009 01:52:51

Can you send through some example code on how you want to use it as it probably needs some hand wrapping to be useful.

ie are you trying to simply set it to a numeric value or do you want to pass a python object around etc

*UPDATE*:
Just too another look and Any kind-of-works now:
>>> import ogre.renderer.OGRE as ogre
>>> a=ogre.Any(10)
>>> b=ogre.Any("testing")
>>> print a
10
>>> print b
testing
>>> c=a.__str__()
>>> print c
10
>>>

so I'll add some helper functions to make it clearer and in the mean time use the __str__ function as a hack

Andy

DenisKoronchik

19-10-2009 12:03:11

Need to set python object to Any and get it back
Something like this:
>>> import ogre.renderer.OGRE as ogre
>>> class A:
def test():
print 'test'
>>> a = A()
>>> b = ogre.Any(a)
>>> b.getObject().x()
>>>

now we have:
>>> import ogre.renderer.OGRE as ogre
>>> class A:
def test():
print 'test'


>>> a = A()
>>> b = ogre.Any(a)

Traceback (most recent call last):
File "<pyshell#58>", line 1, in <module>
b = ogre.Any(a)
ArgumentError: Python argument types in
Any.__init__(Any, instance)
did not match C++ signature:
__init__(struct _object *, class Ogre::Any other)
__init__(struct _object *, class Ogre::UserDefinedObject * value)
__init__(struct _object *, int value)
__init__(struct _object *, float value)
__init__(struct _object *, unsigned int value)
__init__(struct _object *, unsigned long value)
__init__(struct _object *, unsigned short value)
__init__(struct _object *, unsigned char value)
__init__(struct _object *, class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > value)
__init__(struct _object *, class Ogre::Any value)
__init__(struct _object *)

You tried with simple objects, that have signatures, but idea to set any python object to ogre.Any and get it back

andy

19-10-2009 12:47:33

Not really sure I want to extend it that far but will take a look...

One challenge is that the python object can go out of scope and you will end up with memory allocation/access errors (the C++ code is holding a reference to a python object, however the python environment doesn't know this and can delete the object at any time which causes an access violation when the C++ code goes to use it).

I'd need to wrap the assignment operator (and constructor) for Ogre::Any to do a Py_INCREF on the object which means patching the Ogre source which I like doing (plus do the reverse on the destructor)

I'd rather see you store a index in the Ogre.Any variable (an int or string) and use that as a key into a global array that holds the python object you are tracking.

Thoughts?

Andy

DenisKoronchik

20-10-2009 07:53:16

C++ code wouldn't use it.
That just mechanism to link object in scene with your python object. When we picking mouse and finding ogre object mouse picked, then we just getting UserAny object from it to find its logic representation in python.

But we can imagine situation where it will be used in c++ code, but that will be user code, not ogre core.

andy

31-10-2009 04:42:43

OK I took a look into Ogre::Any support and have made a series of enhancements that are in the SVN and latest Windows snapshot. I added a 'getData' function to Any so you can extract the data -- it returns a 2 item tuple, the first item tells you what type of data is being returned such as:
  1. 'p' = a python object
    'us' = unsigned short
    'ul' = unsigned long
    'l' = long
    etc [/list:u]and the 2nd item is the actual data.

    By default you can simply pass a python object to Any and it will just work - otherwise if you want to create a specific type of Any then you use the utility function createAny -- note that if you pass an incorrect value in the create pass it will raise an exception as shown below.
    >>> import ogre.renderer.OGRE as ogre
    >>> l=[1,2,3,4]
    >>> a=ogre.Any(l)
    >>> b=a.getData()
    >>> print b
    ('p', [1, 2, 3, 4])
    >>> c=ogre.createAny(['us',123])
    >>> d=c.getData()
    >>> print d
    ('us', 123)
    >>> c=ogre.createAny(['us',123456789])
    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    OverflowError: bad numeric conversion: positive overflow
    >>> c=ogre.createAny(['ul',123456789])
    >>> d=c.getData()
    >>> print d
    ('ul', 123456789)
    >>>


    Let me know if you have any issues using it..

    Andy