Ok. My question is actually quite simple. This is a frame listener class and python wrapper class that is then used by boost python:
class FrameListener
{
public:
struct FrameEvent
{
double TimeSinceLastEvent;
double TimeSinceLastFrame;
};
FrameListener() {}
~FrameListener() {}
virtual void FrameStart(FrameEvent& evt) = 0;
virtual void FrameEnd(FrameEvent& evt) = 0;
virtual void OnFrame(FrameEvent& evt) = 0;
};
class FrameListener_PyWrapper : public FrameListener, public boost::python::wrapper<FrameListener>
{
public:
FrameListener_PyWrapper() {}
~FrameListener_PyWrapper();
void FrameStart(FrameEvent& evt);
void FrameEnd(FrameEvent& evt);
void OnFrame(FrameEvent& evt);
};
Classes are then wrapped to boost python:
class_<SL_Engine::FrameListener::FrameEvent>("FrameEvent")
.def_readonly("TimeSinceLastEvent", &SL_Engine::FrameListener::FrameEvent::TimeSinceLastEvent)
.def_readonly("TimeSinceLastFrame", &SL_Engine::FrameListener::FrameEvent::TimeSinceLastFrame);
class_<SL_Engine::FrameListener_PyWrapper, boost::noncopyable>("FrameListener")
.def("OnFrame", pure_virtual(&SL_Engine::FrameListener::OnFrame))
.def("FrameStart", pure_virtual(&SL_Engine::FrameListener::FrameStart))
.def("FrameEnd", pure_virtual(&SL_Engine::FrameListener::FrameEnd))
;
This can be overriden in python to create own frame listener class:
class SimpleListen(FrameListener):
def __init__(self):
pass
def FrameEndd(self, evt):
pass
Then you create instance of the new SimpleListener class and "register" it to the engine with CORE_ENGINE.AddFrameListener() function. The function then uses boost::python::extract() to extract it and put it on std::vector of frame listeners which are then executed every frame. This works perfectly, but if I forget to define base in simple class or misspell it, it obviously results in a crash. I have searched on google both in boost::python or C/Python API, how can I test if base class is properly defined. The AddFrameListener takes PyObject* argument. I want to test if PyObject is class type first. If you accidently try to put an integer value or a string that the program will identify the error and message that the object is not class type. If it is class type I want to test if it has base class and if it can be extracted to FrameListener_PyWrapper*. Later on I want to test each individual function (FrameStart, FrameEnd and OnFrame) if they are overriden in python class and if arguments match. How can I get list of arguments from python function? If any of the functions from python class is not overriden it will give me a warning. If arguments don't match and you try to call:
if (boost::python::override f = this->get_override("FrameEnd"))
{
f(evt);
return;
}
It will result in a crash without any information about error. I want to check if arguments match when calling AddFrameListener function and save information if any of the functions are not properly overriden the engine will not call them.